-9
.changeset/README.md
-9
.changeset/README.md
···
1
-
# Changesets
2
-
3
-
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool
4
-
that works with multi-package repos, or single-package repos to help you version and publish your
5
-
code. You can find the full documentation for it
6
-
[in our repository](https://github.com/changesets/changesets)
7
-
8
-
We have a quick list of common questions to get you started engaging with this project in
9
-
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
-11
.changeset/config.json
-11
.changeset/config.json
···
1
-
{
2
-
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
3
-
"changelog": "@changesets/cli/changelog",
4
-
"commit": false,
5
-
"fixed": [],
6
-
"linked": [],
7
-
"access": "restricted",
8
-
"baseBranch": "trunk",
9
-
"updateInternalDependencies": "patch",
10
-
"ignore": ["svelte-site"]
11
-
}
-8
.changeset/six-rabbits-admire.md
-8
.changeset/six-rabbits-admire.md
-13
.gitignore
-13
.gitignore
.nojekyll
.nojekyll
This is a binary file and will not be displayed.
-8
.prettierignore
-8
.prettierignore
-25
.prettierrc
-25
.prettierrc
···
1
-
{
2
-
"trailingComma": "all",
3
-
"useTabs": true,
4
-
"tabWidth": 2,
5
-
"printWidth": 110,
6
-
"semi": true,
7
-
"singleQuote": true,
8
-
"bracketSpacing": true,
9
-
"plugins": ["prettier-plugin-svelte", "prettier-plugin-css-order"],
10
-
"overrides": [
11
-
{
12
-
"files": ["tsconfig.json", "jsconfig.json", "tsconfig.*.json"],
13
-
"options": {
14
-
"parser": "jsonc"
15
-
}
16
-
},
17
-
{
18
-
"files": ["*.md"],
19
-
"options": {
20
-
"printWidth": 100,
21
-
"proseWrap": "always"
22
-
}
23
-
}
24
-
]
25
-
}
-4
.vscode/settings.json
-4
.vscode/settings.json
-17
LICENSE
-17
LICENSE
···
1
-
Permission is hereby granted, free of charge, to any person obtaining a copy
2
-
of this software and associated documentation files (the "Software"), to deal
3
-
in the Software without restriction, including without limitation the rights
4
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5
-
copies of the Software, and to permit persons to whom the Software is
6
-
furnished to do so, subject to the following conditions:
7
-
8
-
The above copyright notice and this permission notice shall be included in all
9
-
copies or substantial portions of the Software.
10
-
11
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
-
SOFTWARE.
-15
README.md
-15
README.md
···
1
-
# <bluesky-embed>
2
-
3
-
A custom element for embedding Bluesky posts.
4
-
5
-
- **Lightweight**, the entire package + dependencies is only ~20 KB (~6 KB gzipped)
6
-
- **Standalone**, no middleman involved, directly calls Bluesky's API
7
-
- **Server-side rendering possible**, allows for no-JavaScript usage
8
-
9
-
| Packages |
10
-
| ------------------------------------------------------------------------------------------------ |
11
-
| [`bluesky-post-embed`](./packages/bluesky-post-embed): displays a post embed |
12
-
| [`bluesky-profile-card-embed`](./packages/bluesky-profile-card-embed): displays a user's profile |
13
-
| [`bluesky-profile-feed-embed`](./packages/bluesky-profile-feed-embed): displays a user's feed |
14
-
15
-

+1
assets/GuideInstructions-B8N7RzmZ.css
+1
assets/GuideInstructions-B8N7RzmZ.css
···
1
+
.code-block.svelte-ipr7k2{display:flex;gap:12px;border:1px solid #d1d5db;border-radius:4px;background:#f9fafb;padding:12px;overflow:hidden;overflow-x:auto;pre:where(.svelte-ipr7k2){flex-grow:1;margin:0;font-size:.75rem;line-height:1.25rem}}.actions.svelte-ipr7k2{position:sticky;top:0;right:0}.action-button.svelte-ipr7k2{display:flex;justify-content:center;align-items:center;cursor:pointer;box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a;border:1px solid #d1d5db;border-radius:4px;background:#fff;padding:0;width:32px;height:32px;color:#4b5563;@media(pointer:fine){opacity:0;transition:75ms ease-in;.code-block:where(.svelte-ipr7k2):hover &,.code-block:where(.svelte-ipr7k2):focus-within &{opacity:1}&:hover{border-color:#9ca3af;background:#e5e7eb;color:#1f2937}}&:active{border-color:#9ca3af;background:#e5e7eb;color:#1f2937}}.icon.svelte-ipr7k2{width:16px;height:16px}.guide.svelte-1wxv0ke{margin:36px 0 0;border-top:1px solid #d1d5db}.guide-header.svelte-1wxv0ke{margin:36px 0 16px}.guide-instructions.svelte-mki4x9{margin:24px 0 0;padding:0 0 0 22px;font-size:.875rem;line-height:1.25rem;li+li{margin:24px 0 0}}
+1
assets/GuideInstructions-CTis8QB-.js
+1
assets/GuideInstructions-CTis8QB-.js
···
1
+
import{t as e,m as t,r as s,n as r,o as n,q as a,v as o,w as i,x as c,p as l,f as d,k as p,c as h,i as u,a as f,b as v,y,z as g}from"./index-CD_0uzJz.js";function w(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function b(o,i,c=!1,l=!1,d=!1){var p=o,h="";e(()=>{var e=t;if(h!==(h=i()??"")&&(null!==e.nodes&&(s(e.nodes.start,e.nodes.end),e.nodes=null),""!==h)){var o=h+"";c?o=`<svg>${o}</svg>`:l&&(o=`<math>${o}</math>`);var d=r(o);if((c||l)&&(d=a(d)),n(a(d),d.lastChild),c||l)for(;a(d);)p.before(a(d));else p.before(d)}})}function k(e){null===o&&w(),function(e){null===o&&w(),i(()=>{const t=c(e);if("function"==typeof t)return t})}(()=>()=>c(e))}const x=({service:e,fetch:t=fetch})=>async(s,r)=>{const n=new URL(s,e);return await t(n,r)},m=(e,t)=>{let s;for(const r in t){const n=t[r];null!==n&&(s??=new Headers(e),s.has(r)||s.set(r,n))}return s??e};class j extends Error{constructor(e,{kind:t=`HTTP error ${e}`,description:s="Unspecified error description",headers:r,cause:n}={}){super(`${t} > ${s}`,{cause:n}),this.name="XRPCError",this.status=e,this.kind=t,this.description=s,this.headers=r||{}}}class ${constructor({handler:e,proxy:t}){this.handle=(e=>"object"==typeof e?e.handle.bind(e):e)(e),this.proxy=t}get(e,t){return this.request({type:"get",nsid:e,...t})}call(e,t){return this.request({type:"post",nsid:e,...t})}async request(e){const t=e.data,s=`/xrpc/${e.nsid}`+O(e.params),r=q(t),n=await this.handle(s,{method:e.type,signal:e.signal,body:r?JSON.stringify(t):t,headers:m(e.headers,{"content-type":r?"application/json":null,"atproto-proxy":C(this.proxy)})}),a=n.status,o=Object.fromEntries(n.headers),i=o["content-type"];let c,l;i&&(i.startsWith("application/json")?c=n.json():i.startsWith("text/")&&(c=n.text()));try{l=await(c||n.arrayBuffer().then(e=>new Uint8Array(e)))}catch(d){throw new j(2,{cause:d,kind:"InvalidResponse",description:"Failed to parse response body",headers:o})}if(200===a)return{data:l,headers:o};if(A(l))throw new j(a,{kind:l.error,description:l.message,headers:o});throw new j(a,{headers:o})}}const C=e=>e?`${e.service}#${e.type}`:null,O=e=>{let t;for(const s in e){const r=e[s];if(void 0!==r)if(t??=new URLSearchParams,Array.isArray(r))for(let e=0,n=r.length;e<n;e++){const n=r[e];t.append(s,""+n)}else t.set(s,""+r)}return t?"?"+t.toString():""},q=e=>{if("object"!=typeof e||null===e)return!1;if("toJSON"in e)return!0;const t=Object.getPrototypeOf(e);return null===t||t===Object.prototype},A=e=>{if("object"!=typeof e||null===e)return!1;const t=typeof e.error,s=typeof e.message;return!("undefined"!==t&&"string"!==t||"undefined"!==s&&"string"!==s)},E=e=>e.replace(/[<"&]/g,e=>"&#"+e.charCodeAt(0)+";");var H=d('<div class="code-block svelte-ipr7k2"><pre class="svelte-ipr7k2"><code> </code></pre> <div class="actions svelte-ipr7k2"><button title="Copy" aria-label="Copy" class="action-button svelte-ipr7k2"><svg class="icon svelte-ipr7k2" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="square" stroke-width="2" d="M15 5h4v16H5V5h4m0-2h6v4H9V3Z"></path></svg></button></div></div>');function P(t,s){l(s,!0);var r=H(),n=h(r),a=h(n),o=h(a),i=p(n,2);h(i).__click=()=>{navigator.clipboard.writeText(s.code).catch(()=>alert("Failed to copy to clipboard"))},e(()=>u(o,s.code)),f(t,r),v()}y(["click"]);var R=d('<div class="guide svelte-1wxv0ke"><h4 class="guide-header svelte-1wxv0ke"> </h4> <!></div>');function S(t,s){var r=R(),n=h(r),a=h(n),o=p(n,2);g(o,()=>s.children),e(()=>u(a,s.title)),f(t,r)}var U=d('<ol class="guide-instructions svelte-mki4x9"><!></ol>');function _(e,t){var s=U(),r=h(s);g(r,()=>t.children),f(e,s)}export{P as C,S as G,$ as X,j as a,_ as b,E as e,b as h,k as o,x as s};
+1
assets/PostDisplay-CqTUAVla.js
+1
assets/PostDisplay-CqTUAVla.js
···
1
+
import{p as e,f as s,t as a,s as t,a as i,b as r,c as l,d as n,e as p,g as d,B as o,h as c,i as h,j as u,k as m,l as f,u as v,C as b}from"./index-CD_0uzJz.js";import{X as k,s as y,a as g,h as $,o as w,G as x,b as z,C as q,e as Z}from"./GuideInstructions-CTis8QB-.js";import{s as A}from"./index-Cr8Vao8y.js";const F=/[&"<]/g,C=/[&<]/g;function M(e,s){const a=String(e??""),t=s?F:C;t.lastIndex=0;let i="",r=0;for(;t.test(a);){const e=t.lastIndex-1,s=a[e];i+=a.substring(r,e)+("&"===s?"&":'"'===s?""":"<"),r=e+1}return i+a.substring(r)}function N(e,s,a=!1){if("hidden"===e&&"until-found"!==s&&(a=!0),null==s||!s&&a)return"";return` ${e}${a?"":`="${M(s,!0)}"`}`}function _(e,s,a){var t=function(e,s){var a=null==e?"":""+e;return s&&(a=a?a+" "+s:s),""===a?null:a}(e,s);return t?` class="${M(t,!0)}"`:""}function B(e,s){var a=function(e){return null==e?null:String(e)}(e);return a?` style="${M(a,!0)}"`:""}function S(e,s){const{children:a}=s;e.push('<div class="bluesky-embed s-3olstj">'),a(e),e.push("</div>")}const U=e=>`https://bsky.app/profile/${e}`,T=(e,s)=>`https://bsky.app/profile/${e}/post/${s}`,I=e=>`https://bsky.app/hashtag/${e}`,R=(e,s)=>`https://bsky.app/profile/${e}/feed/${s}`;let D=0,H=0;const j=new Intl.DateTimeFormat("en-US",{dateStyle:"long",timeStyle:"short"}),P=new Intl.DateTimeFormat("en-US",{dateStyle:"medium"}),V=new Intl.DateTimeFormat("en-US",{month:"short",day:"numeric"}),G=e=>{const s=new Date(e),a=s.getTime();if(isNaN(a))return"N/A";const t=Date.now();if(t>H){const e=new Date(t);e.setMonth(0,1),e.setHours(0,0,0),D=e.getTime(),e.setFullYear(e.getFullYear()+1,0,0),e.setHours(23,59,59,999),H=e.getTime()}return a>=D&&a<=H?V.format(s):P.format(s)},L=e=>{const s=new Date(e);return isNaN(s.getTime())?"N/A":j.format(s)},W={"!hide":{name:"Hidden by moderators",flags:1},"!warn":{name:"Content warning",flags:1},porn:{name:"Adult content",flags:0},sexual:{name:"Sexually suggestive",flags:0},"graphic-media":{name:"Graphic media",flags:0},nudity:{name:"Nudity",flags:0}},E=(e,s)=>{if(e?.length)for(let a=0,t=e.length;a<t;a++){const t=e[a],i=t.val;if(!(i in W))continue;const r=W[i];if(!(1&r.flags&&t.src===s))return r}},Y=new Intl.NumberFormat("en-US"),J=new Intl.NumberFormat("en-US",{notation:"compact"}),K=e=>e<1e3?""+e:e<1e5?Y.format(e):J.format(e),X=e=>Y.format(e),O=/^at:\/\/((?:did:[a-zA-Z0-9._:%-]+)|(?:[a-zA-Z0-9][a-zA-Z0-9-.]*))(?:\/([a-zA-Z0-9.-]+)(?:\/([a-zA-Z0-9_~.:-]{1,512}))?)?\/?(?:\?([^#\s]*))?(?:#([^\s]*))?$/,Q=e=>{const s=O.exec(e);if(!s)throw new ee(`invalid at-uri: ${e}`);return{repo:s[1],collection:s[2]??"",rkey:s[3]??"",query:s[4]??"",fragment:s[5]??""}};let ee=class extends Error{};function se(e,s){{const{embed:a}=s,t=a.external,i=(e=>{let s;if("parse"in URL)s=URL.parse(e);else try{s=new URL(e)}catch{}return!s||"https:"!==s.protocol&&"http:"!==s.protocol?null:s})(t.uri)?.host;e.push(`<a target="_blank"${N("href",i&&t.uri)} rel="noopener noreferrer nofollow" class="external-embed s-rtbqd8">`),t.thumb&&e.push(`<img loading="lazy"${N("src",t.thumb)} alt="" class="thumbnail s-rtbqd8"/>`),e.push(` <div class="meta s-rtbqd8"><p class="title s-rtbqd8">${M(t.title)}</p> <p class="description s-rtbqd8">${M(t.description)}</p> `),i&&e.push(`<div class="domain s-rtbqd8"><svg class="icon" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-width="2" d="m4.172 8.07 3.94 2.957.977-1.941 3.887-.978 1.15-4.6M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-6.078 4.865.973-1.946-2.869-1.928-1.89-.12-1.08 1.075 1.947 2.919h2.919Z"></path></svg> <span class="domain-name">${M(i)}</span></div>`),e.push("</div></a>")}}const ae={width:16,height:9};function te(e,s){{const{embed:a,borderless:t,standalone:i,blur:r}=s,l=a.images,n=l.length;function p(e,s){const a=l[s];e.push(`<img loading="lazy"${N("src",a.thumb)}${N("alt",a.alt)}${_("image"+(r?" is-blurred":""),"s-t3k6fc")}/>`)}if(e.push(`<div${_("image-embed"+(t?"":" is-bordered")+(i&&1===n?" is-aligned":""),"s-t3k6fc")}>`),4===n)e.push('<div class="grid s-t3k6fc"><div class="col s-t3k6fc"><div class="item wide tl s-t3k6fc">'),p(e,0),e.push('</div> <div class="item wide bl s-t3k6fc">'),p(e,2),e.push('</div></div> <div class="col s-t3k6fc"><div class="item wide tr s-t3k6fc">'),p(e,1),e.push('</div> <div class="item wide br s-t3k6fc">'),p(e,3),e.push("</div></div></div>");else if(3===n)e.push('<div class="grid s-t3k6fc"><div class="col square s-t3k6fc"><div class="item tl bl s-t3k6fc">'),p(e,0),e.push('</div></div> <div class="col square s-t3k6fc"><div class="item tr s-t3k6fc">'),p(e,1),e.push('</div> <div class="item br s-t3k6fc">'),p(e,2),e.push("</div></div></div>");else if(2===n)e.push('<div class="grid s-t3k6fc"><div class="col s-t3k6fc"><div class="item square tl bl s-t3k6fc">'),p(e,0),e.push('</div></div> <div class="col s-t3k6fc"><div class="item square tr br s-t3k6fc">'),p(e,1),e.push("</div></div></div>");else if(1===n){const d=i&&(l[0].aspectRatio||ae);e.push(`<div${_("single-item tl tr bl br"+(d?" is-standalone":""),"s-t3k6fc")}${B(d?`aspect-ratio: ${d.width}/${d.height}`:"")}>`),p(e,0),e.push(" "),d&&e.push('<div class="placeholder s-t3k6fc"></div>'),e.push("</div>")}e.push("</div>")}}function ie(e,s){{const{post:a,embed:t,borderless:i,standalone:r,blur:l}=s,n=r&&t.aspectRatio,p=a&&T(a.author.did,Q(a.uri).rkey);function d(e){e.push(`<img loading="lazy"${N("src",t.thumbnail)} alt=""${_("thumbnail"+(l?" is-blurred":""),"s-1azk58e")}/> `),n&&e.push('<div class="placeholder s-1azk58e"></div>'),e.push(' <div class="play s-1azk58e"><svg class="icon s-1azk58e" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M22 12 5 2v20l17-10Z"></path></svg></div>')}r?(e.push(`<a target="_blank"${N("href",p)}${_("video-embed"+(i?"":" is-bordered")+(r?" is-standalone":""),"s-1azk58e")}><div class="constrainer s-1azk58e"${B(n?`aspect-ratio: ${n.width}/${n.height}`:"")}>`),d(e),e.push("</div></a>")):(e.push(`<div${_("video-embed"+(i?"":" is-bordered"),"s-1azk58e")}${B(n?`aspect-ratio: ${n.width}/${n.height}`:"")}>`),d(e),e.push("</div>"))}}const re=e=>{if(e){if("app.bsky.embed.images#view"===e.$type)return e;if("app.bsky.embed.recordWithMedia#view"===e.$type)return re(e.media)}},le=e=>{if(e){if("app.bsky.embed.video#view"===e.$type)return e;if("app.bsky.embed.recordWithMedia#view"===e.$type)return le(e.media)}};function ne(e,s){e.push(`<div class="message s-azdpbr">${M(s)}</div>`)}function pe(e,s){{const{post:a,embed:t,large:i=!1}=s;function r(e,s){!function(e,s){{const{warning:a,children:t}=s;a?(e.push(`<details class="content-hider s-q6x07m"><summary class="gate s-q6x07m"><svg class="icon s-q6x07m" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="square" stroke-width="2" d="M11 11h1v5m9-4a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"></path><path fill="currentColor" stroke="currentColor" stroke-width=".5" d="M11.5 7.25h-.25v1.5h1.5v-1.5H11.5Z"></path></svg> <span class="label s-q6x07m">${M(a.name)}</span> <span class="action s-q6x07m"></span></summary> `),t(e),e.push("</details>")):t(e)}}(e,{warning:a&&E(a.labels,a.author.did),children:e=>{"app.bsky.embed.external#view"===s.$type?se(e,{embed:s}):"app.bsky.embed.images#view"===s.$type?te(e,{embed:s,standalone:!0}):"app.bsky.embed.video#view"===s.$type?ie(e,{post:a,embed:s,standalone:!0}):ne(e,"Unsupported media embed")}})}function l(e,s){const a=s.record;if("app.bsky.embed.record#viewRecord"===a.$type)!function(e,s){{const{embed:a,large:t=!1}=s,i=a.value,r=i.text.trim(),l=a.author,n=l.displayName?.trim(),p=a.embeds?.[0],d=re(p),o=le(p),c=T(l.did,Q(a.uri).rkey),h=!!E(a.labels,l.did);e.push(`<a target="_blank"${N("href",c)} class="quote-embed s-za6fip"><div class="meta s-za6fip"><div class="avatar-wrapper s-za6fip">`),l.avatar&&e.push(`<img loading="lazy"${N("src",l.avatar)} alt="" class="avatar s-za6fip"/>`),e.push('</div> <span class="name-wrapper s-za6fip">'),n&&e.push(`<bdi class="display-name-wrapper s-za6fip"><span class="display-name s-za6fip">${M(n)}</span></bdi>`),e.push(` <span class="handle s-za6fip">@${M(l.handle)}</span></span> <span aria-hidden="true" class="dot s-za6fip">ยท</span> <time${N("datetime",i.createdAt)} class="date s-za6fip">${M(G(i.createdAt))}</time></div> `),r?(e.push('<div class="body s-za6fip">'),t||(d?(e.push('<div class="aside s-za6fip">'),te(e,{embed:d,blur:h}),e.push("</div>")):o&&(e.push('<div class="aside s-za6fip">'),ie(e,{embed:o,blur:h}),e.push("</div>"))),e.push(` <p class="text s-za6fip">${M(r)}</p></div>`)):e.push('<div class="divide s-za6fip"></div>'),e.push(" "),!t&&r||(d?te(e,{embed:d,borderless:!0,blur:h}):o&&ie(e,{embed:o,borderless:!0,blur:h})),e.push("</a>")}}(e,{embed:a,large:i});else if("app.bsky.feed.defs#generatorView"===a.$type)!function(e,s){{const{embed:a}=s,t=a.creator,i=R(t.did,Q(a.uri).rkey);e.push(`<a target="_blank"${N("href",i)} class="feed-embed s-156tlwp"><div class="main s-156tlwp"><div class="avatar-wrapper s-156tlwp">`),a.avatar?e.push(`<img loading="lazy"${N("src",a.avatar)} alt="" class="avatar s-156tlwp"/>`):e.push('<svg viewBox="0 0 32 32" class="avatar s-156tlwp"><path fill="#0070FF" d="M0 0h32v32H0z"></path><path fill="#fff" d="M22.153 22.354a9.328 9.328 0 0 0 3.837-.491 3.076 3.076 0 0 0-4.802-2.79m.965 3.281a6.128 6.128 0 0 0-.965-3.28Zm-11.342-3.28a3.077 3.077 0 0 0-4.801 2.79 9.21 9.21 0 0 0 3.835.49m.966-3.28a6.127 6.127 0 0 0-.966 3.28Zm8.265-8.997a3.076 3.076 0 1 1-6.153 0 3.076 3.076 0 0 1 6.153 0Zm6.154 3.077a2.307 2.307 0 1 1-4.615 0 2.307 2.307 0 0 1 4.615 0Zm-13.847 0a2.307 2.307 0 1 1-4.614 0 2.307 2.307 0 0 1 4.614 0Z"></path><path fill="#fff" d="M22 22c0 3.314-2.686 3.5-6 3.5s-6-.186-6-3.5a6 6 0 0 1 12 0Z"></path></svg>'),e.push(`</div> <div class="info"><p class="name s-156tlwp">${M(a.displayName)}</p> <p class="creator s-156tlwp">Feed by @${M(t.handle)}</p></div></div> <p class="description s-156tlwp">${M(a.description)}</p></a>`)}}(e,{embed:a});else if("app.bsky.graph.defs#listView"===a.$type)!function(e,s){{const{embed:a}=s,t=a.creator,i=R(t.did,Q(a.uri).rkey);e.push(`<a target="_blank"${N("href",i)} class="list-embed s-6uize5"><div class="main s-6uize5"><div class="avatar-wrapper s-6uize5">`),a.avatar?e.push(`<img loading="lazy"${N("src",a.avatar)} alt="" class="avatar s-6uize5"/>`):e.push('<svg viewBox="0 0 32 32" class="avatar s-6uize5"><path fill="#0070FF" d="M0 0h32v32H0z"></path><path fill="#fff" d="M22.153 22.354a9.328 9.328 0 0 0 3.837-.491 3.076 3.076 0 0 0-4.802-2.79m.965 3.281a6.128 6.128 0 0 0-.965-3.28Zm-11.342-3.28a3.077 3.077 0 0 0-4.801 2.79 9.21 9.21 0 0 0 3.835.49m.966-3.28a6.127 6.127 0 0 0-.966 3.28Zm8.265-8.997a3.076 3.076 0 1 1-6.153 0 3.076 3.076 0 0 1 6.153 0Zm6.154 3.077a2.307 2.307 0 1 1-4.615 0 2.307 2.307 0 0 1 4.615 0Zm-13.847 0a2.307 2.307 0 1 1-4.614 0 2.307 2.307 0 0 1 4.614 0Z"></path><path fill="#fff" d="M22 22c0 3.314-2.686 3.5-6 3.5s-6-.186-6-3.5a6 6 0 0 1 12 0Z"></path></svg>'),e.push(`</div> <div class="info"><p class="name s-6uize5">${M(a.name)}</p> <p class="creator s-6uize5">${M((e=>{switch(e){case"app.bsky.graph.defs#curatelist":return"User list";case"app.bsky.graph.defs#modlist":return"Moderation list"}return"Unknown list"})(a.purpose))} by @${M(t.handle)}</p></div></div> <p class="description s-6uize5">${M(a.description)}</p></a>`)}}(e,{embed:a});else if("app.bsky.graph.defs#starterPackViewBasic"===a.$type)!function(e,s){{const{embed:a,large:t=!1}=s,i=a.record,r=a.creator,l=r.did,n=Q(a.uri).rkey,p=((e,s)=>`https://bsky.app/starter-pack/${e}/${s}`)(l,n);if(e.push(`<a target="_blank"${N("href",p)} class="starterpack-embed s-15v965v">`),t){const s=((e,s)=>`https://ogcard.cdn.bsky.app/start/${e}/${s}`)(l,n);e.push(`<img loading="lazy"${N("src",s)} alt="" class="banner s-15v965v"/>`)}e.push(` <div class="meta s-15v965v"><div class="main s-15v965v"><svg fill="none" viewBox="0 0 24 24" class="avatar s-15v965v"><defs><linearGradient id="a" x1="0" x2="100%" y1="0" y2="0" gradientTransform="rotate(45)"><stop offset="0" stop-color="#0A7AFF"></stop><stop offset="1" stop-color="#59B9FF"></stop></linearGradient></defs><path fill="url(#a)" fill-rule="evenodd" d="M11.26 5.227 5.02 6.899c-.734.197-1.17.95-.973 1.685l1.672 6.24c.197.734.951 1.17 1.685.973l6.24-1.672a1.376 1.376 0 0 0 .973-1.685L12.945 6.2a1.375 1.375 0 0 0-1.685-.973Zm-6.566.459a2.632 2.632 0 0 0-1.86 3.223l1.672 6.24a2.632 2.632 0 0 0 3.223 1.861l6.24-1.672a2.631 2.631 0 0 0 1.861-3.223l-1.672-6.24a2.632 2.632 0 0 0-3.223-1.861l-6.24 1.672Z" clip-rule="evenodd"></path><path fill="url(#a)" fill-rule="evenodd" d="M15.138 18.411a4.606 4.606 0 1 0 0-9.211 4.606 4.606 0 0 0 0 9.211Zm0 1.257a5.862 5.862 0 1 0 0-11.724 5.862 5.862 0 0 0 0 11.724Z" clip-rule="evenodd"></path></svg> <div class="info"><p class="name s-15v965v">${M(i.name)}</p> <p class="creator s-15v965v">Starter pack by @${M(r.handle)}</p></div></div> <p class="description s-15v965v">${M(i.description)}</p></div></a>`)}}(e,{embed:a,large:i});else{const s=(e=>{switch(e){case"app.bsky.feed.post":return"post";case"app.bsky.feed.generator":return"feed";case"app.bsky.graph.list":return"list";case"app.bsky.graph.starterpack":return"starter pack";case"app.bsky.labeler.service":return"labeler"}return null})(Q(a.uri).collection);ne(e,s&&("app.bsky.embed.record#viewNotFound"===a.$type||"app.bsky.embed.record#viewBlocked"===a.$type||"app.bsky.embed.record#viewDetached"===a.$type)?`This ${s} is unavailable`:"Unsupported record embed")}}e.push('<div class="embeds s-azdpbr">'),"app.bsky.embed.recordWithMedia#view"===t.$type?(r(e,t.media),e.push(" "),l(e,t.record)):"app.bsky.embed.record#view"===t.$type?l(e,t):r(e,t),e.push("</div>")}}const de=e=>e?.find(e=>"app.bsky.richtext.facet#link"===e.$type||"app.bsky.richtext.facet#mention"===e.$type||"app.bsky.richtext.facet#tag"===e.$type);function oe(e,s){{const{text:a,facets:t,large:i}=s;e.push(`<p${_("rich-text"+(i?" is-large":" is-small"),"s-1lecfnd")}>`);const r=A(a,t);for(let s=0,l=r.length;s<l;s++){let a=r[s];const t=de(a.features);t?"app.bsky.richtext.facet#link"===t.$type?e.push(`<a target="_blank"${N("href",t.uri)} rel="noopener nofollow" class="link s-1lecfnd">${M(a.text)}</a>`):"app.bsky.richtext.facet#mention"===t.$type?e.push(`<a target="_blank"${N("href",U(t.did))} class="mention s-1lecfnd">${M(a.text)}</a>`):"app.bsky.richtext.facet#tag"===t.$type&&e.push(`<a target="_blank"${N("href",I(t.tag))} class="hashtag s-1lecfnd">${M(a.text)}</a>`):e.push(`${M(a.text)}`)}e.push("</p>")}}function ce(e,s){{const{post:a,parent:t,prev:i=!1}=s,r=a.author,l=U(r.did),n=r.displayName?.trim(),p=a.record,d=T(r.did,Q(a.uri).rkey),o=a.replyCount||0,c=a.likeCount||0,h=(a.repostCount||0)+(a.quoteCount||0),u=!!E(r.labels,r.did);if(e.push(`<div class="highlighted-post s-hik11q"><div class="meta s-hik11q"><a${N("href",l)} target="_blank" class="avatar-wrapper s-hik11q">`),r.avatar&&e.push(`<img loading="lazy"${N("src",r.avatar)} alt=""${_("avatar"+(u?" is-blurred":""),"s-hik11q")}/>`),e.push(`</a> <a${N("href",l)} target="_blank" class="name-wrapper s-hik11q">`),n&&e.push(`<bdi class="display-name-wrapper s-hik11q"><span class="display-name s-hik11q">${M(n)}</span></bdi>`),e.push(` <span class="handle s-hik11q">@${M(r.handle)}</span></a> `),i||e.push('<svg class="logo s-hik11q" fill="none" viewBox="0 0 320 286"><path fill="#0A7AFF" d="M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z"></path></svg>'),e.push("</div> "),!i&&p.reply){if(e.push('<p class="context s-hik11q">'),t){const s=t.author;e.push(`Replying to <a target="_blank"${N("href",U(s.did))} dir="auto" class="s-hik11q">${M(s.displayName?.trim()||`@${s.handle}`)}</a>`)}else e.push("Replying to an unknown post");e.push("</p>")}e.push(" "),oe(e,{text:p.text,facets:p.facets,large:!0}),e.push(" "),a.embed&&pe(e,{post:a,embed:a.embed,large:!0}),e.push(` <time${N("datetime",p.createdAt)} class="date s-hik11q">${M(L(p.createdAt))}</time> <div class="stats s-hik11q"><span class="stat s-hik11q"${N("title",1===c?`${X(c)} like`:`${X(c)} likes`)}><svg class="icon" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-width="2" d="M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z"></path></svg> <span>${M(K(c))}</span></span> <span class="stat s-hik11q"${N("title",1===h?`${X(h)} repost`:`${X(h)} reposts`)}><svg class="icon" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="square" stroke-width="2" d="m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15"></path></svg> <span>${M(K(h))}</span></span> <div class="gap s-hik11q"></div> <a${N("href",d)} target="_blank" class="permalink s-hik11q"><span>${M(o?1===o?`Read ${K(o)} reply on Bluesky`:`Read ${K(o)} replies on Bluesky`:"View on Bluesky")}</span></a></div></div>`)}}function he(e,s){{const{post:a,parent:t,prev:i}=s,r=a.author,l=U(r.did),n=r.displayName?.trim(),p=a.record,d=T(r.did,Q(a.uri).rkey),o=!!E(r.labels,r.did);if(e.push('<div class="post s-12mzi62">'),i||e.push('<svg class="logo s-12mzi62" fill="none" viewBox="0 0 320 286"><path fill="#0A7AFF" d="M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z"></path></svg>'),e.push(` <div class="aside s-12mzi62"><a target="_blank"${N("href",l)} class="avatar-wrapper s-12mzi62">`),r.avatar&&e.push(`<img loading="lazy"${N("src",r.avatar)} alt=""${_("avatar"+(o?" is-blurred":""),"s-12mzi62")}/>`),e.push(`</a> <div class="line s-12mzi62"></div></div> <div class="main s-12mzi62"><div class="meta s-12mzi62"><a${N("href",l)} target="_blank" class="name-wrapper s-12mzi62">`),n&&e.push(`<bdi class="display-name-wrapper s-12mzi62"><span class="display-name s-12mzi62">${M(n)}</span></bdi>`),e.push(` <span class="handle s-12mzi62">@${M(r.handle)}</span></a> <span aria-hidden="true" class="dot s-12mzi62">ยท</span> <a target="_blank"${N("href",d)}${N("title",L(p.createdAt))} class="date s-12mzi62"><time${N("datetime",p.createdAt)}>${M(G(p.createdAt))}</time></a></div> `),!i&&p.reply){if(e.push('<p class="context s-12mzi62">'),t){const s=t.author;e.push(`Replying to <a target="_blank"${N("href",U(s.did))} dir="auto" class="s-12mzi62">${M(s.displayName?.trim()||`@${s.handle}`)}</a>`)}else e.push("Replying to an unknown post");e.push("</p>")}e.push(" "),oe(e,{text:p.text,facets:p.facets}),e.push(" "),a.embed&&pe(e,{post:a,embed:a.embed}),e.push("</div></div>")}}function ue(e,s){S(e,{children:e=>{e.push(`<div class="message s-1q9cbx0">${M(s)}</div>`)}})}function me(e,s){{const{thread:a,contextless:t,allowUnauthenticated:i}=s,r=!i&&null!==a&&"app.bsky.feed.defs#threadViewPost"===a.$type&&a.post.author.labels?.some(e=>"!no-unauthenticated"===e.val);if(null===a)ue(e,"The post can't be found, it may have been deleted.");else if(r)ue(e,"The author has requested for their posts to not be displayed on external sites.");else{const s=((e,s,a)=>{const t=[];let i=0,r=s?1:2,l=e;for(;l&&"app.bsky.feed.defs#notFoundPost"!==l.$type&&"app.bsky.feed.defs#blockedPost"!==l.$type;){const e=l.post;if(0!==i&&(t[i-1].parent=e),++i>r)break;const s=e.author;if(!a&&s.labels?.some(e=>"!no-unauthenticated"===e.val))break;t.push({post:e,parent:null}),l=l.parent}return t.reverse()})(a,t,i);S(e,{children:e=>{const a=s;for(let t=0,i=a.length;t<i;t++){let{post:i,parent:r}=a[t];const l=0!==t;t===s.length-1?ce(e,{post:i,parent:r,prev:l}):he(e,{post:i,parent:r,prev:l})}}})}}}const fe=new Intl.DateTimeFormat("en-US",{dateStyle:"long",timeStyle:"short"}),ve=/^at:\/\/((?:did:[a-zA-Z0-9._:%-]+)|(?:[a-zA-Z0-9][a-zA-Z0-9-.]*))(?:\/([a-zA-Z0-9.-]+)(?:\/([a-zA-Z0-9_~.:-]{1,512}))?)?\/?(?:\?([^#\s]*))?(?:#([^\s]*))?$/;class be extends Error{}var ke=s("<bluesky-post><!></bluesky-post>",2);function ye(s,n){e(n,!0);var p=ke();a(()=>t(p,"src",n.data.thread?.post.uri));var d=l(p);$(d,()=>function(e,s={}){let a="";return me({push(e){a+=e}},s.props??{}),{body:a}}(0,{props:n.data}).body),i(s,p),r()}var ge=s('Doing server-side rendering? Check out examples for <a href="https://github.com/mary-ext/bluesky-embed-astro">Astro</a> and <a href="https://github.com/mary-ext/bluesky-embed-sveltekit">SvelteKit</a>.',1),$e=s("<li><p>Insert the following scripts and stylesheets to the <code><head></code> of your website.</p> <!></li> <li><p>Insert the following markup in wherever you want the post to be.</p> <!></li>",1),we=s("<!> <!>",1),xe=s("<!> <!>",1);function ze(s,t){let $;e(t,!0);const A=v(()=>{$?.abort(),$=new AbortController;const e=$.signal;return(async e=>{const s=new k({handler:y({service:e.serviceUri??"https://public.api.bsky.app"})}),a=e.contextless??!1,{data:t}=await s.get("app.bsky.feed.getPostThread",{signal:e.signal,params:{uri:e.uri,parentHeight:a?1:2,depth:0}}).catch(e=>e instanceof g&&"NotFound"===e.kind?{data:null}:Promise.reject(e));return{thread:"app.bsky.feed.defs#threadViewPost"===t?.thread.$type?t.thread:null,contextless:a,allowUnauthenticated:e.allowUnauthenticated??!1}})({uri:`at://${t.matched.author}/app.bsky.feed.post/${t.matched.rkey}`,signal:e})});w(()=>{$?.abort()});const F="https://cdn.jsdelivr.net/npm/bluesky-post-embed@^1.0.0",C=()=>`\x3c!-- Core web component and styling --\x3e\n<script type="module" src="${F}/+esm"><\/script>\n<link rel="stylesheet" href="${F}/dist/core.min.css">\n\n\x3c!-- Built-in themes --\x3e\n<link rel="stylesheet" href="${F}/themes/light.min.css" media="(prefers-color-scheme: light)">\n<link rel="stylesheet" href="${F}/themes/dim.min.css" media="(prefers-color-scheme: dark)">\n\n\x3c!-- Fallback/placeholder elements if JS script is taking a while to load or is failing --\x3e\n<style>\n .bluesky-post-fallback {\n margin: 16px 0;\n border-left: 3px solid var(--divider);\n padding: 4px 8px;\n white-space: pre-wrap;\n overflow-wrap: break-word;\n }\n .bluesky-post-fallback p {\n margin: 0 0 8px 0;\n }\n</style>\n`,M=e=>{const s=e.author,a=e.record;return`<bluesky-post src="${Z(e.uri)}">\n <blockquote class="bluesky-post-fallback">\n <p dir="auto">${Z(a.text)}</p>\n โ ${s.displayName?.trim()?`${Z(s.displayName)} (@${Z(s.handle)})`:`@${Z(s.handle)}`}\n <a href="${Z(((e,s)=>`https://bsky.app/profile/${e}/post/${s}`)(s.did,(e=>{const s=ve.exec(e);if(!s)throw new be(`invalid at-uri: ${e}`);return{repo:s[1],collection:s[2]??"",rkey:s[3]??"",query:s[4]??"",fragment:s[5]??""}})(e.uri).rkey))}">${(e=>{const s=new Date(e);return isNaN(s.getTime())?"N/A":fe.format(s)})(e.indexedAt)}</a>\n </blockquote>\n</bluesky-post>\n`};var N=n(),_=p(N);d(_,()=>u(A),e=>{b(e)},(e,s)=>{var a=xe(),t=p(a);ye(t,{get data(){return u(s)}});var r=m(t,2),n=e=>{x(e,{title:"How do I embed this to my website?",children:(e,a)=>{var t=we(),r=p(t);o(r,{type:"inform",children:(e,s)=>{var a=ge();i(e,a)}});var n=m(r,2);z(n,{children:(e,a)=>{var t=$e(),r=p(t),n=m(l(r),2);{let e=v(C);q(n,{get code(){return u(e)}})}var d=m(r,2),o=m(l(d),2);{let e=v(()=>M(u(s).thread.post));q(o,{get code(){return u(e)}})}i(e,t)}}),i(e,t)}})};f(r,e=>{u(s).thread&&e(n)}),i(e,a)},(e,s)=>{o(e,{type:"alert",children:(e,t)=>{var r=c();a(()=>h(r,""+u(s))),i(e,r)}})}),i(s,N),r()}export{ze as default};
+1
assets/PostDisplay-yMSDBkol.css
+1
assets/PostDisplay-yMSDBkol.css
···
1
+
.bluesky-embed.s-3olstj{position:relative;box-sizing:border-box;margin:0 auto;border:1px solid var(--divider);border-radius:8px;background:var(--background-primary);min-width:250px;max-width:550px;overflow:hidden;color:var(--text-primary);font-weight:400;font-size:calc(var(--font-size) * .875);line-height:calc(var(--font-size) * 1.25);font-family:var(--font-family);:where(*),:where(*:before),:where(*:after){box-sizing:border-box;margin:0;padding:0}:where(a){color:inherit;text-decoration:none}:where(.icon){flex-shrink:0;width:1em;height:1em}}.gate.s-q6x07m{display:flex;align-items:center;gap:12px;cursor:pointer;border:1px solid var(--divider);border-radius:6px;padding:0 12px;height:44px;.content-hider[open]:where(.s-q6x07m) &{margin-bottom:12px}&:hover{border-color:var(--divider-hover)}}.icon.s-q6x07m{width:18px;height:18px;color:var(--text-secondary)}.label.s-q6x07m{flex-grow:1;overflow:hidden;font-weight:500;user-select:none;text-overflow:ellipsis}.action.s-q6x07m{color:var(--text-link);font-weight:500;font-size:calc(var(--font-size) * .8125);line-height:calc(var(--font-size) * 1.25);&:before{content:"Show"}.content-hider[open]:where(.s-q6x07m) &:before{content:"Hide"}}.external-embed.s-rtbqd8{display:block;border:1px solid var(--divider);border-radius:6px;overflow:hidden;&:hover{border-color:var(--divider-hover)}}.thumbnail.s-rtbqd8{display:block;border-bottom:1px solid var(--divider);background:#000;aspect-ratio:1.91;width:100%;.external-embed:where(.s-rtbqd8):hover &{border-color:var(--divider-hover)}}.meta.s-rtbqd8{padding:12px}.title.s-rtbqd8{display:-webkit-box;overflow:hidden;font-weight:700;white-space:pre-wrap;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow-wrap:break-word;&:empty{display:none}}.description.s-rtbqd8{display:-webkit-box;overflow:hidden;color:var(--text-secondary);font-size:calc(var(--font-size) * .8125);white-space:pre-wrap;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow-wrap:break-word;&:empty{display:none}}.domain.s-rtbqd8{display:flex;align-items:center;gap:6px;margin:6px 0 0;color:var(--text-secondary);font-weight:500;font-size:calc(var(--font-size) * .75)}.feed-embed.s-156tlwp{display:flex;flex-direction:column;gap:12px;border:1px solid var(--divider);border-radius:6px;padding:12px;&:hover{border-color:var(--divider-hover)}}.main.s-156tlwp{display:flex;gap:12px}.avatar-wrapper.s-156tlwp{margin:2px 0 0;border-radius:6px;background:var(--background-secondary);width:36px;height:36px;overflow:hidden}.avatar.s-156tlwp{width:100%;height:100%;object-fit:cover}.name.s-156tlwp{font-weight:700}.creator.s-156tlwp{color:var(--text-secondary);font-size:calc(var(--font-size) * .8125)}.description.s-156tlwp{display:-webkit-box;overflow:hidden;font-size:calc(var(--font-size) * .8125);white-space:pre-wrap;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow-wrap:break-word;&:empty{display:none}}.is-aligned.s-t3k6fc{align-self:baseline;max-width:100%}.grid.s-t3k6fc{display:flex;gap:2px}.col.s-t3k6fc{display:flex;flex:1;flex-direction:column;gap:2px}.square.s-t3k6fc{aspect-ratio:1}.wide.s-t3k6fc{aspect-ratio:1.5}.item.s-t3k6fc{position:relative;flex-grow:1;flex-shrink:0;overflow:hidden}.is-bordered.s-t3k6fc{.tl:where(.s-t3k6fc),.tr:where(.s-t3k6fc),.bl:where(.s-t3k6fc),.br:where(.s-t3k6fc){border:1px solid var(--divider)}.tl:where(.s-t3k6fc){border-top-left-radius:6px}.tr:where(.s-t3k6fc){border-top-right-radius:6px}.bl:where(.s-t3k6fc){border-bottom-left-radius:6px}.br:where(.s-t3k6fc){border-bottom-right-radius:6px}}.single-item.s-t3k6fc{position:relative;aspect-ratio:16 / 9;overflow:hidden;.image:where(.s-t3k6fc){object-fit:contain}}.is-standalone.s-t3k6fc{min-width:64px;max-width:100%;min-height:64px;max-height:320px}.image.s-t3k6fc{position:absolute;inset:0;background:#000;width:100%;height:100%;object-fit:cover;font-size:0px}.is-blurred.s-t3k6fc{scale:125%;filter:blur(24px)}.placeholder.s-t3k6fc{width:100vw;height:100vh}.list-embed.s-6uize5{display:flex;flex-direction:column;gap:12px;border:1px solid var(--divider);border-radius:6px;padding:12px;&:hover{border-color:var(--divider-hover)}}.main.s-6uize5{display:flex;gap:12px}.avatar-wrapper.s-6uize5{margin:2px 0 0;border-radius:6px;background:var(--background-secondary);width:36px;height:36px;overflow:hidden}.avatar.s-6uize5{width:100%;height:100%;object-fit:cover}.name.s-6uize5{font-weight:700}.creator.s-6uize5{color:var(--text-secondary);font-size:calc(var(--font-size) * .8125)}.description.s-6uize5{display:-webkit-box;overflow:hidden;font-size:calc(var(--font-size) * .8125);white-space:pre-wrap;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow-wrap:break-word;&:empty{display:none}}.video-embed.s-1azk58e{display:block;position:relative;background:#000;aspect-ratio:16 / 9;overflow:hidden}.is-bordered.s-1azk58e{border:1px solid var(--divider);border-radius:6px}.is-standalone.s-1azk58e{align-self:baseline;aspect-ratio:auto;max-width:100%}.constrainer.s-1azk58e{min-width:64px;max-width:100%;min-height:64px;max-height:320px}.thumbnail.s-1azk58e{width:100%;height:100%;object-fit:contain}.is-blurred.s-1azk58e{scale:125%;filter:blur(24px)}.placeholder.s-1azk58e{width:100vw;height:100vh}.play.s-1azk58e{display:grid;position:absolute;top:50%;left:50%;place-items:center;translate:-50% -50%;border-radius:50%;background:#40404099;aspect-ratio:1 / 1;height:40%;max-height:48px;color:#fff;font-size:20px;.icon:where(.s-1azk58e){width:40%;height:40%}.is-standalone:where(.s-1azk58e) &:hover{background:#404040cc}}.quote-embed.s-za6fip{display:block;border:1px solid var(--divider);border-radius:6px;overflow:hidden;&:hover{border-color:var(--divider-hover)}}.meta.s-za6fip{display:flex;padding:12px 12px 0;color:var(--text-secondary);.avatar-wrapper:where(.s-za6fip){flex-shrink:0;margin:0 8px 0 0;border-radius:9999px;background:var(--background-secondary);width:20px;height:20px;overflow:hidden}.avatar:where(.s-za6fip){width:100%;height:100%}.name-wrapper:where(.s-za6fip){display:flex;gap:4px;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.display-name-wrapper:where(.s-za6fip){overflow:hidden;text-overflow:ellipsis}.display-name:where(.s-za6fip){color:var(--text-primary);font-weight:700}.handle:where(.s-za6fip){display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dot:where(.s-za6fip){flex-shrink:0;margin:0 6px}.date:where(.s-za6fip){white-space:nowrap}}.body.s-za6fip{display:flex;align-items:flex-start}.aside.s-za6fip{flex-grow:1;flex-basis:0;margin:8px 0 12px 12px;max-width:20%}.text.s-za6fip{display:-webkit-box;margin:8px 12px 12px;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:6;line-clamp:6;flex-grow:4;flex-basis:0px;min-width:0px;white-space:pre-wrap;overflow-wrap:break-word}.divide.s-za6fip{padding:6px 0}.starterpack-embed.s-15v965v{display:block;border:1px solid var(--divider);border-radius:6px;overflow:hidden;&:hover{border-color:var(--divider-hover)}}.banner.s-15v965v{display:block;aspect-ratio:1.91;width:100%}.meta.s-15v965v{display:flex;flex-direction:column;gap:12px;padding:12px}.main.s-15v965v{display:flex;gap:12px}.avatar.s-15v965v{margin:2px;width:36px;height:36px}.name.s-15v965v{font-weight:700}.creator.s-15v965v{color:var(--text-secondary);font-size:calc(var(--font-size) * .8125)}.description.s-15v965v{display:-webkit-box;overflow:hidden;font-size:calc(var(--font-size) * .8125);white-space:pre-wrap;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow-wrap:break-word;&:empty{display:none}}.embeds.s-azdpbr{display:flex;flex-direction:column;gap:12px;margin:12px 0 0}.message.s-azdpbr{border:1px solid var(--divider);border-radius:6px;padding:12px;color:var(--text-secondary)}.rich-text.s-1lecfnd{overflow:hidden;white-space:pre-wrap;overflow-wrap:break-word;&:empty{display:none}}.is-large.s-1lecfnd{font-size:calc(var(--font-size) * 1);line-height:calc(var(--font-size) * 1.5)}.link.s-1lecfnd,.mention.s-1lecfnd,.hashtag.s-1lecfnd{color:var(--text-link);&:hover{text-decoration:underline}}.highlighted-post.s-hik11q{padding:16px}.meta.s-hik11q{display:flex;align-items:center;gap:12px;margin:0 0 12px;color:var(--text-secondary)}.avatar-wrapper.s-hik11q{display:block;flex-shrink:0;border-radius:9999px;background:var(--background-secondary);width:40px;height:40px;overflow:hidden;&:hover{filter:brightness(.85)}}.avatar.s-hik11q{width:100%;height:100%;object-fit:cover}.is-blurred.s-hik11q{scale:125%;filter:blur(4px)}.name-wrapper.s-hik11q{display:block;flex-grow:1;max-width:100%;overflow:hidden;color:inherit;text-overflow:ellipsis;white-space:nowrap}.display-name-wrapper.s-hik11q{overflow:hidden;text-overflow:ellipsis;.name-wrapper:where(.s-hik11q):hover &{text-decoration:underline}}.display-name.s-hik11q{color:var(--text-primary);font-weight:700}.handle.s-hik11q{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.logo.s-hik11q{width:32px;height:32px}.context.s-hik11q{overflow:hidden;color:var(--text-secondary);font-size:calc(var(--font-size) * .8125);text-overflow:ellipsis;white-space:nowrap;a:where(.s-hik11q){color:inherit;font-weight:500;&:hover{text-decoration:underline}}}.date.s-hik11q{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:12px 0 0;border-bottom:1px solid var(--divider);padding:0 0 12px;color:var(--text-secondary)}.stats.s-hik11q{display:flex;flex-wrap:wrap;align-items:center;gap:8px 16px;margin:0 0 -16px;padding:12px 0;color:var(--text-secondary);.gap:where(.s-hik11q){flex:1 1 auto}.permalink:where(.s-hik11q){display:flex;align-items:center;gap:4px;color:var(--text-link);font-weight:700;&:hover{text-decoration:underline}}}.stat.s-hik11q{display:flex;align-items:center;gap:8px;font-weight:500}.post.s-12mzi62{display:flex;position:relative;gap:12px;padding:12px 16px 0}.logo.s-12mzi62{position:absolute;top:12px;right:12px;width:24px;height:24px}.aside.s-12mzi62{flex-shrink:0}.avatar-wrapper.s-12mzi62{display:block;border-radius:9999px;background:var(--background-secondary);width:40px;height:40px;overflow:hidden;&:hover{filter:brightness(.85)}}.avatar.s-12mzi62{width:100%;height:100%;object-fit:cover}.is-blurred.s-12mzi62{scale:125%;filter:blur(4px)}.line.s-12mzi62{position:absolute;top:56px;bottom:-12px;left:35px;border-left:2px solid var(--divider)}.main.s-12mzi62{display:flex;flex-grow:1;flex-direction:column;min-width:0px}.meta.s-12mzi62{display:flex;align-items:center;margin:0 0 2px;padding:0 32px 0 0;color:var(--text-secondary);.name-wrapper:where(.s-12mzi62){display:flex;gap:4px;max-width:100%;overflow:hidden;color:inherit;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.display-name-wrapper:where(.s-12mzi62){overflow:hidden;text-overflow:ellipsis;.name-wrapper:where(.s-12mzi62):hover &{text-decoration:underline}}.display-name:where(.s-12mzi62){color:var(--text-primary);font-weight:700}.handle:where(.s-12mzi62){display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dot:where(.s-12mzi62){flex-shrink:0;margin:0 6px}.date:where(.s-12mzi62){color:inherit;text-decoration:none;white-space:nowrap;&:hover{text-decoration:underline}}}.context.s-12mzi62{overflow:hidden;color:var(--text-secondary);font-size:calc(var(--font-size) * .8125);text-overflow:ellipsis;white-space:nowrap;a:where(.s-12mzi62){color:inherit;font-weight:500;&:hover{text-decoration:underline}}}.message.s-1q9cbx0{margin:0 auto;padding:32px 16px;max-width:380px;color:var(--text-secondary);text-align:center}
+1
assets/ProfileCardDisplay-BpCMWdM3.js
+1
assets/ProfileCardDisplay-BpCMWdM3.js
···
1
+
import{p as e,f as s,t,s as a,c as n,a as r,b as l,d as o,e as i,g as c,B as p,h as d,i as u,j as f,k as h,l as m,u as b,C as g}from"./index-CD_0uzJz.js";import{X as w,s as y,a as v,h as $,o as k,G as x,b as q,C,e as F}from"./GuideInstructions-CTis8QB-.js";const I=/^[@๏ผ ]([a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*(?:\.[a-zA-Z]{2,}))($|\s|\p{P})/u,N=/^(?:#(?!\ufe0f|\u20e3)|๏ผ)([\p{N}]*[\p{L}\p{M}\p{Pc}][\p{L}\p{M}\p{Pc}\p{N}]*)($|\s|\p{P})/u,A=/^:([\w-]+):/,P=/^https?:\/\/[\S]+/,B=/(?:(?<!\(.*)\))?[.,;]*$/,U=/^\[((?:\[(?:\\.|[^\[\]\\])*\]|\\.|[^\[\]\\])*?)\]\((.*?)\)/,_=/^\\([@๏ผ #:\\\[])/,j=/^.+?(?:(?=$|[:\\\[]|https?:\/\/)|(?<=\s|[(){}\/\\\[\]\-|:;'".,=+])(?=[@๏ผ #๏ผ]))/s,z=e=>{const s=I.exec(e);if(s&&"@"!==s[2]){const e=s[2].length;return{type:"mention",raw:e>0?s[0].slice(0,-e):s[0],handle:s[1]}}},S=e=>{const s=N.exec(e);if(s&&"#"!==s[2]){const e=s[2].length;return{type:"topic",raw:e>0?s[0].slice(0,-e):s[0],name:s[1]}}},M=e=>{const s=A.exec(e);if(s)return{type:"emote",raw:s[0],name:s[1]}},Z=e=>{const s=P.exec(e);if(s){const e=s[0].replace(B,"");return{type:"autolink",raw:e,url:e}}},G=e=>{const s=U.exec(e);if(s)return{type:"link",raw:s[0],text:s[1],url:s[2]}},H=e=>{const s=_.exec(e);if(s)return{type:"escape",raw:s[0],escaped:s[1]}},L=e=>{const s=j.exec(e);if(s)return{type:"text",raw:s[0],text:s[0]}},T=/[&"<]/g,E=/[&<]/g;function R(e,s){const t=String(e??""),a=s?T:E;a.lastIndex=0;let n="",r=0;for(;a.test(t);){const e=a.lastIndex-1,s=t[e];n+=t.substring(r,e)+("&"===s?"&":'"'===s?""":"<"),r=e+1}return n+t.substring(r)}function X(e,s,t=!1){if("hidden"===e&&"until-found"!==s&&(t=!0),null==s||!s&&t)return"";return` ${e}${t?"":`="${R(s,!0)}"`}`}function D(e,s,t){var a=function(e,s){var t=null==e?"":""+e;return""===(t=t?t+" "+s:s)?null:t}(e,s);return a?` class="${R(a,!0)}"`:""}function J(e,s){const{children:t}=s;e.push('<div class="bluesky-embed s-dgn7w7">'),t(e),e.push("</div>")}const K=e=>`https://bsky.app/profile/${e}`,O=e=>`https://bsky.app/hashtag/${e}`,Q={"!hide":{name:"Hidden by moderators",flags:1},"!warn":{name:"Content warning",flags:1},porn:{name:"Adult content",flags:0},sexual:{name:"Sexually suggestive",flags:0},"graphic-media":{name:"Graphic media",flags:0},nudity:{name:"Nudity",flags:0}},V=new Intl.NumberFormat("en-US"),W=new Intl.NumberFormat("en-US",{notation:"compact"}),Y=e=>e<1e3?""+e:e<1e5?V.format(e):W.format(e),ee=/^https?:\/\//;function se(e,s){{const{text:t}=s;e.push('<p class="rich-text is-small s-1ea7h2m">');const a=(e=>{const s=[];let t,a;for(;e;)if(t=a,a=H(e)||Z(e)||z(e)||S(e)||M(e)||G(e))e=e.slice(a.raw.length),s.push(a);else if(a=L(e))e=e.slice(a.raw.length),t&&"text"===t.type?(t.raw+=a.raw,t.text+=a.text,a=t):s.push(a);else if(e)throw new Error("infinite loop encountered");return s})(t);for(let s=0,n=a.length;s<n;s++){let t=a[s];"autolink"===t.type?e.push(`<a target="_blank"${X("href",t.url)} rel="noopener nofollow" class="link s-1ea7h2m">${R(t.raw.replace(ee,""))}</a>`):"mention"===t.type?e.push(`<a target="_blank"${X("href",K(t.handle))} class="mention s-1ea7h2m">${R(t.raw)}</a>`):"topic"===t.type?e.push(`<a target="_blank"${X("href",O(t.name))} class="hashtag s-1ea7h2m">${R(t.raw)}</a>`):e.push(`${R(t.raw)}`)}e.push("</p>")}}function te(e,s){{const{profile:t}=s,a=K(t.did),n=((e,s)=>{if(e?.length)for(let t=0,a=e.length;t<a;t++){const a=e[t],n=a.val;if(!(n in Q))continue;const r=Q[n];if(!(1&r.flags&&a.src===s))return r}})(t.labels,t.did);e.push('<div class="profile-card has-banner s-2b3fq6"><div class="banner-wrapper s-2b3fq6">'),t.banner&&e.push(`<img loading="lazy"${X("src",t.banner)} alt=""${D("banner"+(n?" is-blurred":""),"s-2b3fq6")}/>`),e.push(`</div> <div class="contents s-2b3fq6"><div class="header s-2b3fq6"><a${X("href",a)} target="_blank" class="avatar-wrapper s-2b3fq6">`),t.avatar&&e.push(`<img loading="lazy"${X("src",t.avatar)} alt=""${D("avatar"+(n?" is-blurred":""),"s-2b3fq6")}/>`),e.push(`</a> <div class="actions s-2b3fq6"><a${X("href",a)} target="_blank" class="follow-button s-2b3fq6"><svg class="icon s-2b3fq6" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="square" stroke-width="2" d="M12 4v8m0 0v8m0-8H4m8 0h8"></path></svg> <span>Follow</span></a> <svg class="logo s-2b3fq6" fill="none" viewBox="0 0 320 286"><path fill="#0A7AFF" d="M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z"></path></svg></div></div> <div class="name-wrapper"><p dir="auto" class="display-name s-2b3fq6">${R(t.displayName?.trim()||t.handle.slice(0,64))}</p> <p class="handle s-2b3fq6">@${R(t.handle)}</p></div> <div class="stats s-2b3fq6"><span class="stat-entry s-2b3fq6"><span class="stat-count s-2b3fq6">${R(Y(t.followersCount||0))}</span> <span>${R(1===t.followersCount?"Follower":"Followers")}</span></span> <span class="stat-entry s-2b3fq6"><span class="stat-count s-2b3fq6">${R(Y(t.followsCount||0))}</span> <span>Following</span></span></div> `),t.description?.trim()&&se(e,{text:t.description}),e.push("</div></div>")}}function ae(e,s){J(e,{children:e=>{e.push(`<div class="message s-ibmh3w">${R(s)}</div>`)}})}function ne(e,s){{const{profile:t,allowUnauthenticated:a}=s,n=!a&&t?.labels?.some(e=>"!no-unauthenticated"===e.val);null===t?ae(e,"The profile can't be found, it may have been deleted."):n?ae(e,"The user has requested for their profile to not be displayed on external sites."):J(e,{children:e=>{te(e,{profile:t})}})}}var re=s("<bluesky-profile-card><!></bluesky-profile-card>",2);function le(s,o){e(o,!0);var i=re();t(()=>a(i,"actor",o.data.profile?.did));var c=n(i);$(c,()=>function(e,s={}){let t="";return ne({push(e){t+=e}},s.props??{}),{body:t}}(0,{props:o.data}).body),r(s,i),l()}var oe=s("<li><p>Insert the following scripts and stylesheets to the <code><head></code> of your website.</p> <!></li> <li><p>Insert the following markup in wherever you want the profile feed to be.</p> <!></li>",1),ie=s("<!> <!>",1);function ce(s,a){let $;e(a,!0);const I=b(()=>{$?.abort(),$=new AbortController;const e=$.signal;return(async e=>{const s=e.actor,t=e.allowUnauthenticated??!1,a=new w({handler:y({service:e.serviceUri??"https://public.api.bsky.app"})}),{data:n}=await a.get("app.bsky.actor.getProfile",{signal:e.signal,params:{actor:s}}).catch(e=>e instanceof v&&"InvalidRequest"===e.kind&&"Profile not found"===e.description?{data:null}:Promise.reject(e));return{profile:n,allowUnauthenticated:t}})({actor:a.matched.actor,signal:e})});k(()=>{$?.abort()});const N=()=>{const e="https://cdn.jsdelivr.net/npm/bluesky-profile-card-embed@^1.0.0";return`\x3c!-- Core web component and styling --\x3e\n<script type="module" src="${e}/+esm"><\/script>\n<link rel="stylesheet" href="${e}/dist/core.min.css">\n\n\x3c!-- Built-in themes --\x3e\n<link rel="stylesheet" href="${e}/themes/light.min.css" media="(prefers-color-scheme: light)">\n<link rel="stylesheet" href="${e}/themes/dim.min.css" media="(prefers-color-scheme: dark)">\n`};var A=o(),P=i(A);c(P,()=>f(I),e=>{g(e)},(e,s)=>{var t=ie(),a=i(t);le(a,{get data(){return f(s)}});var l=h(a,2),o=e=>{x(e,{title:"How do I embed this to my website?",children:(e,t)=>{q(e,{children:(e,t)=>{var a=oe(),l=i(a),o=h(n(l),2);{let e=b(N);C(o,{get code(){return f(e)}})}var c=h(l,2),p=h(n(c),2);{let e=b(()=>(e=>{const s=`https://bsky.app/profile/${e.did}`;return`<bluesky-profile-card actor="${F(e.did)}">\n <a target="_blank" href="${F(s)}" class="bluesky-profile-card-fallback">\n ${e.displayName?.trim()?`Follow ${F(e.displayName)} (@${F(e.handle)}) on Bluesky`:`Follow @${F(e.handle)} on Bluesky`}\n </a>\n</bluesky-profile-card>\n`})(f(s).profile));C(p,{get code(){return f(e)}})}r(e,a)}})}})};m(l,e=>{f(s).profile&&e(o)}),r(e,t)},(e,s)=>{p(e,{type:"alert",children:(e,a)=>{var n=d();t(()=>u(n,""+f(s))),r(e,n)}})}),r(s,A),l()}export{ce as default};
+1
assets/ProfileCardDisplay-D4FwjqsR.css
+1
assets/ProfileCardDisplay-D4FwjqsR.css
···
1
+
.bluesky-embed.s-dgn7w7{position:relative;box-sizing:border-box;margin:0 auto;border:1px solid var(--divider);border-radius:8px;background:var(--background-primary);min-width:250px;max-width:550px;overflow:hidden;color:var(--text-primary);font-weight:400;font-size:calc(var(--font-size) * .875);line-height:calc(var(--font-size) * 1.25);font-family:var(--font-family);:where(*),:where(*:before),:where(*:after){box-sizing:border-box;margin:0;padding:0}:where(a){color:inherit;text-decoration:none}:where(.icon){flex-shrink:0;width:1em;height:1em}}.rich-text.s-1ea7h2m{overflow:hidden;white-space:pre-wrap;overflow-wrap:break-word;&:empty{display:none}}.link.s-1ea7h2m,.mention.s-1ea7h2m,.hashtag.s-1ea7h2m{color:var(--text-link);&:hover{text-decoration:underline}}.profile-card.s-2b3fq6{display:flex;flex-direction:column}.is-blurred.s-2b3fq6{scale:125%;filter:blur(4px)}.banner-wrapper.s-2b3fq6{background:var(--background-secondary);aspect-ratio:3 / 1;overflow:hidden}.banner.s-2b3fq6{width:100%;height:100%;object-fit:cover}.contents.s-2b3fq6{display:flex;position:relative;flex-direction:column;gap:8px;padding:12px 16px 16px}.logo.s-2b3fq6{width:24px;height:24px}.header.s-2b3fq6{display:flex;justify-content:space-between;align-items:end}.actions.s-2b3fq6{display:flex;align-items:center;gap:16px}.avatar-wrapper.s-2b3fq6{display:block;flex-shrink:0;outline:2px solid var(--background-primary);border-radius:9999px;background:var(--background-secondary);width:90px;height:90px;overflow:hidden;.has-banner:where(.s-2b3fq6) &{margin-top:-56px}}.avatar.s-2b3fq6{width:100%;height:100%;object-fit:cover;.avatar-wrapper:where(.s-2b3fq6):hover &{filter:brightness(.85);&.is-blurred{filter:brightness(.85) blur(4px)}}}.follow-button.s-2b3fq6{display:flex;align-items:center;gap:6px;border-radius:9999px;background:var(--button);padding:9px 12px;color:var(--button-text);font-weight:600;font-size:calc(var(--font-size) * .8125);line-height:calc(var(--font-size) * 1);user-select:none;.icon:where(.s-2b3fq6){font-size:16px}&:hover{background:var(--button-hover)}}.display-name.s-2b3fq6{font-weight:700;font-size:calc(var(--font-size) * 1.25);line-height:calc(var(--font-size) * 1.75);overflow-wrap:break-word}.handle.s-2b3fq6{color:var(--text-secondary);overflow-wrap:break-word}.stats.s-2b3fq6{display:flex;flex-wrap:wrap;gap:20px;min-width:0}.stat-entry.s-2b3fq6{color:var(--text-secondary)}.stat-count.s-2b3fq6{color:var(--text-primary);font-weight:700}.message.s-ibmh3w{margin:0 auto;padding:32px 16px;max-width:380px;color:var(--text-secondary);text-align:center}
+1
assets/ProfileFeedDisplay-DOw9fkTH.css
+1
assets/ProfileFeedDisplay-DOw9fkTH.css
···
1
+
.bluesky-embed.s-1pz15a1{position:relative;box-sizing:border-box;margin:0 auto;border:1px solid var(--divider);border-radius:8px;background:var(--background-primary);min-width:250px;max-width:550px;overflow:hidden;color:var(--text-primary);font-weight:400;font-size:calc(var(--font-size) * .875);line-height:calc(var(--font-size) * 1.25);font-family:var(--font-family);:where(*),:where(*:before),:where(*:after){box-sizing:border-box;margin:0;padding:0}:where(a){color:inherit;text-decoration:none}:where(.icon){flex-shrink:0;width:1em;height:1em}}.gate.s-1se5tqk{display:flex;align-items:center;gap:12px;cursor:pointer;border:1px solid var(--divider);border-radius:6px;padding:0 12px;height:44px;.content-hider[open]:where(.s-1se5tqk) &{margin-bottom:12px}&:hover{border-color:var(--divider-hover)}}.icon.s-1se5tqk{width:18px;height:18px;color:var(--text-secondary)}.label.s-1se5tqk{flex-grow:1;overflow:hidden;font-weight:500;user-select:none;text-overflow:ellipsis}.action.s-1se5tqk{color:var(--text-link);font-weight:500;font-size:calc(var(--font-size) * .8125);line-height:calc(var(--font-size) * 1.25);&:before{content:"Show"}.content-hider[open]:where(.s-1se5tqk) &:before{content:"Hide"}}.external-embed.s-au8a8u{display:block;border:1px solid var(--divider);border-radius:6px;overflow:hidden;&:hover{border-color:var(--divider-hover)}}.thumbnail.s-au8a8u{display:block;border-bottom:1px solid var(--divider);background:#000;aspect-ratio:1.91;width:100%;.external-embed:where(.s-au8a8u):hover &{border-color:var(--divider-hover)}}.meta.s-au8a8u{padding:12px}.title.s-au8a8u{display:-webkit-box;overflow:hidden;font-weight:700;white-space:pre-wrap;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow-wrap:break-word;&:empty{display:none}}.description.s-au8a8u{display:-webkit-box;overflow:hidden;color:var(--text-secondary);font-size:calc(var(--font-size) * .8125);white-space:pre-wrap;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow-wrap:break-word;&:empty{display:none}}.domain.s-au8a8u{display:flex;align-items:center;gap:6px;margin:6px 0 0;color:var(--text-secondary);font-weight:500;font-size:calc(var(--font-size) * .75)}.feed-embed.s-1c1phtf{display:flex;flex-direction:column;gap:12px;border:1px solid var(--divider);border-radius:6px;padding:12px;&:hover{border-color:var(--divider-hover)}}.main.s-1c1phtf{display:flex;gap:12px}.avatar-wrapper.s-1c1phtf{margin:2px 0 0;border-radius:6px;background:var(--background-secondary);width:36px;height:36px;overflow:hidden}.avatar.s-1c1phtf{width:100%;height:100%;object-fit:cover}.name.s-1c1phtf{font-weight:700}.creator.s-1c1phtf{color:var(--text-secondary);font-size:calc(var(--font-size) * .8125)}.description.s-1c1phtf{display:-webkit-box;overflow:hidden;font-size:calc(var(--font-size) * .8125);white-space:pre-wrap;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow-wrap:break-word;&:empty{display:none}}.is-aligned.s-1d339cy{align-self:baseline;max-width:100%}.grid.s-1d339cy{display:flex;gap:2px}.col.s-1d339cy{display:flex;flex:1;flex-direction:column;gap:2px}.square.s-1d339cy{aspect-ratio:1}.wide.s-1d339cy{aspect-ratio:1.5}.item.s-1d339cy{position:relative;flex-grow:1;flex-shrink:0;overflow:hidden}.is-bordered.s-1d339cy{.tl:where(.s-1d339cy),.tr:where(.s-1d339cy),.bl:where(.s-1d339cy),.br:where(.s-1d339cy){border:1px solid var(--divider)}.tl:where(.s-1d339cy){border-top-left-radius:6px}.tr:where(.s-1d339cy){border-top-right-radius:6px}.bl:where(.s-1d339cy){border-bottom-left-radius:6px}.br:where(.s-1d339cy){border-bottom-right-radius:6px}}.single-item.s-1d339cy{position:relative;aspect-ratio:16 / 9;overflow:hidden;.image:where(.s-1d339cy){object-fit:contain}}.is-standalone.s-1d339cy{min-width:64px;max-width:100%;min-height:64px;max-height:320px}.image.s-1d339cy{position:absolute;inset:0;background:#000;width:100%;height:100%;object-fit:cover;font-size:0px}.is-blurred.s-1d339cy{scale:125%;filter:blur(24px)}.placeholder.s-1d339cy{width:100vw;height:100vh}.list-embed.s-1mo1e33{display:flex;flex-direction:column;gap:12px;border:1px solid var(--divider);border-radius:6px;padding:12px;&:hover{border-color:var(--divider-hover)}}.main.s-1mo1e33{display:flex;gap:12px}.avatar-wrapper.s-1mo1e33{margin:2px 0 0;border-radius:6px;background:var(--background-secondary);width:36px;height:36px;overflow:hidden}.avatar.s-1mo1e33{width:100%;height:100%;object-fit:cover}.name.s-1mo1e33{font-weight:700}.creator.s-1mo1e33{color:var(--text-secondary);font-size:calc(var(--font-size) * .8125)}.description.s-1mo1e33{display:-webkit-box;overflow:hidden;font-size:calc(var(--font-size) * .8125);white-space:pre-wrap;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow-wrap:break-word;&:empty{display:none}}.video-embed.s-1h3cnsw{display:block;position:relative;background:#000;aspect-ratio:16 / 9;overflow:hidden}.is-bordered.s-1h3cnsw{border:1px solid var(--divider);border-radius:6px}.is-standalone.s-1h3cnsw{align-self:baseline;aspect-ratio:auto;max-width:100%}.constrainer.s-1h3cnsw{min-width:64px;max-width:100%;min-height:64px;max-height:320px}.thumbnail.s-1h3cnsw{width:100%;height:100%;object-fit:contain}.is-blurred.s-1h3cnsw{scale:125%;filter:blur(24px)}.placeholder.s-1h3cnsw{width:100vw;height:100vh}.play.s-1h3cnsw{display:grid;position:absolute;top:50%;left:50%;place-items:center;translate:-50% -50%;border-radius:50%;background:#40404099;aspect-ratio:1 / 1;height:40%;max-height:48px;color:#fff;font-size:20px;.icon:where(.s-1h3cnsw){width:40%;height:40%}.is-standalone:where(.s-1h3cnsw) &:hover{background:#404040cc}}.quote-embed.s-vbjlyj{display:block;border:1px solid var(--divider);border-radius:6px;overflow:hidden;&:hover{border-color:var(--divider-hover)}}.meta.s-vbjlyj{display:flex;padding:12px 12px 0;color:var(--text-secondary);.avatar-wrapper:where(.s-vbjlyj){flex-shrink:0;margin:0 8px 0 0;border-radius:9999px;background:var(--background-secondary);width:20px;height:20px;overflow:hidden}.avatar:where(.s-vbjlyj){width:100%;height:100%}.name-wrapper:where(.s-vbjlyj){display:flex;gap:4px;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.display-name-wrapper:where(.s-vbjlyj){overflow:hidden;text-overflow:ellipsis}.display-name:where(.s-vbjlyj){color:var(--text-primary);font-weight:700}.handle:where(.s-vbjlyj){display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dot:where(.s-vbjlyj){flex-shrink:0;margin:0 6px}.date:where(.s-vbjlyj){white-space:nowrap}}.body.s-vbjlyj{display:flex;align-items:flex-start}.aside.s-vbjlyj{flex-grow:1;flex-basis:0;margin:8px 0 12px 12px;max-width:20%}.text.s-vbjlyj{display:-webkit-box;margin:8px 12px 12px;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:6;line-clamp:6;flex-grow:4;flex-basis:0px;min-width:0px;white-space:pre-wrap;overflow-wrap:break-word}.divide.s-vbjlyj{padding:6px 0}.starterpack-embed.s-whpa2l{display:block;border:1px solid var(--divider);border-radius:6px;overflow:hidden;&:hover{border-color:var(--divider-hover)}}.banner.s-whpa2l{display:block;aspect-ratio:1.91;width:100%}.meta.s-whpa2l{display:flex;flex-direction:column;gap:12px;padding:12px}.main.s-whpa2l{display:flex;gap:12px}.avatar.s-whpa2l{margin:2px;width:36px;height:36px}.name.s-whpa2l{font-weight:700}.creator.s-whpa2l{color:var(--text-secondary);font-size:calc(var(--font-size) * .8125)}.description.s-whpa2l{display:-webkit-box;overflow:hidden;font-size:calc(var(--font-size) * .8125);white-space:pre-wrap;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow-wrap:break-word;&:empty{display:none}}.embeds.s-1nks9gp{display:flex;flex-direction:column;gap:12px;margin:12px 0 0}.message.s-1nks9gp{border:1px solid var(--divider);border-radius:6px;padding:12px;color:var(--text-secondary)}.rich-text.s-10xqaeb{overflow:hidden;white-space:pre-wrap;overflow-wrap:break-word;&:empty{display:none}}.is-large.s-10xqaeb{font-size:calc(var(--font-size) * 1);line-height:calc(var(--font-size) * 1.5)}.link.s-10xqaeb,.mention.s-10xqaeb,.hashtag.s-10xqaeb{color:var(--text-link);&:hover{text-decoration:underline}}.feed-post.s-1c3lek9{padding:0 16px}.is-leaf.s-1c3lek9{border-bottom:1px solid var(--divider)}.ascendant-line-wrapper.s-1c3lek9{display:flex;flex-direction:column;align-items:center;width:36px;.line:where(.s-1c3lek9){position:absolute;top:0;bottom:4px;flex-grow:1;border-left:2px solid var(--divider)}}.descendant-line.s-1c3lek9{flex-grow:1;margin-top:4px;border-left:2px solid var(--divider)}.contexts.s-1c3lek9{display:flex;position:relative;flex-direction:column;padding:8px 0 4px}.context.s-1c3lek9{display:flex;align-items:center;gap:12px;color:var(--text-secondary);font-size:.8125rem;line-height:1.25rem;.aside:where(.s-1c3lek9){display:flex;flex-shrink:0;justify-content:flex-end;width:36px}.main:where(.s-1c3lek9){display:flex;min-width:0px;&:hover{text-decoration-line:underline}}.name:where(.s-1c3lek9){overflow:hidden;font-weight:500;text-overflow:ellipsis;white-space:nowrap}.affix:where(.s-1c3lek9){flex-shrink:0;white-space:pre}}.content.s-1c3lek9{display:flex;gap:12px;.aside:where(.s-1c3lek9){display:flex;flex-shrink:0;flex-direction:column;align-items:center}.main:where(.s-1c3lek9){flex-grow:1;padding-bottom:12px;min-width:0}}.avatar-wrapper.s-1c3lek9{display:block;border-radius:9999px;background:var(--background-secondary);width:36px;height:36px;overflow:hidden;&:hover{filter:brightness(.85)}}.avatar.s-1c3lek9{width:100%;height:100%;object-fit:cover}.meta.s-1c3lek9{display:flex;align-items:center;margin:0 0 2px;color:var(--text-secondary);.name-wrapper:where(.s-1c3lek9){display:flex;gap:4px;max-width:100%;overflow:hidden;color:inherit;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.display-name-wrapper:where(.s-1c3lek9){overflow:hidden;text-overflow:ellipsis;.name-wrapper:where(.s-1c3lek9):hover &{text-decoration:underline}}.display-name:where(.s-1c3lek9){color:var(--text-primary);font-weight:700}.handle:where(.s-1c3lek9){display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dot:where(.s-1c3lek9){flex-shrink:0;margin:0 6px}.date:where(.s-1c3lek9){color:inherit;text-decoration:none;white-space:nowrap;&:hover{text-decoration:underline}}}.reply-context.s-1c3lek9{overflow:hidden;color:var(--text-secondary);font-size:calc(var(--font-size) * .8125);text-overflow:ellipsis;white-space:nowrap;a:where(.s-1c3lek9){color:inherit;font-weight:500;&:hover{text-decoration:underline}}}.metrics.s-1c3lek9{display:flex;align-items:center;gap:16px;margin-top:12px;color:var(--text-secondary)}.stat.s-1c3lek9{display:flex;align-items:center;gap:8px;min-width:0px;max-width:100%;.count:where(.s-1c3lek9){padding-right:8px;overflow:hidden;font-size:calc(var(--font-size) * .8125);line-height:calc(var(--font-size) * 1.25);text-overflow:ellipsis;white-space:nowrap}}.profile-feed-header.s-1xh30xs{display:flex;justify-content:space-between;align-items:center;gap:16px;container-type:inline-size;border-bottom:1px solid var(--divider);padding:12px 16px}.title.s-1xh30xs{padding:4px 0;min-width:0;overflow:hidden;font-weight:600;font-size:calc(var(--font-size) * 1);line-height:calc(var(--font-size) * 1.5);text-overflow:ellipsis;white-space:nowrap;&:hover{text-decoration:underline}}.logo.s-1xh30xs{width:24px;height:24px}.message.s-f12rvk{margin:0 auto;padding:32px 16px;max-width:380px;color:var(--text-secondary);text-align:center}.feed.s-f12rvk{max-height:var(--max-feed-height);overflow-y:auto}.end-marker.s-f12rvk{display:grid;place-items:center;height:48px;.dot:where(.s-f12rvk){border-radius:50%;background:var(--text-secondary);width:4px;height:4px}}
+1
assets/ProfileFeedDisplay-QaaAcc9o.js
+1
assets/ProfileFeedDisplay-QaaAcc9o.js
···
1
+
import{p as e,f as s,t as a,s as t,c as i,a as l,b as r,d as n,e as d,g as p,B as c,h as o,i as h,j as u,k as v,l as f,u as m,C as b}from"./index-CD_0uzJz.js";import{X as y,s as k,a as g,h as $,o as w,G as x,b as j,C as Z,e as M}from"./GuideInstructions-CTis8QB-.js";import{s as q}from"./index-Cr8Vao8y.js";const C=/[&"<]/g,A=/[&<]/g;function F(e,s){const a=String(e??""),t=s?C:A;t.lastIndex=0;let i="",l=0;for(;t.test(a);){const e=t.lastIndex-1,s=a[e];i+=a.substring(l,e)+("&"===s?"&":'"'===s?""":"<"),l=e+1}return i+a.substring(l)}function _(e,s,a=!1){if("hidden"===e&&"until-found"!==s&&(a=!0),null==s||!s&&a)return"";return` ${e}${a?"":`="${F(s,!0)}"`}`}function B(e,s,a){var t=function(e,s){var a=null==e?"":""+e;return s&&(a=a?a+" "+s:s),""===a?null:a}(e,s);return t?` class="${F(t,!0)}"`:""}function N(e,s){var a=function(e){return null==e?null:String(e)}(e);return a?` style="${F(a,!0)}"`:""}const z="!no-unauthenticated";function U(e,s){const{children:a}=s;e.push('<div class="bluesky-embed s-1pz15a1">'),a(e),e.push("</div>")}const P=e=>`https://bsky.app/profile/${e}`,I=(e,s)=>`https://bsky.app/profile/${e}/post/${s}`,R=e=>`https://bsky.app/hashtag/${e}`,S=(e,s)=>`https://bsky.app/profile/${e}/feed/${s}`;let T=0,H=0;const V=new Intl.DateTimeFormat("en-US",{dateStyle:"long",timeStyle:"short"}),L=new Intl.DateTimeFormat("en-US",{dateStyle:"medium"}),D=new Intl.DateTimeFormat("en-US",{month:"short",day:"numeric"}),G=e=>{const s=new Date(e),a=s.getTime();if(isNaN(a))return"N/A";const t=Date.now();if(t>H){const e=new Date(t);e.setMonth(0,1),e.setHours(0,0,0),T=e.getTime(),e.setFullYear(e.getFullYear()+1,0,0),e.setHours(23,59,59,999),H=e.getTime()}return a>=T&&a<=H?D.format(s):L.format(s)},W=/^at:\/\/((?:did:[a-zA-Z0-9._:%-]+)|(?:[a-zA-Z0-9][a-zA-Z0-9-.]*))(?:\/([a-zA-Z0-9.-]+)(?:\/([a-zA-Z0-9_~.:-]{1,512}))?)?\/?(?:\?([^#\s]*))?(?:#([^\s]*))?$/,Y=e=>{const s=W.exec(e);if(!s)throw new E(`invalid at-uri: ${e}`);return{repo:s[1],collection:s[2]??"",rkey:s[3]??"",query:s[4]??"",fragment:s[5]??""}};class E extends Error{}const X=new Intl.NumberFormat("en-US"),J=new Intl.NumberFormat("en-US",{notation:"compact"}),K=e=>e<1e3?""+e:e<1e5?X.format(e):J.format(e),O=e=>X.format(e),Q={"!hide":{name:"Hidden by moderators",flags:1},"!warn":{name:"Content warning",flags:1},porn:{name:"Adult content",flags:0},sexual:{name:"Sexually suggestive",flags:0},"graphic-media":{name:"Graphic media",flags:0},nudity:{name:"Nudity",flags:0}},ee=(e,s)=>{if(e?.length)for(let a=0,t=e.length;a<t;a++){const t=e[a],i=t.val;if(!(i in Q))continue;const l=Q[i];if(!(1&l.flags&&t.src===s))return l}};function se(e,s){{const{embed:a}=s,t=a.external,i=(e=>{let s;if("parse"in URL)s=URL.parse(e);else try{s=new URL(e)}catch{}return!s||"https:"!==s.protocol&&"http:"!==s.protocol?null:s})(t.uri)?.host;e.push(`<a target="_blank"${_("href",i&&t.uri)} rel="noopener noreferrer nofollow" class="external-embed s-au8a8u">`),t.thumb&&e.push(`<img loading="lazy"${_("src",t.thumb)} alt="" class="thumbnail s-au8a8u"/>`),e.push(` <div class="meta s-au8a8u"><p class="title s-au8a8u">${F(t.title)}</p> <p class="description s-au8a8u">${F(t.description)}</p> `),i&&e.push(`<div class="domain s-au8a8u"><svg class="icon" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-width="2" d="m4.172 8.07 3.94 2.957.977-1.941 3.887-.978 1.15-4.6M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-6.078 4.865.973-1.946-2.869-1.928-1.89-.12-1.08 1.075 1.947 2.919h2.919Z"></path></svg> <span class="domain-name">${F(i)}</span></div>`),e.push("</div></a>")}}const ae={width:16,height:9};function te(e,s){{const{embed:a,borderless:t,standalone:i,blur:l}=s,r=a.images,n=r.length;function d(e,s){const a=r[s];e.push(`<img loading="lazy"${_("src",a.thumb)}${_("alt",a.alt)}${B("image"+(l?" is-blurred":""),"s-1d339cy")}/>`)}if(e.push(`<div${B("image-embed"+(t?"":" is-bordered")+(i&&1===n?" is-aligned":""),"s-1d339cy")}>`),4===n)e.push('<div class="grid s-1d339cy"><div class="col s-1d339cy"><div class="item wide tl s-1d339cy">'),d(e,0),e.push('</div> <div class="item wide bl s-1d339cy">'),d(e,2),e.push('</div></div> <div class="col s-1d339cy"><div class="item wide tr s-1d339cy">'),d(e,1),e.push('</div> <div class="item wide br s-1d339cy">'),d(e,3),e.push("</div></div></div>");else if(3===n)e.push('<div class="grid s-1d339cy"><div class="col square s-1d339cy"><div class="item tl bl s-1d339cy">'),d(e,0),e.push('</div></div> <div class="col square s-1d339cy"><div class="item tr s-1d339cy">'),d(e,1),e.push('</div> <div class="item br s-1d339cy">'),d(e,2),e.push("</div></div></div>");else if(2===n)e.push('<div class="grid s-1d339cy"><div class="col s-1d339cy"><div class="item square tl bl s-1d339cy">'),d(e,0),e.push('</div></div> <div class="col s-1d339cy"><div class="item square tr br s-1d339cy">'),d(e,1),e.push("</div></div></div>");else if(1===n){const p=i&&(r[0].aspectRatio||ae);e.push(`<div${B("single-item tl tr bl br"+(p?" is-standalone":""),"s-1d339cy")}${N(p?`aspect-ratio: ${p.width}/${p.height}`:"")}>`),d(e,0),e.push(" "),p&&e.push('<div class="placeholder s-1d339cy"></div>'),e.push("</div>")}e.push("</div>")}}function ie(e,s){{const{post:a,embed:t,borderless:i,standalone:l,blur:r}=s,n=l&&t.aspectRatio,d=a&&I(a.author.did,Y(a.uri).rkey);function p(e){e.push(`<img loading="lazy"${_("src",t.thumbnail)} alt=""${B("thumbnail"+(r?" is-blurred":""),"s-1h3cnsw")}/> `),n&&e.push('<div class="placeholder s-1h3cnsw"></div>'),e.push(' <div class="play s-1h3cnsw"><svg class="icon s-1h3cnsw" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M22 12 5 2v20l17-10Z"></path></svg></div>')}l?(e.push(`<a target="_blank"${_("href",d)}${B("video-embed"+(i?"":" is-bordered")+(l?" is-standalone":""),"s-1h3cnsw")}><div class="constrainer s-1h3cnsw"${N(n?`aspect-ratio: ${n.width}/${n.height}`:"")}>`),p(e),e.push("</div></a>")):(e.push(`<div${B("video-embed"+(i?"":" is-bordered"),"s-1h3cnsw")}${N(n?`aspect-ratio: ${n.width}/${n.height}`:"")}>`),p(e),e.push("</div>"))}}const le=e=>{if(e){if("app.bsky.embed.images#view"===e.$type)return e;if("app.bsky.embed.recordWithMedia#view"===e.$type)return le(e.media)}},re=e=>{if(e){if("app.bsky.embed.video#view"===e.$type)return e;if("app.bsky.embed.recordWithMedia#view"===e.$type)return re(e.media)}};function ne(e,s){e.push(`<div class="message s-1nks9gp">${F(s)}</div>`)}function de(e,s){{const{post:a,embed:t,large:i=!1}=s;function l(e,s){!function(e,s){{const{warning:a,children:t}=s;a?(e.push(`<details class="content-hider s-1se5tqk"><summary class="gate s-1se5tqk"><svg class="icon s-1se5tqk" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="square" stroke-width="2" d="M11 11h1v5m9-4a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"></path><path fill="currentColor" stroke="currentColor" stroke-width=".5" d="M11.5 7.25h-.25v1.5h1.5v-1.5H11.5Z"></path></svg> <span class="label s-1se5tqk">${F(a.name)}</span> <span class="action s-1se5tqk"></span></summary> `),t(e),e.push("</details>")):t(e)}}(e,{warning:a&&ee(a.labels,a.author.did),children:e=>{"app.bsky.embed.external#view"===s.$type?se(e,{embed:s}):"app.bsky.embed.images#view"===s.$type?te(e,{embed:s,standalone:!0}):"app.bsky.embed.video#view"===s.$type?ie(e,{post:a,embed:s,standalone:!0}):ne(e,"Unsupported media embed")}})}function r(e,s){const a=s.record;if("app.bsky.embed.record#viewRecord"===a.$type)!function(e,s){{const{embed:a,large:t=!1}=s,i=a.value,l=i.text.trim(),r=a.author,n=r.displayName?.trim(),d=a.embeds?.[0],p=le(d),c=re(d),o=I(r.did,Y(a.uri).rkey),h=!!ee(a.labels,r.did);e.push(`<a target="_blank"${_("href",o)} class="quote-embed s-vbjlyj"><div class="meta s-vbjlyj"><div class="avatar-wrapper s-vbjlyj">`),r.avatar&&e.push(`<img loading="lazy"${_("src",r.avatar)} alt="" class="avatar s-vbjlyj"/>`),e.push('</div> <span class="name-wrapper s-vbjlyj">'),n&&e.push(`<bdi class="display-name-wrapper s-vbjlyj"><span class="display-name s-vbjlyj">${F(n)}</span></bdi>`),e.push(` <span class="handle s-vbjlyj">@${F(r.handle)}</span></span> <span aria-hidden="true" class="dot s-vbjlyj">ยท</span> <time${_("datetime",i.createdAt)} class="date s-vbjlyj">${F(G(i.createdAt))}</time></div> `),l?(e.push('<div class="body s-vbjlyj">'),t||(p?(e.push('<div class="aside s-vbjlyj">'),te(e,{embed:p,blur:h}),e.push("</div>")):c&&(e.push('<div class="aside s-vbjlyj">'),ie(e,{embed:c,blur:h}),e.push("</div>"))),e.push(` <p class="text s-vbjlyj">${F(l)}</p></div>`)):e.push('<div class="divide s-vbjlyj"></div>'),e.push(" "),!t&&l||(p?te(e,{embed:p,borderless:!0,blur:h}):c&&ie(e,{embed:c,borderless:!0,blur:h})),e.push("</a>")}}(e,{embed:a,large:i});else if("app.bsky.feed.defs#generatorView"===a.$type)!function(e,s){{const{embed:a}=s,t=a.creator,i=S(t.did,Y(a.uri).rkey);e.push(`<a target="_blank"${_("href",i)} class="feed-embed s-1c1phtf"><div class="main s-1c1phtf"><div class="avatar-wrapper s-1c1phtf">`),a.avatar?e.push(`<img loading="lazy"${_("src",a.avatar)} alt="" class="avatar s-1c1phtf"/>`):e.push('<svg viewBox="0 0 32 32" class="avatar s-1c1phtf"><path fill="#0070FF" d="M0 0h32v32H0z"></path><path fill="#fff" d="M22.153 22.354a9.328 9.328 0 0 0 3.837-.491 3.076 3.076 0 0 0-4.802-2.79m.965 3.281a6.128 6.128 0 0 0-.965-3.28Zm-11.342-3.28a3.077 3.077 0 0 0-4.801 2.79 9.21 9.21 0 0 0 3.835.49m.966-3.28a6.127 6.127 0 0 0-.966 3.28Zm8.265-8.997a3.076 3.076 0 1 1-6.153 0 3.076 3.076 0 0 1 6.153 0Zm6.154 3.077a2.307 2.307 0 1 1-4.615 0 2.307 2.307 0 0 1 4.615 0Zm-13.847 0a2.307 2.307 0 1 1-4.614 0 2.307 2.307 0 0 1 4.614 0Z"></path><path fill="#fff" d="M22 22c0 3.314-2.686 3.5-6 3.5s-6-.186-6-3.5a6 6 0 0 1 12 0Z"></path></svg>'),e.push(`</div> <div class="info"><p class="name s-1c1phtf">${F(a.displayName)}</p> <p class="creator s-1c1phtf">Feed by @${F(t.handle)}</p></div></div> <p class="description s-1c1phtf">${F(a.description)}</p></a>`)}}(e,{embed:a});else if("app.bsky.graph.defs#listView"===a.$type)!function(e,s){{const{embed:a}=s,t=a.creator,i=S(t.did,Y(a.uri).rkey);e.push(`<a target="_blank"${_("href",i)} class="list-embed s-1mo1e33"><div class="main s-1mo1e33"><div class="avatar-wrapper s-1mo1e33">`),a.avatar?e.push(`<img loading="lazy"${_("src",a.avatar)} alt="" class="avatar s-1mo1e33"/>`):e.push('<svg viewBox="0 0 32 32" class="avatar s-1mo1e33"><path fill="#0070FF" d="M0 0h32v32H0z"></path><path fill="#fff" d="M22.153 22.354a9.328 9.328 0 0 0 3.837-.491 3.076 3.076 0 0 0-4.802-2.79m.965 3.281a6.128 6.128 0 0 0-.965-3.28Zm-11.342-3.28a3.077 3.077 0 0 0-4.801 2.79 9.21 9.21 0 0 0 3.835.49m.966-3.28a6.127 6.127 0 0 0-.966 3.28Zm8.265-8.997a3.076 3.076 0 1 1-6.153 0 3.076 3.076 0 0 1 6.153 0Zm6.154 3.077a2.307 2.307 0 1 1-4.615 0 2.307 2.307 0 0 1 4.615 0Zm-13.847 0a2.307 2.307 0 1 1-4.614 0 2.307 2.307 0 0 1 4.614 0Z"></path><path fill="#fff" d="M22 22c0 3.314-2.686 3.5-6 3.5s-6-.186-6-3.5a6 6 0 0 1 12 0Z"></path></svg>'),e.push(`</div> <div class="info"><p class="name s-1mo1e33">${F(a.name)}</p> <p class="creator s-1mo1e33">${F((e=>{switch(e){case"app.bsky.graph.defs#curatelist":return"User list";case"app.bsky.graph.defs#modlist":return"Moderation list"}return"Unknown list"})(a.purpose))} by @${F(t.handle)}</p></div></div> <p class="description s-1mo1e33">${F(a.description)}</p></a>`)}}(e,{embed:a});else if("app.bsky.graph.defs#starterPackViewBasic"===a.$type)!function(e,s){{const{embed:a,large:t=!1}=s,i=a.record,l=a.creator,r=l.did,n=Y(a.uri).rkey,d=((e,s)=>`https://bsky.app/starter-pack/${e}/${s}`)(r,n);if(e.push(`<a target="_blank"${_("href",d)} class="starterpack-embed s-whpa2l">`),t){const s=((e,s)=>`https://ogcard.cdn.bsky.app/start/${e}/${s}`)(r,n);e.push(`<img loading="lazy"${_("src",s)} alt="" class="banner s-whpa2l"/>`)}e.push(` <div class="meta s-whpa2l"><div class="main s-whpa2l"><svg fill="none" viewBox="0 0 24 24" class="avatar s-whpa2l"><defs><linearGradient id="a" x1="0" x2="100%" y1="0" y2="0" gradientTransform="rotate(45)"><stop offset="0" stop-color="#0A7AFF"></stop><stop offset="1" stop-color="#59B9FF"></stop></linearGradient></defs><path fill="url(#a)" fill-rule="evenodd" d="M11.26 5.227 5.02 6.899c-.734.197-1.17.95-.973 1.685l1.672 6.24c.197.734.951 1.17 1.685.973l6.24-1.672a1.376 1.376 0 0 0 .973-1.685L12.945 6.2a1.375 1.375 0 0 0-1.685-.973Zm-6.566.459a2.632 2.632 0 0 0-1.86 3.223l1.672 6.24a2.632 2.632 0 0 0 3.223 1.861l6.24-1.672a2.631 2.631 0 0 0 1.861-3.223l-1.672-6.24a2.632 2.632 0 0 0-3.223-1.861l-6.24 1.672Z" clip-rule="evenodd"></path><path fill="url(#a)" fill-rule="evenodd" d="M15.138 18.411a4.606 4.606 0 1 0 0-9.211 4.606 4.606 0 0 0 0 9.211Zm0 1.257a5.862 5.862 0 1 0 0-11.724 5.862 5.862 0 0 0 0 11.724Z" clip-rule="evenodd"></path></svg> <div class="info"><p class="name s-whpa2l">${F(i.name)}</p> <p class="creator s-whpa2l">Starter pack by @${F(l.handle)}</p></div></div> <p class="description s-whpa2l">${F(i.description)}</p></div></a>`)}}(e,{embed:a,large:i});else{const s=(e=>{switch(e){case"app.bsky.feed.post":return"post";case"app.bsky.feed.generator":return"feed";case"app.bsky.graph.list":return"list";case"app.bsky.graph.starterpack":return"starter pack";case"app.bsky.labeler.service":return"labeler"}return null})(Y(a.uri).collection);ne(e,s&&("app.bsky.embed.record#viewNotFound"===a.$type||"app.bsky.embed.record#viewBlocked"===a.$type||"app.bsky.embed.record#viewDetached"===a.$type)?`This ${s} is unavailable`:"Unsupported record embed")}}e.push('<div class="embeds s-1nks9gp">'),"app.bsky.embed.recordWithMedia#view"===t.$type?(l(e,t.media),e.push(" "),r(e,t.record)):"app.bsky.embed.record#view"===t.$type?r(e,t):l(e,t),e.push("</div>")}}const pe=e=>e?.find(e=>"app.bsky.richtext.facet#link"===e.$type||"app.bsky.richtext.facet#mention"===e.$type||"app.bsky.richtext.facet#tag"===e.$type);function ce(e,s){{const{item:a,prev:t=!1,next:i=!1}=s,l=a.reason,r=a.post,n=a.reply?.parent,d=r.author,p=P(d.did),c=d.displayName?.trim(),o=r.record,h=I(d.did,Y(r.uri).rkey),u=r.replyCount||0,v=r.likeCount||0,f=(r.repostCount||0)+(r.quoteCount||0);if(e.push(`<div${B("feed-post"+(i?"":" is-leaf"),"s-1c3lek9")}><div class="contexts s-1c3lek9">`),t&&e.push('<div class="ascendant-line-wrapper s-1c3lek9"><div class="line s-1c3lek9"></div></div>'),e.push(" "),l)if("app.bsky.feed.defs#reasonRepost"===l.$type){const s=l.by;e.push(`<div class="context s-1c3lek9"><div class="aside s-1c3lek9"><svg class="icon" viewBox="0 0 24 24" fill="none"><path d="M17 3L20 6L17 9M7 21L4 18L7 15M5 18H20V13M4 11V6H19" stroke="currentColor" stroke-width="2" stroke-linecap="square"></path></svg></div> <a${_("href",P(s.did))} class="main s-1c3lek9"><span dir="auto" class="name s-1c3lek9">${F(s.displayName)}</span> <span class="affix s-1c3lek9"> reposted</span></a></div>`)}else"app.bsky.feed.defs#reasonPin"===l.$type&&e.push('<div class="context s-1c3lek9"><div class="aside s-1c3lek9"><svg class="icon" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="square" stroke-width="2" d="M12 15H5v-2.5l.377-.377A7.25 7.25 0 0 0 7.5 6.997V3h9v3.997a7.25 7.25 0 0 0 2.123 5.127L19 12.5V15h-7Zm0 0v6"></path></svg></div> <span class="main s-1c3lek9">Pinned</span></div>');if(e.push(`</div> <div class="content s-1c3lek9"><div class="aside s-1c3lek9"><a target="_blank"${_("href",p)} class="avatar-wrapper s-1c3lek9">`),d.avatar&&e.push(`<img loading="lazy"${_("src",d.avatar)} alt="" class="avatar s-1c3lek9"/>`),e.push("</a> "),i&&e.push('<div class="descendant-line s-1c3lek9"></div>'),e.push(`</div> <div class="main s-1c3lek9"><div class="meta s-1c3lek9"><a${_("href",p)} target="_blank" class="name-wrapper s-1c3lek9">`),c&&e.push(`<bdi class="display-name-wrapper s-1c3lek9"><span class="display-name s-1c3lek9">${F(c)}</span></bdi>`),e.push(` <span class="handle s-1c3lek9">@${F(d.handle)}</span></a> <span aria-hidden="true" class="dot s-1c3lek9">ยท</span> <a target="_blank"${_("href",h)}${_("title",(e=>{const s=new Date(e);return isNaN(s.getTime())?"N/A":V.format(s)})(o.createdAt))} class="date s-1c3lek9"><time${_("datetime",o.createdAt)}>${F(G(o.createdAt))}</time></a></div> `),!t&&o.reply){if(e.push('<p class="reply-context s-1c3lek9">'),n&&"app.bsky.feed.defs#postView"===n.$type){const s=n.author;e.push(`Replying to <a target="_blank"${_("href",P(s.did))} dir="auto" class="s-1c3lek9">${F(s.displayName?.trim()||`@${s.handle}`)}</a>`)}else e.push("Replying to an unknown post");e.push("</p>")}e.push(" "),function(e,s){{const{text:a,facets:t,large:i}=s;e.push(`<p${B("rich-text"+(i?" is-large":" is-small"),"s-10xqaeb")}>`);const l=q(a,t);for(let s=0,r=l.length;s<r;s++){let a=l[s];const t=pe(a.features);t?"app.bsky.richtext.facet#link"===t.$type?e.push(`<a target="_blank"${_("href",t.uri)} rel="noopener nofollow" class="link s-10xqaeb">${F(a.text)}</a>`):"app.bsky.richtext.facet#mention"===t.$type?e.push(`<a target="_blank"${_("href",P(t.did))} class="mention s-10xqaeb">${F(a.text)}</a>`):"app.bsky.richtext.facet#tag"===t.$type&&e.push(`<a target="_blank"${_("href",R(t.tag))} class="hashtag s-10xqaeb">${F(a.text)}</a>`):e.push(`${F(a.text)}`)}e.push("</p>")}}(e,{text:o.text,facets:o.facets}),e.push(" "),r.embed&&de(e,{post:r,embed:r.embed}),e.push(` <div class="metrics s-1c3lek9"><div${_("title",1===u?`${O(u)} reply`:`${O(u)} replies`)} class="stat s-1c3lek9"><svg class="icon" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="square" stroke-width="2" d="M3.002 4h18v14h-9l-5 3v-3h-4V4Z"></path></svg> <span class="count s-1c3lek9">${F(K(u))}</span></div> <div${_("title",1===f?`${O(f)} repost`:`${O(f)} reposts`)} class="stat s-1c3lek9"><svg class="icon" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="square" stroke-width="2" d="m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15"></path></svg> <span class="count s-1c3lek9">${F(K(f))}</span></div> <div${_("title",1===v?`${O(v)} like`:`${O(v)} likes`)} class="stat s-1c3lek9"><svg class="icon" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-width="2" d="M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z"></path></svg> <span class="count s-1c3lek9">${F(K(v))}</span></div></div></div></div></div>`)}}function oe(e,s){U(e,{children:e=>{e.push(`<div class="message s-f12rvk">${F(s)}</div>`)}})}function he(e,s){{const{profile:a,feed:t,allowUnauthenticated:i}=s,l=!i&&a?.labels?.some(e=>e.val===z),r=t.filter(e=>{if(!a)return!1;const s=e.reason;if(s){if("app.bsky.feed.defs#reasonPin"===s.$type)return!0;if("app.bsky.feed.defs#reasonRepost"===s.$type){const s=e.post.author;return s.did===a.did||(i||!s.labels?.some(e=>e.val===z))}return!1}return!e.reply});null===a?oe(e,"The profile can't be found, it may have been deleted."):l?oe(e,"The user has requested for their posts to not be displayed on external sites."):U(e,{children:e=>{if(function(e,s){{const{profile:a}=s;e.push(`<div class="profile-feed-header s-1xh30xs"><a target="_blank"${_("href",P(a.did))} class="title s-1xh30xs">Posts from @${F(a.handle)}</a> <svg class="logo s-1xh30xs" fill="none" viewBox="0 0 320 286"><path fill="#0A7AFF" d="M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z"></path></svg></div>`)}}(e,{profile:a}),e.push(" "),r.length>0){e.push('<div class="feed s-f12rvk">');const s=r;for(let a=0,t=s.length;a<t;a++){ce(e,{item:s[a]})}e.push(' <div class="end-marker s-f12rvk"><div class="dot s-f12rvk"></div></div></div>')}else e.push('<div class="message s-f12rvk">This user has not made any posts.</div>')}})}}var ue=s("<bluesky-profile-feed><!></bluesky-profile-feed>",2);function ve(s,n){e(n,!0);var d=ue();a(()=>t(d,"actor",n.data.profile?.did));var p=i(d);$(p,()=>function(e,s={}){let a="";return he({push(e){a+=e}},s.props??{}),{body:a}}(0,{props:n.data}).body),l(s,d),r()}var fe=s("<li><p>Insert the following scripts and stylesheets to the <code><head></code> of your website.</p> <!></li> <li><p>Insert the following markup in wherever you want the profile feed to be.</p> <!></li>",1),me=s("<!> <!>",1);function be(s,t){let $;e(t,!0);const q=m(()=>{$?.abort(),$=new AbortController;const e=$.signal;return(async e=>{const s=e.actor,a=e.allowUnauthenticated??!1,t=new y({handler:k({service:e.serviceUri??"https://public.api.bsky.app"})}),[{data:i},{data:l}]=await Promise.all([t.get("app.bsky.actor.getProfile",{signal:e.signal,params:{actor:s}}).catch(e=>e instanceof g&&"InvalidRequest"===e.kind&&"Profile not found"===e.description?{data:null}:Promise.reject(e)),t.get("app.bsky.feed.getAuthorFeed",{signal:e.signal,params:{actor:s,filter:"posts_no_replies",includePins:e.includePins,limit:30}}).catch(e=>e instanceof g&&"InvalidRequest"===e.kind&&"Profile not found"===e.description?{data:{feed:[]}}:Promise.reject(e))]);return{profile:i,feed:l.feed,allowUnauthenticated:a}})({actor:t.matched.actor,signal:e})});w(()=>{$?.abort()});const C=()=>{const e="https://cdn.jsdelivr.net/npm/bluesky-profile-feed-embed@^1.0.0";return`\x3c!-- Core web component and styling --\x3e\n<script type="module" src="${e}/+esm"><\/script>\n<link rel="stylesheet" href="${e}/dist/core.min.css">\n\n\x3c!-- Built-in themes --\x3e\n<link rel="stylesheet" href="${e}/themes/light.min.css" media="(prefers-color-scheme: light)">\n<link rel="stylesheet" href="${e}/themes/dim.min.css" media="(prefers-color-scheme: dark)">\n`};var A=n(),F=d(A);p(F,()=>u(q),e=>{b(e)},(e,s)=>{var a=me(),t=d(a);ve(t,{get data(){return u(s)}});var r=v(t,2),n=e=>{x(e,{title:"How do I embed this to my website?",children:(e,a)=>{j(e,{children:(e,a)=>{var t=fe(),r=d(t),n=v(i(r),2);{let e=m(C);Z(n,{get code(){return u(e)}})}var p=v(r,2),c=v(i(p),2);{let e=m(()=>(e=>{const s=`https://bsky.app/profile/${e.did}`;return`<bluesky-profile-feed actor="${M(e.did)}" include-pins>\n <a target="_blank" href="${M(s)}" class="bluesky-profile-feed-fallback">\n ${e.displayName?.trim()?`Posts by ${M(e.displayName)} (@${M(e.handle)})`:`Posts by @${M(e.handle)}`}\n </a>\n</bluesky-profile-feed>\n`})(u(s).profile));Z(c,{get code(){return u(e)}})}l(e,t)}})}})};f(r,e=>{u(s).profile&&e(n)}),l(e,a)},(e,s)=>{c(e,{type:"alert",children:(e,t)=>{var i=o();a(()=>h(i,""+u(s))),l(e,i)}})}),l(s,A),r()}export{be as default};
+1
assets/index-B_9yoyg2.css
+1
assets/index-B_9yoyg2.css
···
1
+
*,:before,:after{box-sizing:border-box}html{line-height:1.15;font-family:Inter,Roboto,ui-sans-serif,sans-serif,"Noto Color Emoji",Twemoji Mozilla;-webkit-text-size-adjust:100%;tab-size:4}body{margin:0}b,strong{font-weight:bolder}code,kbd,samp,pre{font-size:1em;font-family:JetBrains Mono NL,ui-monospace,monospace}small{font-size:80%}sub,sup{position:relative;vertical-align:baseline;font-size:75%;line-height:0}sub{bottom:-.25em}sup{top:-.5em}table{border-color:currentcolor}button,input,optgroup,select,textarea{margin:0;font-size:100%;line-height:1.15;font-family:inherit}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}.bluesky-embed{--font-size: 16px;--font-family: system-ui, "Segoe UI", "Roboto", "Helvetica", "Arial", sans-serif, "Apple Color Emoji", "Segoe UI Emoji";--max-feed-height: 600px}.bluesky-embed{--text-primary: #000000;--text-secondary: #455668;--text-link: #1083fe;--background-primary: #ffffff;--background-secondary: #455668;--divider-hover: #a9b7c5;--divider: #d4dbe2;--button: #1083fe;--button-text: #ffffff;--button-hover: #0168d5}.banner.svelte-4gizvm{border:1px solid;border-radius:4px;padding:10px 12px;font-weight:500;font-size:.875rem;line-height:1.25rem;a{color:inherit;font-weight:600}}.type-alert.svelte-4gizvm{border-color:#fca5a5;background:#fee2e2;color:#991b1b}.type-inform.svelte-4gizvm{border-color:#bfdbfe;background:#dbeafe;color:#1e40af}.circular-spinner.svelte-rq8vha{display:block;animation:svelte-rq8vha-spin 1s linear infinite;margin:0 auto;width:24px;height:24px}@keyframes svelte-rq8vha-spin{to{transform:rotate(360deg)}}.accented.svelte-rq8vha{stroke:#2563eb}.background.svelte-rq8vha{stroke:#2563eb;opacity:20%}.field.svelte-1wzaqos{display:flex;flex-direction:column;gap:8px}.input-wrapper.svelte-1wzaqos{display:contents}.label.svelte-1wzaqos{color:#4b5563;font-weight:600;font-size:.875rem;line-height:1.25rem}.text-input.svelte-1e5va0l{outline:2px none #2563eb;outline-offset:-1px;border:1px solid #9ca3af;border-radius:4px;padding:8px 12px;font-size:.875rem;line-height:1.25rem;&::placeholder{color:#9ca3af}&:focus{outline-style:solid}}.app.svelte-1n46o8q{margin:0 auto;padding:36px 16px;width:100%;max-width:582px}.header.svelte-1n46o8q{margin:24px 0}.main.svelte-1n46o8q{margin:36px 0}.choices.svelte-1n46o8q{display:flex;flex-direction:column;gap:8px;margin:16px 0 36px;border:0;padding:0}.choice.svelte-1n46o8q{display:flex;align-items:center;gap:8px;font-size:.875rem;line-height:1.25rem;input:where(.svelte-1n46o8q){appearance:none;outline:2px none #2563eb;outline-offset:2px;border:1px solid #9ca3af;border-radius:8px;width:16px;height:16px;&:checked{border:0;background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");background-color:#2563eb}&:focus{outline-style:solid}}}.footer.svelte-1n46o8q{display:flex;flex-wrap:wrap;gap:.5rem;margin:36px 0 0;border-top:1px solid #d1d5db;padding:36px 0 0;color:#4b5563;font-size:.875rem;line-height:1.25rem;a:where(.svelte-1n46o8q){color:#2563eb}}
+2
assets/index-CD_0uzJz.js
+2
assets/index-CD_0uzJz.js
···
1
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./PostDisplay-CqTUAVla.js","./GuideInstructions-CTis8QB-.js","./GuideInstructions-B8N7RzmZ.css","./index-Cr8Vao8y.js","./PostDisplay-yMSDBkol.css","./ProfileCardDisplay-BpCMWdM3.js","./ProfileCardDisplay-D4FwjqsR.css","./ProfileFeedDisplay-QaaAcc9o.js","./ProfileFeedDisplay-DOw9fkTH.css"])))=>i.map(i=>d[i]);
2
+
!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))t(e);new MutationObserver(e=>{for(const n of e)if("childList"===n.type)for(const e of n.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&t(e)}).observe(document,{childList:!0,subtree:!0})}function t(e){if(e.ep)return;e.ep=!0;const t=function(e){const t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?t.credentials="include":"anonymous"===e.crossOrigin?t.credentials="omit":t.credentials="same-origin",t}(e);fetch(e.href,t)}}();const e=!1;var t=Array.isArray,n=Array.prototype.indexOf,r=Array.from,i=Object.defineProperty,l=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyDescriptors,o=Object.prototype,a=Array.prototype,f=Object.getPrototypeOf,c=Object.isExtensible;const u=()=>{};function d(){var e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}const h=16,v=32,p=64,_=128,g=512,m=1024,y=2048,b=4096,w=8192,k=16384,x=32768,E=65536,P=1<<17,S=1<<18,A=1<<19,q=32768,j=1<<21,O=1<<23,L=Symbol("$state"),z=Symbol("legacy props"),N=Symbol(""),$=new class extends Error{name="StaleReactionError";message="The reaction that called `getAbortSignal()` was re-run or destroyed"};const M=Symbol(),D="http://www.w3.org/1999/xhtml";function R(e){return e===this.v}let C=null;function T(e){C=e}function I(e,t=!1,n){C={p:C,i:!1,c:null,e:null,s:e,x:null,l:null}}function U(e){var t=C,n=t.e;if(null!==n)for(var r of(t.e=null,n))Ge(r);return t.i=!0,C=t.p,{}}let Z=[];function B(){var e=Z;Z=[],function(e){for(var t=0;t<e.length;t++)e[t]()}(e)}function V(e){if(0===Z.length&&!te){var t=Z;queueMicrotask(()=>{t===Z&&B()})}Z.push(e)}function W(){for(;Z.length>0;)B()}function F(e){var t=gt;if(null===t)return vt.f|=O,e;if(0===(t.f&x)){if(0===(t.f&_))throw e;t.b.error(e)}else K(e,t)}function K(e,t){for(;null!==t;){if(0!==(t.f&_))try{return void t.b.error(e)}catch(n){e=n}t=t.parent}throw e}const H=new Set;let G=null,J=null,Q=null,X=[],Y=null,ee=!1,te=!1;class ne{committed=!1;current=new Map;previous=new Map;#e=new Set;#t=new Set;#n=0;#r=0;#i=null;#l=[];#s=[];skipped_effects=new Set;is_fork=!1;is_deferred(){return this.is_fork||this.#r>0}process(e){X=[],J=null,this.apply();var t={parent:null,effect:null,effects:[],render_effects:[],block_effects:[]};for(const n of e)this.#o(n,t);this.is_fork||this.#a(),this.is_deferred()?(this.#f(t.effects),this.#f(t.render_effects),this.#f(t.block_effects)):(J=this,G=null,oe(t.render_effects),oe(t.effects),J=null,this.#i?.resolve()),Q=null}#o(e,t){e.f^=m;for(var n=e.first;null!==n;){var r=n.f,i=!!(96&r),l=i&&0!==(r&m)||0!==(r&w)||this.skipped_effects.has(n);if(0!==(n.f&_)&&n.b?.is_pending()&&(t={parent:t,effect:n,effects:[],render_effects:[],block_effects:[]}),!l&&null!==n.fn){i?n.f^=m:4&r?t.effects.push(n):jt(n)&&(0!==(n.f&h)&&t.block_effects.push(n),$t(n));var s=n.first;if(null!==s){n=s;continue}}var o=n.parent;for(n=n.next;null===n&&null!==o;)o===t.effect&&(this.#f(t.effects),this.#f(t.render_effects),this.#f(t.block_effects),t=t.parent),n=o.next,o=o.parent}}#f(e){for(const t of e){(0!==(t.f&y)?this.#l:this.#s).push(t),this.#c(t.deps),It(t,m)}}#c(e){if(null!==e)for(const t of e)2&t.f&&0!==(t.f&q)&&(t.f^=q,this.#c(t.deps))}capture(e,t){this.previous.has(e)||this.previous.set(e,t),0===(e.f&O)&&(this.current.set(e,e.v),Q?.set(e,e.v))}activate(){G=this,this.apply()}deactivate(){G===this&&(G=null,Q=null)}flush(){if(this.activate(),X.length>0){if(ie(),null!==G&&G!==this)return}else 0===this.#n&&this.process([]);this.deactivate()}discard(){for(const e of this.#t)e(this);this.#t.clear()}#a(){if(0===this.#r){for(const e of this.#e)e();this.#e.clear()}0===this.#n&&this.#u()}#u(){if(H.size>1){this.previous.clear();var e=Q,t=!0,n={parent:null,effect:null,effects:[],render_effects:[],block_effects:[]};for(const e of H){if(e===this){t=!1;continue}const i=[];for(const[n,r]of this.current){if(e.current.has(n)){if(!t||r===e.current.get(n))continue;e.current.set(n,r)}i.push(n)}if(0===i.length)continue;const l=[...e.current.keys()].filter(e=>!this.current.has(e));if(l.length>0){var r=X;X=[];const t=new Set,s=new Map;for(const e of i)ae(e,l,t,s);if(X.length>0){G=e,e.apply();for(const t of X)e.#o(t,n);e.deactivate()}X=r}}G=null,Q=e}this.committed=!0,H.delete(this)}increment(e){this.#n+=1,e&&(this.#r+=1)}decrement(e){this.#n-=1,e&&(this.#r-=1),this.revive()}revive(){for(const e of this.#l)It(e,y),ce(e);for(const e of this.#s)It(e,b),ce(e);this.#l=[],this.#s=[],this.flush()}oncommit(e){this.#e.add(e)}ondiscard(e){this.#t.add(e)}settled(){return(this.#i??=d()).promise}static ensure(){if(null===G){const e=G=new ne;H.add(G),te||ne.enqueue(()=>{G===e&&e.flush()})}return G}static enqueue(e){V(e)}apply(){}}function re(e){var t=te;te=!0;try{for(;;){if(W(),0===X.length&&(G?.flush(),0===X.length))return void(Y=null);ie()}}finally{te=t}}function ie(){var t=ct;ee=!0;try{var n=0;for(ut(!0);X.length>0;){var r=ne.ensure();if(n++>1e3)e,le();r.process(X),we.clear()}}finally{ee=!1,ut(t),Y=null}}function le(){try{!function(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}()}catch(e){K(e,Y)}}let se=null;function oe(e){var t=e.length;if(0!==t){for(var n=0;n<t;){var r=e[n++];if(!(24576&r.f)&&jt(r)&&(se=new Set,$t(r),null===r.deps&&null===r.first&&null===r.nodes&&(null===r.teardown&&null===r.ac?it(r):r.fn=null),se?.size>0)){we.clear();for(const e of se){if(24576&e.f)continue;const t=[e];let n=e.parent;for(;null!==n;)se.has(n)&&(se.delete(n),t.push(n)),n=n.parent;for(let e=t.length-1;e>=0;e--){const n=t[e];24576&n.f||$t(n)}}se.clear()}}se=null}}function ae(e,t,n,r){if(!n.has(e)&&(n.add(e),null!==e.reactions))for(const i of e.reactions){const e=i.f;2&e?ae(i,t,n,r):4194320&e&&0===(e&y)&&fe(i,t,r)&&(It(i,y),ce(i))}}function fe(e,t,n){const r=n.get(e);if(void 0!==r)return r;if(null!==e.deps)for(const i of e.deps){if(t.includes(i))return!0;if(2&i.f&&fe(i,t,n))return n.set(i,!0),!0}return n.set(e,!1),!1}function ce(e){for(var t=Y=e;null!==t.parent;){var n=(t=t.parent).f;if(ee&&t===gt&&0!==(n&h)&&0===(n&S))return;if(96&n){if(0===(n&m))return;t.f^=m}}X.push(t)}class ue{parent;#n=!1;#d;#h=null;#v;#p;#_;#g=null;#m=null;#y=null;#b=null;#w=null;#k=0;#x=0;#E=!1;#P=null;#S=function(e){let t,n=0,r=xe(0);return()=>{Fe()&&(Mt(r),Je(()=>(0===n&&(t=Ct(()=>e(()=>Ae(r)))),n+=1,()=>{V(()=>{n-=1,0===n&&(t?.(),t=void 0,Ae(r))})})))}}(()=>(this.#P=xe(this.#k),()=>{this.#P=null}));constructor(e,t,n){this.#d=e,this.#v=t,this.#p=n,this.parent=gt.b,this.#n=!!this.#v.pending,this.#_=Xe(()=>{gt.b=this;var e=this.#A();try{this.#g=Ye(()=>n(e))}catch(t){this.error(t)}return this.#x>0?this.#q():this.#n=!1,()=>{this.#w?.remove()}},589952)}#j(){try{this.#g=Ye(()=>this.#p(this.#d))}catch(e){this.error(e)}this.#n=!1}#O(){const e=this.#v.pending;e&&(this.#m=Ye(()=>e(this.#d)),ne.enqueue(()=>{var e=this.#A();this.#g=this.#L(()=>(ne.ensure(),Ye(()=>this.#p(e)))),this.#x>0?this.#q():(lt(this.#m,()=>{this.#m=null}),this.#n=!1)}))}#A(){var e=this.#d;return this.#n&&(this.#w=Me(),this.#d.before(this.#w),e=this.#w),e}is_pending(){return this.#n||!!this.parent&&this.parent.is_pending()}has_pending_snippet(){return!!this.#v.pending}#L(e){var t=gt,n=vt,r=C;mt(this.#_),_t(this.#_),T(this.#_.ctx);try{return e()}catch(i){return F(i),null}finally{mt(t),_t(n),T(r)}}#q(){const e=this.#v.pending;null!==this.#g&&(this.#b=document.createDocumentFragment(),this.#b.append(this.#w),ft(this.#g,this.#b)),null===this.#m&&(this.#m=Ye(()=>e(this.#d)))}#z(e){this.has_pending_snippet()?(this.#x+=e,0===this.#x&&(this.#n=!1,this.#m&<(this.#m,()=>{this.#m=null}),this.#b&&(this.#d.before(this.#b),this.#b=null))):this.parent&&this.parent.#z(e)}update_pending_count(e){this.#z(e),this.#k+=e,this.#P&&Se(this.#P,this.#k)}get_effect_pending(){return this.#S(),Mt(this.#P)}error(e){var t=this.#v.onerror;let n=this.#v.failed;if(this.#E||!t&&!n)throw e;this.#g&&(nt(this.#g),this.#g=null),this.#m&&(nt(this.#m),this.#m=null),this.#y&&(nt(this.#y),this.#y=null);var r=!1,i=!1;const l=()=>{r?console.warn("https://svelte.dev/e/svelte_boundary_reset_noop"):(r=!0,i&&function(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}(),ne.ensure(),this.#k=0,null!==this.#y&<(this.#y,()=>{this.#y=null}),this.#n=this.has_pending_snippet(),this.#g=this.#L(()=>(this.#E=!1,Ye(()=>this.#p(this.#d)))),this.#x>0?this.#q():this.#n=!1)};var s=vt;try{_t(null),i=!0,t?.(e,l),i=!1}catch(e){K(e,this.#_&&this.#_.parent)}finally{_t(s)}n&&V(()=>{this.#y=this.#L(()=>{ne.ensure(),this.#E=!0;try{return Ye(()=>{n(this.#d,()=>e,()=>l)})}catch(e){return K(e,this.#_.parent),null}finally{this.#E=!1}})})}}function de(e,t,n,r){const i=pe;if(0!==n.length||0!==e.length){var l=G,s=gt,o=he();e.length>0?Promise.all(e).then(()=>{o();try{return a()}finally{l?.deactivate(),ve()}}):a()}else r(t.map(i));function a(){Promise.all(n.map(e=>function(e){let t=gt;null===t&&function(){throw new Error("https://svelte.dev/e/async_derived_orphan")}();var n=t.b,r=void 0,i=xe(M),l=!vt,s=new Map;return function(e){We(4718592,e,!0)}(()=>{var t=d();r=t.promise;try{Promise.resolve(e()).then(t.resolve,t.reject).then(()=>{o===G&&o.committed&&o.deactivate(),ve()})}catch(c){t.reject(c),ve()}var o=G;if(l){var a=!n.is_pending();n.update_pending_count(1),o.increment(a),s.get(o)?.reject($),s.delete(o),s.set(o,t)}const f=(e,t=void 0)=>{if(o.activate(),t)t!==$&&(i.f|=O,Se(i,t));else{0!==(i.f&O)&&(i.f^=O),Se(i,e);for(const[e,t]of s){if(s.delete(e),e===o)break;t.reject($)}}l&&(n.update_pending_count(-1),o.decrement(a))};t.promise.then(f,e=>f(null,e||"unknown"))}),Ke(()=>{for(const e of s.values())e.reject($)}),new Promise(e=>{function t(n){function l(){n===r?e(i):t(r)}n.then(l,l)}t(r)})}(e))).then(e=>{o();try{r([...t.map(i),...e])}catch(n){0===(s.f&k)&&K(n,s)}l?.deactivate(),ve()}).catch(e=>{K(e,s)})}}function he(){var e=gt,t=vt,n=C,r=G;return function(i=!0){mt(e),_t(t),T(n),i&&r?.activate()}}function ve(){mt(null),_t(null),T(null)}function pe(e){var t=null!==vt&&2&vt.f?vt:null;null!==gt&&(gt.f|=A);return{ctx:C,deps:null,effects:null,equals:R,f:2050,fn:e,reactions:null,rv:0,v:M,wv:0,parent:t??gt,ac:null}}function _e(e){const t=pe(e);return bt(t),t}function ge(e){var t=e.effects;if(null!==t){e.effects=null;for(var n=0;n<t.length;n+=1)nt(t[n])}}function me(e){var t,n=gt;mt(function(e){for(var t=e.parent;null!==t;){if(!(2&t.f))return 0===(t.f&k)?t:null;t=t.parent}return null}(e));try{e.f&=-32769,ge(e),t=Lt(e)}finally{mt(n)}return t}function ye(e){var t=me(e);(e.equals(t)||(G?.is_fork||(e.v=t),e.wv=qt()),dt)||(null!==Q?(Fe()||G?.is_fork)&&Q.set(e,t):It(e,0===(e.f&g)?b:m))}let be=new Set;const we=new Map;let ke=!1;function xe(e,t){return{f:0,v:e,reactions:null,equals:R,rv:0,wv:0}}function Ee(e,t){const n=xe(e);return bt(n),n}function Pe(e,t,n=!1){return null===vt||pt&&0===(vt.f&P)||!(4325394&vt.f)||yt?.includes(e)||function(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}(),Se(e,n?je(t):t)}function Se(e,t){if(!e.equals(t)){var n=e.v;dt?we.set(e,t):we.set(e,n),e.v=t;var r=ne.ensure();r.capture(e,n),2&e.f&&(0!==(e.f&y)&&me(e),It(e,0!==(e.f&g)?m:b)),e.wv=qt(),qe(e,y),null===gt||0===(gt.f&m)||96>.f||(null===xt?function(e){xt=e}([e]):xt.push(e)),!r.is_fork&&be.size>0&&!ke&&function(){ke=!1;var e=ct;ut(!0);const t=Array.from(be);try{for(const e of t)0!==(e.f&m)&&It(e,b),jt(e)&&$t(e)}finally{ut(e)}be.clear()}()}return t}function Ae(e){Pe(e,e.v+1)}function qe(e,t){var n=e.reactions;if(null!==n)for(var r=n.length,i=0;i<r;i++){var l=n[i],s=l.f,o=0===(s&y);if(o&&It(l,t),2&s){var a=l;Q?.delete(a),0===(s&q)&&(s&g&&(l.f|=q),qe(a,b))}else o&&(0!==(s&h)&&null!==se&&se.add(l),ce(l))}}function je(e){if("object"!=typeof e||null===e||L in e)return e;const n=f(e);if(n!==o&&n!==a)return e;var r=new Map,i=t(e),s=Ee(0),c=St,u=e=>{if(St===c)return e();var t=vt,n=St;_t(null),At(c);var r=e();return _t(t),At(n),r};return i&&r.set("length",Ee(e.length)),new Proxy(e,{defineProperty(e,t,n){"value"in n&&!1!==n.configurable&&!1!==n.enumerable&&!1!==n.writable||function(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}();var i=r.get(t);return void 0===i?i=u(()=>{var e=Ee(n.value);return r.set(t,e),e}):Pe(i,n.value,!0),!0},deleteProperty(e,t){var n=r.get(t);if(void 0===n){if(t in e){const e=u(()=>Ee(M));r.set(t,e),Ae(s)}}else Pe(n,M),Ae(s);return!0},get(t,n,i){if(n===L)return e;var s=r.get(n),o=n in t;if(void 0!==s||o&&!l(t,n)?.writable||(s=u(()=>Ee(je(o?t[n]:M))),r.set(n,s)),void 0!==s){var a=Mt(s);return a===M?void 0:a}return Reflect.get(t,n,i)},getOwnPropertyDescriptor(e,t){var n=Reflect.getOwnPropertyDescriptor(e,t);if(n&&"value"in n){var i=r.get(t);i&&(n.value=Mt(i))}else if(void 0===n){var l=r.get(t),s=l?.v;if(void 0!==l&&s!==M)return{enumerable:!0,configurable:!0,value:s,writable:!0}}return n},has(e,t){if(t===L)return!0;var n=r.get(t),i=void 0!==n&&n.v!==M||Reflect.has(e,t);if((void 0!==n||null!==gt&&(!i||l(e,t)?.writable))&&(void 0===n&&(n=u(()=>Ee(i?je(e[t]):M)),r.set(t,n)),Mt(n)===M))return!1;return i},set(e,t,n,o){var a=r.get(t),f=t in e;if(i&&"length"===t)for(var c=n;c<a.v;c+=1){var d=r.get(c+"");void 0!==d?Pe(d,M):c in e&&(d=u(()=>Ee(M)),r.set(c+"",d))}void 0===a?f&&!l(e,t)?.writable||(Pe(a=u(()=>Ee(void 0)),je(n)),r.set(t,a)):(f=a.v!==M,Pe(a,u(()=>je(n))));var h=Reflect.getOwnPropertyDescriptor(e,t);if(h?.set&&h.set.call(o,n),!f){if(i&&"string"==typeof t){var v=r.get("length"),p=Number(t);Number.isInteger(p)&&p>=v.v&&Pe(v,p+1)}Ae(s)}return!0},ownKeys(e){Mt(s);var t=Reflect.ownKeys(e).filter(e=>{var t=r.get(e);return void 0===t||t.v!==M});for(var[n,i]of r)i.v===M||n in e||t.push(n);return t},setPrototypeOf(){!function(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}()}})}function Oe(e){try{if(null!==e&&"object"==typeof e&&L in e)return e[L]}catch{}return e}var Le,ze,Ne,$e;function Me(e=""){return document.createTextNode(e)}function De(e){return Ne.call(e)}function Re(e){return $e.call(e)}function Ce(e,t){return De(e)}function Te(e,t=!1){var n=De(e);return n instanceof Comment&&""===n.data?Re(n):n}function Ie(e,t=1,n=!1){let r=e;for(;t--;)r=Re(r);return r}let Ue=!1;function Ze(e){var t=vt,n=gt;_t(null),mt(null);try{return e()}finally{_t(t),mt(n)}}function Be(e,t,n,r=n){e.addEventListener(t,()=>Ze(n));const i=e.__on_r;e.__on_r=i?()=>{i(),r(!0)}:()=>r(!0),Ue||(Ue=!0,document.addEventListener("reset",e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(const t of e.target.elements)t.__on_r?.()})},{capture:!0}))}function Ve(e){null===gt&&(null===vt&&function(){throw new Error("https://svelte.dev/e/effect_orphan")}(),function(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}()),dt&&function(){throw new Error("https://svelte.dev/e/effect_in_teardown")}()}function We(e,t,n){var r=gt;null!==r&&0!==(r.f&w)&&(e|=w);var i={ctx:C,deps:null,nodes:null,f:e|y|g,first:null,fn:t,last:null,next:null,parent:r,b:r&&r.b,prev:null,teardown:null,wv:0,ac:null};if(n)try{$t(i),i.f|=x}catch(l){throw nt(i),l}else null!==t&&ce(i);var l=i;if(n&&null===l.deps&&null===l.teardown&&null===l.nodes&&l.first===l.last&&0===(l.f&A)&&(l=l.first,0!==(e&h)&&0!==(e&E)&&null!==l&&(l.f|=E)),null!==l&&(l.parent=r,null!==r&&function(e,t){var n=t.last;null===n?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}(l,r),null!==vt&&2&vt.f&&0===(e&p))){var s=vt;(s.effects??=[]).push(l)}return i}function Fe(){return null!==vt&&!pt}function Ke(e){const t=We(8,null,!1);return It(t,m),t.teardown=e,t}function He(e){Ve();var t=gt.f;if(!(!vt&&0!==(t&v)&&0===(t&x)))return Ge(e);var n=C;(n.e??=[]).push(e)}function Ge(e){return We(1048580,e,!1)}function Je(e,t=0){return We(8|t,e,!0)}function Qe(e,t=[],n=[],r=[]){de(r,t,n,t=>{We(8,()=>e(...t.map(Mt)),!0)})}function Xe(e,t=0){return We(h|t,e,!0)}function Ye(e){return We(524320,e,!0)}function et(e){var t=e.teardown;if(null!==t){const e=dt,n=vt;ht(!0),_t(null);try{t.call(null)}finally{ht(e),_t(n)}}}function tt(e,t=!1){var n=e.first;for(e.first=e.last=null;null!==n;){const e=n.ac;null!==e&&Ze(()=>{e.abort($)});var r=n.next;0!==(n.f&p)?n.parent=null:nt(n,t),n=r}}function nt(e,t=!0){var n=!1;!t&&0===(e.f&S)||null===e.nodes||null===e.nodes.end||(rt(e.nodes.start,e.nodes.end),n=!0),tt(e,t&&!n),Nt(e,0),It(e,k);var r=e.nodes&&e.nodes.t;if(null!==r)for(const l of r)l.stop();et(e);var i=e.parent;null!==i&&null!==i.first&&it(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=null}function rt(e,t){for(;null!==e;){var n=e===t?null:Re(e);e.remove(),e=n}}function it(e){var t=e.parent,n=e.prev,r=e.next;null!==n&&(n.next=r),null!==r&&(r.prev=n),null!==t&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function lt(e,t,n=!0){var r=[];st(e,r,!0);var i=()=>{n&&nt(e),t&&t()},l=r.length;if(l>0){var s=()=>--l||i();for(var o of r)o.out(s)}else i()}function st(e,t,n){if(0===(e.f&w)){e.f^=w;var r=e.nodes&&e.nodes.t;if(null!==r)for(const e of r)(e.is_global||n)&&t.push(e);for(var i=e.first;null!==i;){var l=i.next;st(i,t,!!(0!==(i.f&E)||0!==(i.f&v)&&0!==(e.f&h))&&n),i=l}}}function ot(e){at(e,!0)}function at(e,t){if(0!==(e.f&w)){e.f^=w,0===(e.f&m)&&(It(e,y),ce(e));for(var n=e.first;null!==n;){var r=n.next;at(n,!!(0!==(n.f&E)||0!==(n.f&v))&&t),n=r}var i=e.nodes&&e.nodes.t;if(null!==i)for(const e of i)(e.is_global||t)&&e.in()}}function ft(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;null!==n;){var i=n===r?null:Re(n);t.append(n),n=i}}let ct=!1;function ut(e){ct=e}let dt=!1;function ht(e){dt=e}let vt=null,pt=!1;function _t(e){vt=e}let gt=null;function mt(e){gt=e}let yt=null;function bt(e){null!==vt&&(null===yt?yt=[e]:yt.push(e))}let wt=null,kt=0,xt=null;let Et=1,Pt=0,St=Pt;function At(e){St=e}function qt(){return++Et}function jt(e){var t=e.f;if(0!==(t&y))return!0;if(2&t&&(e.f&=-32769),0!==(t&b)){var n=e.deps;if(null!==n)for(var r=n.length,i=0;i<r;i++){var l=n[i];if(jt(l)&&ye(l),l.wv>e.wv)return!0}0!==(t&g)&&null===Q&&It(e,m)}return!1}function Ot(e,t,n=!0){var r=e.reactions;if(null!==r&&!yt?.includes(e))for(var i=0;i<r.length;i++){var l=r[i];2&l.f?Ot(l,t,!1):t===l&&(n?It(l,y):0!==(l.f&m)&&It(l,b),ce(l))}}function Lt(e){var t=wt,n=kt,r=xt,i=vt,l=yt,s=C,o=pt,a=St,f=e.f;wt=null,kt=0,xt=null,vt=96&f?null:e,yt=null,T(e.ctx),pt=!1,St=++Pt,null!==e.ac&&(Ze(()=>{e.ac.abort($)}),e.ac=null);try{e.f|=j;var c=(0,e.fn)(),u=e.deps;if(null!==wt){var d;if(Nt(e,kt),null!==u&&kt>0)for(u.length=kt+wt.length,d=0;d<wt.length;d++)u[kt+d]=wt[d];else e.deps=u=wt;if(Fe()&&0!==(e.f&g))for(d=kt;d<u.length;d++)(u[d].reactions??=[]).push(e)}else null!==u&&kt<u.length&&(Nt(e,kt),u.length=kt);if(!(null===xt||pt||null===u||6146&e.f))for(d=0;d<xt.length;d++)Ot(xt[d],e);return null!==i&&i!==e&&(Pt++,null!==xt&&(null===r?r=xt:r.push(...xt))),0!==(e.f&O)&&(e.f^=O),c}catch(h){return F(h)}finally{e.f^=j,wt=t,kt=n,xt=r,vt=i,yt=l,T(s),pt=o,St=a}}function zt(e,t){let r=t.reactions;if(null!==r){var i=n.call(r,e);if(-1!==i){var l=r.length-1;0===l?r=t.reactions=null:(r[i]=r[l],r.pop())}}null===r&&2&t.f&&(null===wt||!wt.includes(t))&&(It(t,b),0!==(t.f&g)&&(t.f^=g,t.f&=-32769),ge(t),Nt(t,0))}function Nt(e,t){var n=e.deps;if(null!==n)for(var r=t;r<n.length;r++)zt(e,n[r])}function $t(e){var t=e.f;if(0===(t&k)){It(e,m);var n=gt,r=ct;gt=e,ct=!0;try{16777232&t?function(e){for(var t=e.first;null!==t;){var n=t.next;0===(t.f&v)&&nt(t),t=n}}(e):tt(e),et(e);var i=Lt(e);e.teardown="function"==typeof i?i:null,e.wv=Et}finally{ct=r,gt=n}}}function Mt(e){var t=!!(2&e.f);if(null!==vt&&!pt&&(!(null!==gt&&0!==(gt.f&k))&&!yt?.includes(e))){var n=vt.deps;if(0!==(vt.f&j))e.rv<Pt&&(e.rv=Pt,null===wt&&null!==n&&n[kt]===e?kt++:null===wt?wt=[e]:wt.includes(e)||wt.push(e));else{(vt.deps??=[]).push(e);var r=e.reactions;null===r?e.reactions=[vt]:r.includes(vt)||r.push(vt)}}if(dt){if(we.has(e))return we.get(e);if(t){var i=e,l=i.v;return(0===(i.f&m)&&null!==i.reactions||Rt(i))&&(l=me(i)),we.set(i,l),l}}else t&&(!Q?.has(e)||G?.is_fork&&!Fe())&&(jt(i=e)&&ye(i),ct&&Fe()&&0===(i.f&g)&&Dt(i));if(Q?.has(e))return Q.get(e);if(0!==(e.f&O))throw e.v;return e.v}function Dt(e){if(null!==e.deps){e.f^=g;for(const t of e.deps)(t.reactions??=[]).push(e),2&t.f&&0===(t.f&g)&&Dt(t)}}function Rt(e){if(e.v===M)return!0;if(null===e.deps)return!1;for(const t of e.deps){if(we.has(t))return!0;if(2&t.f&&Rt(t))return!0}return!1}function Ct(e){var t=pt;try{return pt=!0,e()}finally{pt=t}}const Tt=-7169;function It(e,t){e.f=e.f&Tt|t}const Ut=["touchstart","touchmove"];function Zt(e){return Ut.includes(e)}const Bt=new Set,Vt=new Set;function Wt(e){for(var t=0;t<e.length;t++)Bt.add(e[t]);for(var n of Vt)n(e)}let Ft=null;function Kt(e){var t=this,n=t.ownerDocument,r=e.type,l=e.composedPath?.()||[],s=l[0]||e.target;Ft=e;var o=0,a=Ft===e&&e.__root;if(a){var f=l.indexOf(a);if(-1!==f&&(t===document||t===window))return void(e.__root=t);var c=l.indexOf(t);if(-1===c)return;f<=c&&(o=f)}if((s=l[o]||e.target)!==t){i(e,"currentTarget",{configurable:!0,get:()=>s||n});var u=vt,d=gt;_t(null),mt(null);try{for(var h,v=[];null!==s;){var p=s.assignedSlot||s.parentNode||s.host||null;try{var _=s["__"+r];null==_||s.disabled&&e.target!==s||_.call(s,e)}catch(g){h?v.push(g):h=g}if(e.cancelBubble||p===t||null===p)break;s=p}if(h){for(let e of v)queueMicrotask(()=>{throw e});throw h}}finally{e.__root=t,delete e.currentTarget,_t(u),mt(d)}}}function Ht(e){var t=document.createElement("template");return t.innerHTML=e.replaceAll("<!>","\x3c!----\x3e"),t.content}function Gt(e,t){var n=gt;null===n.nodes&&(n.nodes={start:e,end:t,a:null,t:null})}function Jt(e,t){var n,r=!!(1&t),i=!!(2&t),l=!e.startsWith("<!>");return()=>{void 0===n&&(n=Ht(l?e:"<!>"+e),r||(n=De(n)));var t=i||ze?document.importNode(n,!0):n.cloneNode(!0);r?Gt(De(t),t.lastChild):Gt(t,t);return t}}function Qt(e=""){var t=Me(e+"");return Gt(t,t),t}function Xt(){var e=document.createDocumentFragment(),t=document.createComment(""),n=Me();return e.append(t,n),Gt(t,n),e}function Yt(e,t){null!==e&&e.before(t)}function en(e,t){var n=null==t?"":"object"==typeof t?t+"":t;n!==(e.__t??=e.nodeValue)&&(e.__t=n,e.nodeValue=n+"")}const tn=new Map;let nn=new WeakMap;class rn{anchor;#N=new Map;#$=new Map;#M=new Map;#D=new Set;#R=!0;constructor(e,t=!0){this.anchor=e,this.#R=t}#u=()=>{var e=G;if(this.#N.has(e)){var t=this.#N.get(e),n=this.#$.get(t);if(n)ot(n),this.#D.delete(t);else{var r=this.#M.get(t);r&&(this.#$.set(t,r.effect),this.#M.delete(t),r.fragment.lastChild.remove(),this.anchor.before(r.fragment),n=r.effect)}for(const[t,n]of this.#N){if(this.#N.delete(t),t===e)break;const r=this.#M.get(n);r&&(nt(r.effect),this.#M.delete(n))}for(const[e,r]of this.#$){if(e===t||this.#D.has(e))continue;const i=()=>{if(Array.from(this.#N.values()).includes(e)){var t=document.createDocumentFragment();ft(r,t),t.append(Me()),this.#M.set(e,{effect:r,fragment:t})}else nt(r);this.#D.delete(e),this.#$.delete(e)};this.#R||!n?(this.#D.add(e),lt(r,i,!1)):i()}}};#C=e=>{this.#N.delete(e);const t=Array.from(this.#N.values());for(const[n,r]of this.#M)t.includes(n)||(nt(r.effect),this.#M.delete(n))};ensure(e,t){var n=G;!t||this.#$.has(e)||this.#M.has(e)||this.#$.set(e,Ye(()=>t(this.anchor)));this.#N.set(n,e),this.#u()}}function ln(e,t,n,r,i){var l=M,s=xe(l),o=xe(l),a=new rn(e);Xe(()=>{var e=t(),l=!1;if(function(e){return"function"==typeof e?.then}(e)){var f=he(),c=!1;const t=e=>{if(!l){c=!0,f(!1),ne.ensure();try{e()}finally{ve(),te||re()}}};e.then(e=>{t(()=>{Se(s,e),a.ensure(1,r&&(e=>r(e,s)))})},e=>{t(()=>{if(Se(o,e),a.ensure(1,i&&(e=>i(e,o))),!i)throw o.v})}),V(()=>{c||t(()=>{a.ensure(0,n)})})}else Se(s,e),a.ensure(1,r&&(e=>r(e,s)));return()=>{l=!0}})}function sn(e,t,n=!1){var r=new rn(e);function i(e,t){r.ensure(e,t)}Xe(()=>{var e=!1;t((t,n=!0)=>{e=!0,i(n,t)}),e||i(!1,null)},n?E:0)}function on(e,t,...n){var r=new rn(e);Xe(()=>{const e=t()??null;r.ensure(e,e&&(t=>e(t,...n)))},E)}function an(e,t,n){var r=new rn(e);Xe(()=>{var e=t()??null;r.ensure(e,e&&(t=>n(t,e)))},E)}const fn=[..." \t\n\r\fย \v\ufeff"];function cn(e,t,n,r,i,l){var s=e.__className;if(s!==n||void 0===s){var o=function(e,t,n){var r=""+e;if(n)for(var i in n)if(n[i])r=r?r+" "+i:i;else if(r.length)for(var l=i.length,s=0;(s=r.indexOf(i,s))>=0;){var o=s+l;0!==s&&!fn.includes(r[s-1])||o!==r.length&&!fn.includes(r[o])?s=o:r=(0===s?"":r.substring(0,s))+r.substring(o+1)}return""===r?null:r}(n,0,l);null==o?e.removeAttribute("class"):e.className=o,e.__className=n}else if(l&&i!==l)for(var a in l){var f=!!l[a];null!=i&&f===!!i[a]||e.classList.toggle(a,f)}return l}const un=Symbol("is custom element"),dn=Symbol("is html");function hn(e,t,n,r){var i=function(e){return e.__attributes??={[un]:e.nodeName.includes("-"),[dn]:e.namespaceURI===D}}(e);i[t]!==(i[t]=n)&&("loading"===t&&(e[N]=n),null==n?e.removeAttribute(t):"string"!=typeof n&&_n(e).includes(t)?e[t]=n:e.setAttribute(t,n))}function vn(e,t,n){var r=vt,i=gt;_t(null),mt(null);try{"style"!==t&&(pn.has(e.getAttribute("is")||e.nodeName)||!customElements||customElements.get(e.getAttribute("is")||e.tagName.toLowerCase())?_n(e).includes(t):n&&"object"==typeof n)?e[t]=n:hn(e,t,null==n?n:String(n))}finally{_t(r),mt(i)}}var pn=new Map;function _n(e){var t,n=e.getAttribute("is")||e.nodeName,r=pn.get(n);if(r)return r;pn.set(n,r=[]);for(var i=e,l=Element.prototype;l!==i;){for(var o in t=s(i))t[o].set&&r.push(o);i=f(i)}return r}function gn(e,t,n=t){var r=new WeakSet;Be(e,"input",async i=>{var l=i?e.defaultValue:e.value;if(l=bn(e)?wn(l):l,n(l),null!==G&&r.add(G),await async function(){await Promise.resolve(),re()}(),l!==(l=t())){var s=e.selectionStart,o=e.selectionEnd,a=e.value.length;if(e.value=l??"",null!==o){var f=e.value.length;s===o&&o===a&&f>a?(e.selectionStart=f,e.selectionEnd=f):(e.selectionStart=s,e.selectionEnd=Math.min(o,f))}}}),null==Ct(t)&&e.value&&(n(bn(e)?wn(e.value):e.value),null!==G&&r.add(G)),Je(()=>{var n=t();if(e===document.activeElement){var i=J??G;if(r.has(i))return}bn(e)&&n===wn(e.value)||("date"!==e.type||n||e.value)&&n!==e.value&&(e.value=n??"")})}const mn=new Set;function yn(e,t,n,r,i=r){var l="checkbox"===n.getAttribute("type"),s=e;if(null!==t)for(var o of t)s=s[o]??=[];s.push(n),Be(n,"change",()=>{var e=n.__value;l&&(e=function(e,t,n){for(var r=new Set,i=0;i<e.length;i+=1)e[i].checked&&r.add(e[i].__value);n||r.delete(t);return Array.from(r)}(s,e,n.checked)),i(e)},()=>i(l?[]:null)),Je(()=>{var e,t,i=r();l?(i=i||[],n.checked=i.includes(n.__value)):n.checked=(e=n.__value,t=i,Object.is(Oe(e),Oe(t)))}),Ke(()=>{var e=s.indexOf(n);-1!==e&&s.splice(e,1)}),mn.has(s)||(mn.add(s),V(()=>{s.sort((e,t)=>4===e.compareDocumentPosition(t)?-1:1),mn.delete(s)})),V(()=>{})}function bn(e){var t=e.type;return"number"===t||"range"===t}function wn(e){return""===e?null:+e}let kn=!1;function xn(e,t,n,r){var i,s,o=r,a=!0,f=L in e||z in e;i=l(e,t)?.set??(f&&t in e?n=>e[t]=n:void 0);var c,u=!1;if([s,u]=function(e){var t=kn;try{return kn=!1,[e(),kn]}finally{kn=t}}(()=>e[t]),c=()=>{var n=e[t];return void 0===n?(a&&(a=!1,o=r),o):(a=!0,n)},i){var d=e.$$legacy;return function(e,t){return arguments.length>0?((!t||d||u)&&i(t?c():e),e):c()}}var h=!1,v=pe(()=>(h=!1,c()));Mt(v);var p=gt;return function(e,t){if(arguments.length>0){const n=t?Mt(v):je(e);return Pe(v,n),h=!0,void 0!==o&&(o=n),e}return dt&&h||0!==(p.f&k)?v.v:Mt(v)}}const En={},Pn=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){const e=document.getElementsByTagName("link"),l=document.querySelector("meta[property=csp-nonce]"),s=l?.nonce||l?.getAttribute("nonce");i=t.map(t=>{if(t=function(e,t){return new URL(e,t).href}(t,n),t in En)return;En[t]=!0;const r=t.endsWith(".css"),i=r?'[rel="stylesheet"]':"";if(n)for(let n=e.length-1;n>=0;n--){const i=e[n];if(i.href===t&&(!r||"stylesheet"===i.rel))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;const l=document.createElement("link");return l.rel=r?"stylesheet":"modulepreload",r||(l.as="script"),l.crossOrigin="",l.href=t,s&&l.setAttribute("nonce",s),document.head.appendChild(l),r?new Promise((e,n)=>{l.addEventListener("load",e),l.addEventListener("error",()=>n(new Error(`Unable to preload CSS for ${t}`)))}):void 0}),r=Promise.all(i.map(e=>Promise.resolve(e).then(e=>({status:"fulfilled",value:e}),e=>({status:"rejected",reason:e}))))}var i;function l(e){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(const e of t||[])"rejected"===e.status&&l(e.reason);return e().catch(l)})};"undefined"!=typeof window&&((window.__svelte??={}).v??=new Set).add("5");const Sn=/^[234567abcdefghij][234567abcdefghijklmnopqrstuvwxyz]{12}$/,An=/^did:([a-z]+):([a-zA-Z0-9._:%-]*[a-zA-Z0-9._-])$/,qn=/^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/,jn=e=>(e=>e.length>=7&&e.length<=2048&&An.test(e))(e)||(e=>e.length>=3&&e.length<=253&&qn.test(e))(e),On=e=>{const t=Ln(e);if(!t)return null;let n;if("bsky.app"===t.host||"staging.bsky.app"===t.host||"main.bsky.dev"===t.host){if(n=/^\/profile\/([^/]+)\/post\/([^/]+)\/?$/.exec(t.pathname))return jn(n[1])&&(e=>13===e.length&&Sn.test(e))(n[2])?{type:"post",author:n[1],rkey:n[2]}:null;if(n=/^\/profile\/([^/]+)\/?$/.exec(t.pathname))return jn(n[1])?{type:"profile",actor:n[1]}:null}return null},Ln=e=>{let t;if("parse"in URL)t=URL.parse(e);else try{t=new URL(e)}catch{}return!t||"https:"!==t.protocol&&"http:"!==t.protocol?null:t};var zn=Jt("<div><!></div>");function Nn(e,t){var n=zn();let r;on(Ce(n),()=>t.children),Qe(()=>r=cn(n,0,"banner svelte-4gizvm",0,r,{"type-alert":"alert"===t.type,"type-inform":"inform"===t.type})),Yt(e,n)}var $n=function(e,t,n="svg"){var r,i=`<${n}>${e.startsWith("<!>")?"<!>"+e:e}</${n}>`;return()=>{if(!r){var e=De(Ht(i));r=De(e)}var t=r.cloneNode(!0);return Gt(t,t),t}}('<svg viewBox="0 0 32 32" class="circular-spinner svelte-rq8vha"><circle cx="16" cy="16" fill="none" r="14" stroke-width="4" class="background svelte-rq8vha"></circle><circle cx="16" cy="16" fill="none" r="14" stroke-width="4" stroke-dasharray="80px" stroke-dashoffset="60px" class="accented svelte-rq8vha"></circle></svg>',0,"svg");function Mn(e,t){Yt(e,$n())}var Dn=Jt('<div class="field svelte-1wzaqos"><label class="input-wrapper svelte-1wzaqos"><span class="label svelte-1wzaqos"> </span> <!></label></div>');const Rn=new WeakMap;function Cn(e,t){I(t,!0);const n=_e(()=>(e=>{let t=Rn.get(e);return void 0===t&&Rn.set(e,t=e().then(e=>e.default)),t})(t.loader));var r=Xt();ln(Te(r),()=>Mt(n),e=>{var n=Xt();on(Te(n),()=>t.fallback),Yt(e,n)},(e,n)=>{var r=Xt();on(Te(r),()=>t.children,()=>Mt(n)),Yt(e,r)},(e,n)=>{var r=Xt();on(Te(r),()=>t.boundary,()=>Mt(n)),Yt(e,r)}),Yt(e,r),U()}var Tn=Jt('<input class="text-input svelte-1e5va0l"/>');const In=e=>{Mn(e)},Un=(e,t=u)=>{Nn(e,{type:"alert",children:(e,n)=>{var r=Qt();Qe(()=>en(r,""+t())),Yt(e,r)}})},Zn=()=>Pn(()=>import("./PostDisplay-CqTUAVla.js"),__vite__mapDeps([0,1,2,3,4]),import.meta.url),Bn=()=>Pn(()=>import("./ProfileCardDisplay-BpCMWdM3.js"),__vite__mapDeps([5,1,2,6]),import.meta.url),Vn=()=>Pn(()=>import("./ProfileFeedDisplay-QaaAcc9o.js"),__vite__mapDeps([7,1,2,3,8]),import.meta.url);var Wn=Jt('<fieldset class="choices svelte-1n46o8q"><label class="choice svelte-1n46o8q"><input type="radio" name="profile-type" class="svelte-1n46o8q"/> <span>Profile feed</span></label> <label class="choice svelte-1n46o8q"><input type="radio" name="profile-type" class="svelte-1n46o8q"/> <span>Profile card</span></label></fieldset>'),Fn=Jt('<div class="app svelte-1n46o8q"><h1 class="header svelte-1n46o8q"><code><bluesky-embed></code></h1> <!> <!> <main class="main svelte-1n46o8q"><!></main> <footer class="footer svelte-1n46o8q"><span>made with โค๏ธ by <a href="https://bsky.app/profile/did:plc:ia76kvnndjutgedggx2ibrem" class="svelte-1n46o8q">@mary.my.id</a></span> <span aria-hidden="true">ยท</span> <span><a href="https://github.com/mary-ext/bluesky-embed" class="svelte-1n46o8q">source code</a></span> <span aria-hidden="true">ยท</span> <span>MIT License</span></footer></div>');!function(e,t){(function(e,{target:t,anchor:n,props:i={},events:s,context:o,intro:a=!0}){!function(){if(void 0===Le){Le=window,ze=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;Ne=l(t,"firstChild").get,$e=l(t,"nextSibling").get,c(e)&&(e.__click=void 0,e.__className=void 0,e.__attributes=null,e.__style=void 0,e.__e=void 0),c(n)&&(n.__t=void 0)}}();var f=new Set,u=e=>{for(var n=0;n<e.length;n++){var r=e[n];if(!f.has(r)){f.add(r);var i=Zt(r);t.addEventListener(r,Kt,{passive:i});var l=tn.get(r);void 0===l?(document.addEventListener(r,Kt,{passive:i}),tn.set(r,1)):tn.set(r,l+1)}}};u(r(Bt)),Vt.add(u);var d=void 0,h=function(e){ne.ensure();const t=We(524352,e,!0);return(e={})=>new Promise(n=>{e.outro?lt(t,()=>{nt(t),n(void 0)}):(nt(t),n(void 0))})}(()=>{var r=n??t.appendChild(Me());return function(e,t,n){new ue(e,t,n)}(r,{pending:()=>{}},t=>{o&&(I({}),C.c=o);s&&(i.$$events=s),d=e(t,i)||{},o&&U()}),()=>{for(var e of f){t.removeEventListener(e,Kt);var i=tn.get(e);0===--i?(document.removeEventListener(e,Kt),tn.delete(e)):tn.set(e,i)}Vt.delete(u),r!==n&&r.parentNode?.removeChild(r)}});nn.set(d,h)})(e,t)}(function(e,t){I(t,!0);const n=[],r="https://bsky.app/profile/did:plc:ragtjsm2j2vknwkz3zp4oxrd/post/3kj2umze7zj2n";let i=Ee(""),l=Ee("feed");const s=_e(()=>On(Mt(i)||r));var o=Fn(),a=Ie(Ce(o),2);!function(e,t){var n=Dn(),r=Ce(n),i=Ce(r),l=Ce(i);on(Ie(i,2),()=>t.children),Qe(()=>en(l,t.label)),Yt(e,n)}(a,{label:"Bluesky post or profile URL",children:(e,t)=>{!function(e,t){I(t,!0);let n=xn(t,"value");var r=Tn();Qe(()=>{hn(r,"type",t.type),hn(r,"placeholder",t.placeholder)}),gn(r,n),Yt(e,r),U()}(e,{type:"url",placeholder:r,get value(){return Mt(i)},set value(e){Pe(i,e,!0)}})}});var f=Ie(a,2),c=e=>{var t=Wn(),r=Ce(t),i=Ce(r);i.value=i.__value="feed";var s=Ce(Ie(r,2));s.value=s.__value="card",yn(n,[],i,()=>Mt(l),e=>Pe(l,e)),yn(n,[],s,()=>Mt(l),e=>Pe(l,e)),Yt(e,t)};sn(f,e=>{Mt(s)&&"profile"===Mt(s).type&&e(c)});var d=Ce(Ie(f,2)),h=e=>{Nn(e,{type:"alert",children:(e,t)=>{Yt(e,Qt("Invalid URL, did you type it correctly?"))}})},v=e=>{var t=Xt(),n=Te(t),r=e=>{{const t=(e,t=u)=>{var n=Xt();an(Te(n),t,(e,t)=>{t(e,{get matched(){return Mt(s)}})}),Yt(e,n)};Cn(e,{loader:Zn,get fallback(){return In},get boundary(){return Un},children:t,$$slots:{default:!0}})}},i=e=>{var t=Xt(),n=Te(t),r=e=>{{const t=(e,t=u)=>{var n=Xt();an(Te(n),t,(e,t)=>{t(e,{get matched(){return Mt(s)}})}),Yt(e,n)};let n=_e(()=>"card"===Mt(l)?Bn:Vn);Cn(e,{get loader(){return Mt(n)},get fallback(){return In},get boundary(){return Un},children:t,$$slots:{default:!0}})}};sn(n,e=>{"profile"===Mt(s).type&&e(r)},!0),Yt(e,t)};sn(n,e=>{"post"===Mt(s).type?e(r):e(i,!1)},!0),Yt(e,t)};sn(d,e=>{Mt(s)?e(v,!1):e(h)}),Yt(e,o),U()},{target:document.getElementById("app")});export{Nn as B,Mn as C,Yt as a,U as b,Ce as c,Xt as d,Te as e,Jt as f,ln as g,Qt as h,en as i,Mt as j,Ie as k,sn as l,gt as m,Ht as n,Gt as o,I as p,De as q,rt as r,vn as s,Qe as t,_e as u,C as v,He as w,Ct as x,Wt as y,on as z};
+1
assets/index-Cr8Vao8y.js
+1
assets/index-Cr8Vao8y.js
···
1
+
const t=(t,e)=>({text:t,features:t.length>0?e:void 0}),e=(e,o)=>{if(void 0===o||0===o.length)return[t(e,void 0)];const r=[],c=e.length;let h=0,d=0;const n=(t,o)=>{let r=t;if(e.charCodeAt(r)<128)for(r+=1,d+=1;d+8<=o&&r+8<=c;){if(!((e.charCodeAt(r)|e.charCodeAt(r+1)|e.charCodeAt(r+2)|e.charCodeAt(r+3)|e.charCodeAt(r+4)|e.charCodeAt(r+5)|e.charCodeAt(r+6)|e.charCodeAt(r+7))<128))break;r+=8,d+=8}for(;d<o&&r<c;){const t=e.charCodeAt(r);t<128?(r+=1,d+=1):t<2048?(r+=1,d+=2):t<55296||t>56319?(r+=1,d+=3):(r+=2,d+=4)}return r};for(let s=0,a=o.length;s<a;s++){const c=o[s],{byteStart:a,byteEnd:i}=c.index,l=c.features;if(!(a>i||0===l.length)){if(d<a){const o=n(h,a);o>h&&r.push(t(e.slice(h,o),void 0)),h=o}{const o=n(h,i);o>h&&r.push(t(e.slice(h,o),l)),h=o}}}return h<c&&r.push(t(e.slice(h),void 0)),r};export{e as s};
+13
index.html
+13
index.html
···
1
+
<!doctype html>
2
+
<html lang="en">
3
+
<head>
4
+
<meta charset="UTF-8" />
5
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+
<title>Bluesky embed</title>
7
+
<script type="module" crossorigin src="./assets/index-CD_0uzJz.js"></script>
8
+
<link rel="stylesheet" crossorigin href="./assets/index-B_9yoyg2.css">
9
+
</head>
10
+
<body>
11
+
<div id="app"></div>
12
+
</body>
13
+
</html>
-18
package.json
-18
package.json
···
1
-
{
2
-
"private": true,
3
-
"scripts": {
4
-
"fmt": "prettier --cache --write ."
5
-
},
6
-
"devDependencies": {
7
-
"@changesets/cli": "^2.29.8",
8
-
"prettier": "^3.7.4",
9
-
"prettier-plugin-css-order": "^2.1.2",
10
-
"prettier-plugin-svelte": "^3.4.0",
11
-
"typescript": "~5.8.3"
12
-
},
13
-
"pnpm": {
14
-
"patchedDependencies": {
15
-
"svelte": "patches/svelte.patch"
16
-
}
17
-
}
18
-
}
-1
packages/bluesky-post-embed/.gitignore
-1
packages/bluesky-post-embed/.gitignore
···
1
-
themes/
-83
packages/bluesky-post-embed/README.md
-83
packages/bluesky-post-embed/README.md
···
1
-
# <bluesky-post-embed>
2
-
3
-
A custom element for embedding Bluesky posts.
4
-
5
-
## Installation
6
-
7
-
### via npm
8
-
9
-
```
10
-
npm install bluesky-post-embed
11
-
```
12
-
13
-
then, import the package on your app.
14
-
15
-
```js
16
-
import 'bluesky-post-embed';
17
-
18
-
import 'bluesky-post-embed/style.css';
19
-
import 'bluesky-post-embed/themes/light.css';
20
-
```
21
-
22
-
## Usage
23
-
24
-
```html
25
-
<bluesky-post src="at://did:plc:ragtjsm2j2vknwkz3zp4oxrd/app.bsky.feed.post/3kj2umze7zj2n">
26
-
<blockquote class="bluesky-post-fallback">
27
-
<p dir="auto">angel mode</p>
28
-
โ Paul Frazee (@pfrazee.com)
29
-
<a href="https://bsky.app/profile/did:plc:ragtjsm2j2vknwkz3zp4oxrd/post/3kj2umze7zj2n"
30
-
>January 16, 2024 at 9:11 AM</a
31
-
>
32
-
</blockquote>
33
-
</bluesky-post>
34
-
```
35
-
36
-
### Attributes
37
-
38
-
- `src` **Required**
39
-
AT-URI of the post record
40
-
- `contextless` **Optional**
41
-
Whether to show the post without any context (no parent reply)
42
-
- `allow-unauthenticated` **Optional**
43
-
Whether to allow unauthenticated viewing
44
-
- `service-uri` **Optional**
45
-
URL to an AppView service, defaults to `https://public.api.bsky.app`
46
-
47
-
### Events
48
-
49
-
- `loaded`
50
-
Fired when the embed has successfully loaded the post
51
-
- `error`
52
-
Fired when the embed fails to load the post
53
-
54
-
## SSR usage
55
-
56
-
The embeds are powered by a static HTML renderer, this renderer can be used directly in your
57
-
server-rendering framework of choice for a zero-JS experience.
58
-
59
-
```tsx
60
-
import { fetchPost, renderPost } from 'bluesky-post-embed/core';
61
-
62
-
import 'bluesky-post-embed/style.css';
63
-
import 'bluesky-post-embed/themes/light.css';
64
-
65
-
// fetch the post
66
-
const controller = new AbortController();
67
-
const data = await fetchPost({
68
-
src: `at://did:plc:ragtjsm2j2vknwkz3zp4oxrd/app.bsky.feed.post/3kj2umze7zj2n`,
69
-
signal: controller.signal,
70
-
});
71
-
72
-
// render the post
73
-
const html = renderPost(data);
74
-
return (
75
-
<bluesky-post
76
-
src={data.thread?.post.uri}
77
-
dangerouslySetInnerHTML={{ __html: html }}
78
-
></bluesky-post>
79
-
);
80
-
```
81
-
82
-
Check out examples for [Astro](https://github.com/mary-ext/bluesky-embed-astro) and
83
-
[SvelteKit](https://github.com/mary-ext/bluesky-embed-sveltekit).
-11
packages/bluesky-post-embed/index.html
-11
packages/bluesky-post-embed/index.html
···
1
-
<!doctype html>
2
-
<html lang="en">
3
-
<head>
4
-
<meta charset="utf-8" />
5
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
-
<title>Bluesky post embed</title>
7
-
</head>
8
-
<body>
9
-
<script type="module" src="./src/main.tsx"></script>
10
-
</body>
11
-
</html>
-95
packages/bluesky-post-embed/lib/bluesky-post.svelte
-95
packages/bluesky-post-embed/lib/bluesky-post.svelte
···
1
-
<script lang="ts" module>
2
-
import type { AppBskyFeedDefs, AppBskyFeedGetPostThread } from '@atcute/client/lexicons';
3
-
4
-
type ThreadData = AppBskyFeedGetPostThread.Output['thread'];
5
-
type PostView = AppBskyFeedDefs.PostView;
6
-
7
-
const unwrapPostThread = (data: ThreadData, contextless: boolean, allowUnauthenticated: boolean) => {
8
-
const items: { post: PostView; parent: PostView | null }[] = [];
9
-
10
-
let i = 0;
11
-
let il = contextless ? 1 : 2;
12
-
13
-
let curr: typeof data | undefined = data;
14
-
while (curr) {
15
-
if (
16
-
curr.$type === 'app.bsky.feed.defs#notFoundPost' ||
17
-
curr.$type === 'app.bsky.feed.defs#blockedPost'
18
-
) {
19
-
break;
20
-
}
21
-
22
-
const post = curr.post;
23
-
24
-
if (i !== 0) {
25
-
items[i - 1].parent = post;
26
-
}
27
-
28
-
if (++i > il) {
29
-
break;
30
-
}
31
-
32
-
const author = post.author;
33
-
if (!allowUnauthenticated && author.labels?.some((def) => def.val === '!no-unauthenticated')) {
34
-
break;
35
-
}
36
-
37
-
items.push({ post: post, parent: null });
38
-
curr = curr.parent;
39
-
}
40
-
return items.reverse();
41
-
};
42
-
</script>
43
-
44
-
<script lang="ts">
45
-
import EmbedFrame from 'internal/components/embed-frame.svelte';
46
-
import HighlightedPost from 'internal/components/highlighted-post.svelte';
47
-
import Post from 'internal/components/post.svelte';
48
-
49
-
import { NO_UNAUTHENTICATED_LABEL } from 'internal/utils/constants.js';
50
-
import type { PostData } from 'internal/types/post.js';
51
-
52
-
const { thread, contextless, allowUnauthenticated }: PostData = $props();
53
-
54
-
const isPwiForbidden =
55
-
!allowUnauthenticated &&
56
-
thread !== null &&
57
-
thread.$type === 'app.bsky.feed.defs#threadViewPost' &&
58
-
thread.post.author.labels?.some((label) => label.val === NO_UNAUTHENTICATED_LABEL);
59
-
</script>
60
-
61
-
{#if thread === null}
62
-
{@render Message(`The post can't be found, it may have been deleted.`)}
63
-
{:else if isPwiForbidden}
64
-
{@render Message(`The author has requested for their posts to not be displayed on external sites.`)}
65
-
{:else}
66
-
{@const posts = unwrapPostThread(thread, contextless, allowUnauthenticated)}
67
-
68
-
<EmbedFrame>
69
-
{#each posts as { post, parent }, idx}
70
-
{@const hasPrevious = idx !== 0}
71
-
72
-
{#if idx === posts.length - 1}
73
-
<HighlightedPost {post} {parent} prev={hasPrevious} />
74
-
{:else}
75
-
<Post {post} {parent} prev={hasPrevious} />
76
-
{/if}
77
-
{/each}
78
-
</EmbedFrame>
79
-
{/if}
80
-
81
-
{#snippet Message(msg: string)}
82
-
<EmbedFrame>
83
-
<div class="message">{msg}</div>
84
-
</EmbedFrame>
85
-
{/snippet}
86
-
87
-
<style>
88
-
.message {
89
-
margin: 0 auto;
90
-
padding: 32px 16px;
91
-
max-width: 380px;
92
-
color: var(--text-secondary);
93
-
text-align: center;
94
-
}
95
-
</style>
-70
packages/bluesky-post-embed/lib/core.ts
-70
packages/bluesky-post-embed/lib/core.ts
···
1
-
import '@atcute/bluesky/lexicons';
2
-
3
-
import { simpleFetchHandler, XRPC, XRPCError } from '@atcute/client';
4
-
import type { At } from '@atcute/client/lexicons';
5
-
import { render } from 'svelte/server';
6
-
7
-
import type { PostData } from 'internal/types/post.js';
8
-
import { DEFAULT_APPVIEW_URL } from 'internal/utils/constants.js';
9
-
10
-
import BlueskyPost from './bluesky-post.svelte';
11
-
12
-
export type { PostData };
13
-
14
-
export interface PostFetchOptions {
15
-
/**
16
-
* AT-URI of the post in question
17
-
*/
18
-
uri: string;
19
-
/**
20
-
* Abort signal to cancel the request
21
-
*/
22
-
signal?: AbortSignal;
23
-
/**
24
-
* Whether to fetch post without context (no parent replies)
25
-
* @default false
26
-
*/
27
-
contextless?: boolean;
28
-
/**
29
-
* Whether to allow unauthenticated viewing
30
-
* @default false
31
-
*/
32
-
allowUnauthenticated?: boolean;
33
-
/**
34
-
* AppView service to use
35
-
* @default "https://public.api.bsky.app"
36
-
*/
37
-
serviceUri?: string;
38
-
}
39
-
40
-
export const fetchPost = async (opts: PostFetchOptions): Promise<PostData> => {
41
-
const rpc = new XRPC({ handler: simpleFetchHandler({ service: opts.serviceUri ?? DEFAULT_APPVIEW_URL }) });
42
-
const contextless = opts.contextless ?? false;
43
-
44
-
const { data } = await rpc
45
-
.get('app.bsky.feed.getPostThread', {
46
-
signal: opts.signal,
47
-
params: {
48
-
uri: opts.uri as At.ResourceUri,
49
-
parentHeight: !contextless ? 2 : 1,
50
-
depth: 0,
51
-
},
52
-
})
53
-
.catch((err) => {
54
-
if (err instanceof XRPCError) {
55
-
if (err.kind === 'NotFound') {
56
-
return { data: null };
57
-
}
58
-
}
59
-
60
-
return Promise.reject(err);
61
-
});
62
-
63
-
const thread = data?.thread.$type === 'app.bsky.feed.defs#threadViewPost' ? data.thread : null;
64
-
65
-
return { thread, contextless, allowUnauthenticated: opts.allowUnauthenticated ?? false };
66
-
};
67
-
68
-
export const renderPost = (data: PostData): string => {
69
-
return render(BlueskyPost, { props: data }).body;
70
-
};
-59
packages/bluesky-post-embed/lib/wc.ts
-59
packages/bluesky-post-embed/lib/wc.ts
···
1
-
import { fetchPost, renderPost } from './core';
2
-
3
-
export class BlueskyPost extends HTMLElement {
4
-
connectedCallback() {
5
-
this.load().then(
6
-
() => this.dispatchEvent(new CustomEvent('loaded')),
7
-
(err) => {
8
-
const defaulted = this.dispatchEvent(new CustomEvent('error', { detail: err }));
9
-
if (defaulted) {
10
-
throw err;
11
-
}
12
-
},
13
-
);
14
-
}
15
-
16
-
async load() {
17
-
const src = this.getAttribute('src')!;
18
-
const serviceUri = this.getAttribute('service-uri') || undefined;
19
-
const contextless = this.getAttribute('contextless') !== null;
20
-
const allowUnauthenticated = this.getAttribute('allow-unauthenticated') !== null;
21
-
const silent = this.getAttribute('silent') !== null;
22
-
23
-
const data = await fetchPost({ uri: src, contextless, allowUnauthenticated, serviceUri }).catch(
24
-
(error) => {
25
-
if (silent) {
26
-
console.warn('Failed to fetch post:', error);
27
-
return null;
28
-
}
29
-
throw error;
30
-
},
31
-
);
32
-
33
-
if (data === null) {
34
-
return;
35
-
}
36
-
37
-
const html = renderPost(data);
38
-
39
-
const root = this.shadowRoot;
40
-
41
-
if (!root) {
42
-
this.innerHTML = html;
43
-
} else {
44
-
const template = document.createElement('template');
45
-
template.innerHTML = html;
46
-
47
-
const fragment = template.content;
48
-
const slot = root.querySelector('slot');
49
-
50
-
if (slot) {
51
-
slot.replaceWith(fragment);
52
-
} else {
53
-
root.appendChild(fragment);
54
-
}
55
-
}
56
-
}
57
-
}
58
-
59
-
customElements.define('bluesky-post', BlueskyPost);
-45
packages/bluesky-post-embed/package.json
-45
packages/bluesky-post-embed/package.json
···
1
-
{
2
-
"type": "module",
3
-
"name": "bluesky-post-embed",
4
-
"description": "Custom element for embedding Bluesky posts",
5
-
"version": "1.0.6",
6
-
"author": "externdefs",
7
-
"license": "MIT",
8
-
"repository": {
9
-
"type": "git",
10
-
"url": "https://github.com/mary-ext/bluesky-embed",
11
-
"directory": "packages/bluesky-post-embed"
12
-
},
13
-
"files": [
14
-
"dist/",
15
-
"themes/"
16
-
],
17
-
"exports": {
18
-
".": "./dist/wc.js",
19
-
"./core": "./dist/core.js",
20
-
"./style.css": "./dist/core.css",
21
-
"./themes/*": "./themes/*"
22
-
},
23
-
"scripts": {
24
-
"dev": "vite",
25
-
"build": "pnpm run check && vite build && rsync -aHAX --delete ../../themes/ themes/",
26
-
"check": "svelte-check --tsconfig ./tsconfig.json && tsc -p tsconfig.node.json",
27
-
"prepack": "pnpm run build"
28
-
},
29
-
"dependencies": {
30
-
"@atcute/bluesky": "^2.1.1",
31
-
"@atcute/bluesky-richtext-segmenter": "^2.0.4",
32
-
"@atcute/client": "^3.1.0"
33
-
},
34
-
"devDependencies": {
35
-
"@preact/preset-vite": "^2.10.2",
36
-
"@tsconfig/svelte": "^5.0.6",
37
-
"@types/node": "^24.10.1",
38
-
"internal": "workspace:^",
39
-
"preact": "^10.28.0",
40
-
"svelte": "catalog:",
41
-
"svelte-check": "^4.3.4",
42
-
"vite": "^7.2.6",
43
-
"vite-plugin-dts": "^4.5.4"
44
-
}
45
-
}
-53
packages/bluesky-post-embed/src/app.tsx
-53
packages/bluesky-post-embed/src/app.tsx
···
1
-
import { useEffect, useMemo, useState } from 'preact/hooks';
2
-
3
-
import type { PostData } from 'internal/types/post.js';
4
-
import { fetchPost, renderPost } from '../lib/core';
5
-
6
-
const uri = `at://did:plc:ragtjsm2j2vknwkz3zp4oxrd/app.bsky.feed.post/3kj2umze7zj2n`;
7
-
8
-
const App = () => {
9
-
const [state, setState] = useState<{ uri: string; data: PostData }>();
10
-
11
-
useEffect(() => {
12
-
if (state && state.uri === uri) {
13
-
return;
14
-
}
15
-
16
-
const controller = new AbortController();
17
-
const promise = fetchPost({
18
-
uri: uri,
19
-
signal: controller.signal,
20
-
allowUnauthenticated: true,
21
-
});
22
-
23
-
promise.then((data) => {
24
-
setState({ uri, data });
25
-
});
26
-
27
-
return () => {
28
-
controller.abort();
29
-
};
30
-
}, [uri]);
31
-
32
-
return <div class="app">{state && <BlueskyPost data={state.data} />}</div>;
33
-
};
34
-
35
-
export default App;
36
-
37
-
const BlueskyPost = ({ data }: { data: PostData }) => {
38
-
const html = useMemo(() => renderPost(data), [data]);
39
-
40
-
return <bluesky-post src={data.thread?.post.uri} dangerouslySetInnerHTML={{ __html: html }}></bluesky-post>;
41
-
};
42
-
43
-
declare module 'preact' {
44
-
namespace JSX {
45
-
interface BlueskyPostAttributes extends HTMLAttributes<HTMLElement> {
46
-
src?: string;
47
-
}
48
-
49
-
interface IntrinsicElements {
50
-
'bluesky-post': BlueskyPostAttributes;
51
-
}
52
-
}
53
-
}
-8
packages/bluesky-post-embed/src/main.tsx
-8
packages/bluesky-post-embed/src/main.tsx
-8
packages/bluesky-post-embed/src/styles/main.css
-8
packages/bluesky-post-embed/src/styles/main.css
-199
packages/bluesky-post-embed/src/styles/normalize.css
-199
packages/bluesky-post-embed/src/styles/normalize.css
···
1
-
/*! modern-normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize */
2
-
3
-
/*
4
-
Document
5
-
========
6
-
*/
7
-
8
-
/**
9
-
Use a better box model (opinionated).
10
-
*/
11
-
12
-
*,
13
-
::before,
14
-
::after {
15
-
box-sizing: border-box;
16
-
}
17
-
18
-
html {
19
-
line-height: 1.15; /* 1. Correct the line height in all browsers. */
20
-
/* Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) */
21
-
font-family: 'Inter', 'Roboto', ui-sans-serif, sans-serif, 'Noto Color Emoji', 'Twemoji Mozilla';
22
-
-webkit-text-size-adjust: 100%; /* 2. Prevent adjustments of font size after orientation changes in iOS. */
23
-
tab-size: 4; /* 3. Use a more readable tab size (opinionated). */
24
-
}
25
-
26
-
/*
27
-
Sections
28
-
========
29
-
*/
30
-
31
-
body {
32
-
margin: 0; /* Remove the margin in all browsers. */
33
-
}
34
-
35
-
/*
36
-
Text-level semantics
37
-
====================
38
-
*/
39
-
40
-
/**
41
-
Add the correct font weight in Chrome and Safari.
42
-
*/
43
-
44
-
b,
45
-
strong {
46
-
font-weight: bolder;
47
-
}
48
-
49
-
/**
50
-
1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
51
-
2. Correct the odd 'em' font sizing in all browsers.
52
-
*/
53
-
54
-
code,
55
-
kbd,
56
-
samp,
57
-
pre {
58
-
font-size: 1em; /* 2 */
59
-
font-family: 'JetBrains Mono NL', ui-monospace, monospace; /* 1 */
60
-
}
61
-
62
-
/**
63
-
Add the correct font size in all browsers.
64
-
*/
65
-
66
-
small {
67
-
font-size: 80%;
68
-
}
69
-
70
-
/**
71
-
Prevent 'sub' and 'sup' elements from affecting the line height in all browsers.
72
-
*/
73
-
74
-
sub,
75
-
sup {
76
-
position: relative;
77
-
vertical-align: baseline;
78
-
font-size: 75%;
79
-
line-height: 0;
80
-
}
81
-
82
-
sub {
83
-
bottom: -0.25em;
84
-
}
85
-
86
-
sup {
87
-
top: -0.5em;
88
-
}
89
-
90
-
/*
91
-
Tabular data
92
-
============
93
-
*/
94
-
95
-
/**
96
-
Correct table border color inheritance in Chrome and Safari. (https://issues.chromium.org/issues/40615503, https://bugs.webkit.org/show_bug.cgi?id=195016)
97
-
*/
98
-
99
-
table {
100
-
border-color: currentcolor;
101
-
}
102
-
103
-
/*
104
-
Forms
105
-
=====
106
-
*/
107
-
108
-
/**
109
-
1. Change the font styles in all browsers.
110
-
2. Remove the margin in Firefox and Safari.
111
-
*/
112
-
113
-
button,
114
-
input,
115
-
optgroup,
116
-
select,
117
-
textarea {
118
-
margin: 0; /* 2 */
119
-
font-size: 100%; /* 1 */
120
-
line-height: 1.15; /* 1 */
121
-
font-family: inherit; /* 1 */
122
-
}
123
-
124
-
/**
125
-
Correct the inability to style clickable types in iOS and Safari.
126
-
*/
127
-
128
-
button,
129
-
[type='button'],
130
-
[type='reset'],
131
-
[type='submit'] {
132
-
-webkit-appearance: button;
133
-
}
134
-
135
-
/**
136
-
Remove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.
137
-
*/
138
-
139
-
legend {
140
-
padding: 0;
141
-
}
142
-
143
-
/**
144
-
Add the correct vertical alignment in Chrome and Firefox.
145
-
*/
146
-
147
-
progress {
148
-
vertical-align: baseline;
149
-
}
150
-
151
-
/**
152
-
Correct the cursor style of increment and decrement buttons in Safari.
153
-
*/
154
-
155
-
::-webkit-inner-spin-button,
156
-
::-webkit-outer-spin-button {
157
-
height: auto;
158
-
}
159
-
160
-
/**
161
-
1. Correct the odd appearance in Chrome and Safari.
162
-
2. Correct the outline style in Safari.
163
-
*/
164
-
165
-
[type='search'] {
166
-
-webkit-appearance: textfield; /* 1 */
167
-
outline-offset: -2px; /* 2 */
168
-
}
169
-
170
-
/**
171
-
Remove the inner padding in Chrome and Safari on macOS.
172
-
*/
173
-
174
-
::-webkit-search-decoration {
175
-
-webkit-appearance: none;
176
-
}
177
-
178
-
/**
179
-
1. Correct the inability to style clickable types in iOS and Safari.
180
-
2. Change font properties to 'inherit' in Safari.
181
-
*/
182
-
183
-
::-webkit-file-upload-button {
184
-
-webkit-appearance: button; /* 1 */
185
-
font: inherit; /* 2 */
186
-
}
187
-
188
-
/*
189
-
Interactive
190
-
===========
191
-
*/
192
-
193
-
/*
194
-
Add the correct display in Chrome and Safari.
195
-
*/
196
-
197
-
summary {
198
-
display: list-item;
199
-
}
-8
packages/bluesky-post-embed/svelte.config.js
-8
packages/bluesky-post-embed/svelte.config.js
-14
packages/bluesky-post-embed/tsconfig.build.json
-14
packages/bluesky-post-embed/tsconfig.build.json
···
1
-
{
2
-
"extends": "@tsconfig/svelte/tsconfig.json",
3
-
"compilerOptions": {
4
-
"types": [],
5
-
"target": "ESNext",
6
-
"useDefineForClassFields": true,
7
-
"module": "ESNext",
8
-
"resolveJsonModule": true,
9
-
"isolatedModules": true,
10
-
"moduleDetection": "force",
11
-
"noEmit": true,
12
-
},
13
-
"include": ["lib"],
14
-
}
-17
packages/bluesky-post-embed/tsconfig.json
-17
packages/bluesky-post-embed/tsconfig.json
···
1
-
{
2
-
"extends": "@tsconfig/svelte/tsconfig.json",
3
-
"compilerOptions": {
4
-
"types": [],
5
-
"target": "ESNext",
6
-
"useDefineForClassFields": true,
7
-
"module": "ESNext",
8
-
"resolveJsonModule": true,
9
-
"isolatedModules": true,
10
-
"moduleDetection": "force",
11
-
"noEmit": true,
12
-
"jsx": "react-jsx",
13
-
"jsxImportSource": "preact",
14
-
},
15
-
"include": ["lib", "src"],
16
-
"references": [{ "path": "./tsconfig.node.json" }],
17
-
}
-14
packages/bluesky-post-embed/tsconfig.node.json
-14
packages/bluesky-post-embed/tsconfig.node.json
···
1
-
{
2
-
"compilerOptions": {
3
-
"composite": true,
4
-
"types": ["node"],
5
-
"skipLibCheck": true,
6
-
"module": "ESNext",
7
-
"target": "ESNext",
8
-
"moduleResolution": "Bundler",
9
-
"strict": true,
10
-
"noEmit": true,
11
-
"noUncheckedSideEffectImports": true,
12
-
},
13
-
"include": ["vite.config.ts"],
14
-
}
-103
packages/bluesky-post-embed/vite.config.ts
-103
packages/bluesky-post-embed/vite.config.ts
···
1
-
import * as path from 'node:path';
2
-
3
-
import { compile as compileSvelte } from 'svelte/compiler';
4
-
import { type Plugin, createFilter, defineConfig } from 'vite';
5
-
6
-
import preact from '@preact/preset-vite';
7
-
import dts from 'vite-plugin-dts';
8
-
9
-
export default defineConfig({
10
-
base: './',
11
-
build: {
12
-
outDir: 'dist/',
13
-
target: 'esnext',
14
-
minify: false,
15
-
cssMinify: false,
16
-
cssCodeSplit: true,
17
-
lib: {
18
-
entry: {
19
-
core: 'lib/core.ts',
20
-
wc: 'lib/wc.ts',
21
-
},
22
-
formats: ['es'],
23
-
},
24
-
rollupOptions: {
25
-
external: ['@atcute/client', '@atcute/bluesky-richtext-segmenter'],
26
-
},
27
-
},
28
-
esbuild: {
29
-
target: 'esnext',
30
-
},
31
-
plugins: [
32
-
svelte(),
33
-
preact(),
34
-
dts({
35
-
rollupTypes: true,
36
-
tsconfigPath: 'tsconfig.build.json',
37
-
beforeWriteFile(filePath, content) {
38
-
if (filePath.endsWith('/core.d.ts')) {
39
-
// Make sure the relevant types are present
40
-
return { content: `import '@atcute/bluesky/lexicons';\n${content}` };
41
-
}
42
-
},
43
-
}),
44
-
],
45
-
});
46
-
47
-
function svelte(): Plugin {
48
-
const filter = createFilter('**/*.svelte');
49
-
const stylesheets = new Map<string, string>();
50
-
51
-
return {
52
-
name: 'svelte',
53
-
resolveId(id) {
54
-
return stylesheets.has(id) ? id : null;
55
-
},
56
-
load(id) {
57
-
const css = stylesheets.get(id);
58
-
if (css !== undefined) {
59
-
this.addWatchFile(id.slice(0, -4));
60
-
return { code: css };
61
-
}
62
-
63
-
return null;
64
-
},
65
-
transform(source, id) {
66
-
if (!filter(id)) {
67
-
return null;
68
-
}
69
-
70
-
const result = compileSvelte(source, {
71
-
generate: 'server',
72
-
css: 'external',
73
-
cssHash({ hash, filename }) {
74
-
const prefix = `github:mary-ext/bluesky-post-embed/`;
75
-
return `s-` + hash(prefix + path.relative(__dirname, filename));
76
-
},
77
-
runes: true,
78
-
filename: id,
79
-
});
80
-
81
-
{
82
-
const { js, css, warnings } = result;
83
-
84
-
let jsCode = js.code;
85
-
86
-
if (css) {
87
-
const cssId = `${id}.css`;
88
-
jsCode = jsCode + `\nimport ${JSON.stringify(cssId)};\n`;
89
-
stylesheets.set(cssId, css.code);
90
-
}
91
-
92
-
for (const warn of warnings) {
93
-
if (warn.code === 'state_referenced_locally') {
94
-
continue;
95
-
}
96
-
this.warn(warn);
97
-
}
98
-
99
-
return { code: jsCode };
100
-
}
101
-
},
102
-
};
103
-
}
-1
packages/bluesky-profile-card-embed/.gitignore
-1
packages/bluesky-profile-card-embed/.gitignore
···
1
-
themes/
-81
packages/bluesky-profile-card-embed/README.md
-81
packages/bluesky-profile-card-embed/README.md
···
1
-
# <bluesky-profile-card-embed>
2
-
3
-
A custom element for embedding Bluesky profile cards.
4
-
5
-
## Installation
6
-
7
-
### via npm
8
-
9
-
```
10
-
npm install bluesky-profile-card-embed
11
-
```
12
-
13
-
then, import the package on your app.
14
-
15
-
```js
16
-
import 'bluesky-profile-card-embed';
17
-
18
-
import 'bluesky-profile-card-embed/style.css';
19
-
import 'bluesky-profile-card-embed/themes/light.css';
20
-
```
21
-
22
-
## Usage
23
-
24
-
```html
25
-
<bluesky-profile-card actor="did:plc:2gkh62xvzokhlf6li4ol3b3d">
26
-
<a
27
-
target="_blank"
28
-
href="https://bsky.app/profile/did:plc:2gkh62xvzokhlf6li4ol3b3d"
29
-
class="bluesky-profile-card-fallback"
30
-
>
31
-
@patak.dev's Bluesky profile
32
-
</a>
33
-
</bluesky-profile-card>
34
-
```
35
-
36
-
### Attributes
37
-
38
-
- `actor` **Required**
39
-
DID or handle of the account
40
-
- `allow-unauthenticated` **Optional**
41
-
Whether to allow unauthenticated viewing
42
-
- `service-uri` **Optional**
43
-
URL to an AppView service, defaults to `https://public.api.bsky.app`
44
-
45
-
### Events
46
-
47
-
- `loaded`
48
-
Fired when the embed has successfully loaded the profile card
49
-
- `error`
50
-
Fired when the embed fails to load the profile card
51
-
52
-
## SSR usage
53
-
54
-
The embeds are powered by a static HTML renderer, this renderer can be used directly in your
55
-
server-rendering framework of choice for a zero-JS experience.
56
-
57
-
```tsx
58
-
import { fetchProfileCard, renderProfileCard } from 'bluesky-profile-card-embed/core';
59
-
60
-
import 'bluesky-profile-card-embed/style.css';
61
-
import 'bluesky-profile-card-embed/themes/light.css';
62
-
63
-
// fetch the profile
64
-
const controller = new AbortController();
65
-
const data = await fetchProfileCard({
66
-
actor: `did:plc:ragtjsm2j2vknwkz3zp4oxrd`,
67
-
signal: controller.signal,
68
-
});
69
-
70
-
// render the profile
71
-
const html = renderProfileCard(data);
72
-
return (
73
-
<bluesky-profile-card
74
-
actor={data.profile?.did}
75
-
dangerouslySetInnerHTML={{ __html: html }}
76
-
></bluesky-profile-card>
77
-
);
78
-
```
79
-
80
-
Check out examples for [Astro](https://github.com/mary-ext/bluesky-embed-astro) and
81
-
[SvelteKit](https://github.com/mary-ext/bluesky-embed-sveltekit).
-11
packages/bluesky-profile-card-embed/index.html
-11
packages/bluesky-profile-card-embed/index.html
···
1
-
<!doctype html>
2
-
<html lang="en">
3
-
<head>
4
-
<meta charset="utf-8" />
5
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
-
<title>Bluesky profile card embed</title>
7
-
</head>
8
-
<body>
9
-
<script type="module" src="./src/main.tsx"></script>
10
-
</body>
11
-
</html>
-38
packages/bluesky-profile-card-embed/lib/bluesky-profile-card.svelte
-38
packages/bluesky-profile-card-embed/lib/bluesky-profile-card.svelte
···
1
-
<script lang="ts">
2
-
import EmbedFrame from 'internal/components/embed-frame.svelte';
3
-
import ProfileCard from 'internal/components/profile-card.svelte';
4
-
5
-
import type { ProfileCardData } from 'internal/types/profile-card.js';
6
-
import { NO_UNAUTHENTICATED_LABEL } from 'internal/utils/constants.js';
7
-
8
-
const { profile, allowUnauthenticated }: ProfileCardData = $props();
9
-
10
-
const isPwiForbidden =
11
-
!allowUnauthenticated && profile?.labels?.some((label) => label.val === NO_UNAUTHENTICATED_LABEL);
12
-
</script>
13
-
14
-
{#if profile === null}
15
-
{@render Message(`The profile can't be found, it may have been deleted.`)}
16
-
{:else if isPwiForbidden}
17
-
{@render Message(`The user has requested for their profile to not be displayed on external sites.`)}
18
-
{:else}
19
-
<EmbedFrame>
20
-
<ProfileCard {profile} />
21
-
</EmbedFrame>
22
-
{/if}
23
-
24
-
{#snippet Message(msg: string)}
25
-
<EmbedFrame>
26
-
<div class="message">{msg}</div>
27
-
</EmbedFrame>
28
-
{/snippet}
29
-
30
-
<style>
31
-
.message {
32
-
margin: 0 auto;
33
-
padding: 32px 16px;
34
-
max-width: 380px;
35
-
color: var(--text-secondary);
36
-
text-align: center;
37
-
}
38
-
</style>
-61
packages/bluesky-profile-card-embed/lib/core.ts
-61
packages/bluesky-profile-card-embed/lib/core.ts
···
1
-
import '@atcute/bluesky/lexicons';
2
-
3
-
import { simpleFetchHandler, XRPC, XRPCError } from '@atcute/client';
4
-
import type { At } from '@atcute/client/lexicons';
5
-
import { render } from 'svelte/server';
6
-
7
-
import type { ProfileCardData } from 'internal/types/profile-card.js';
8
-
import { DEFAULT_APPVIEW_URL } from 'internal/utils/constants.js';
9
-
10
-
import BlueskyProfileCard from './bluesky-profile-card.svelte';
11
-
12
-
export type { ProfileCardData };
13
-
14
-
export interface ProfileCardFetchOptions {
15
-
/**
16
-
* Handle or DID identifier of the user
17
-
*/
18
-
actor: string;
19
-
/**
20
-
* Abort signal to cancel the request
21
-
*/
22
-
signal?: AbortSignal;
23
-
/**
24
-
* Allow unauthenticated viewing
25
-
* @default false
26
-
*/
27
-
allowUnauthenticated?: boolean;
28
-
/**
29
-
* AppView service to use
30
-
* @default "https://public.api.bsky.app"
31
-
*/
32
-
serviceUri?: string;
33
-
}
34
-
35
-
export const fetchProfileCard = async (opts: ProfileCardFetchOptions): Promise<ProfileCardData> => {
36
-
const actor = opts.actor;
37
-
const allowUnauthenticated = opts.allowUnauthenticated ?? false;
38
-
39
-
const rpc = new XRPC({ handler: simpleFetchHandler({ service: opts.serviceUri ?? DEFAULT_APPVIEW_URL }) });
40
-
41
-
const { data: profile } = await rpc
42
-
.get('app.bsky.actor.getProfile', {
43
-
signal: opts.signal,
44
-
params: { actor: actor as At.Identifier },
45
-
})
46
-
.catch((err) => {
47
-
if (err instanceof XRPCError) {
48
-
if (err.kind === 'InvalidRequest' && err.description === 'Profile not found') {
49
-
return { data: null };
50
-
}
51
-
}
52
-
53
-
return Promise.reject(err);
54
-
});
55
-
56
-
return { profile: profile, allowUnauthenticated };
57
-
};
58
-
59
-
export const renderProfileCard = (data: ProfileCardData): string => {
60
-
return render(BlueskyProfileCard, { props: data }).body;
61
-
};
-56
packages/bluesky-profile-card-embed/lib/wc.ts
-56
packages/bluesky-profile-card-embed/lib/wc.ts
···
1
-
import { fetchProfileCard, renderProfileCard } from './core';
2
-
3
-
export class BlueskyProfileCard extends HTMLElement {
4
-
connectedCallback() {
5
-
this.load().then(
6
-
() => this.dispatchEvent(new CustomEvent('loaded')),
7
-
(err) => {
8
-
const defaulted = this.dispatchEvent(new CustomEvent('error', { detail: err }));
9
-
if (defaulted) {
10
-
throw err;
11
-
}
12
-
},
13
-
);
14
-
}
15
-
16
-
async load() {
17
-
const actor = this.getAttribute('actor')!;
18
-
const serviceUri = this.getAttribute('service-uri') || undefined;
19
-
const allowUnauthenticated = this.getAttribute('allow-unauthenticated') !== null;
20
-
const silent = this.getAttribute('silent') !== null;
21
-
22
-
const data = await fetchProfileCard({ actor, allowUnauthenticated, serviceUri }).catch((error) => {
23
-
if (silent) {
24
-
console.warn('Failed to fetch profile card:', error);
25
-
return null;
26
-
}
27
-
throw error;
28
-
});
29
-
30
-
if (data === null) {
31
-
return;
32
-
}
33
-
34
-
const html = renderProfileCard(data);
35
-
36
-
const root = this.shadowRoot;
37
-
38
-
if (!root) {
39
-
this.innerHTML = html;
40
-
} else {
41
-
const template = document.createElement('template');
42
-
template.innerHTML = html;
43
-
44
-
const fragment = template.content;
45
-
const slot = root.querySelector('slot');
46
-
47
-
if (slot) {
48
-
slot.replaceWith(fragment);
49
-
} else {
50
-
root.appendChild(fragment);
51
-
}
52
-
}
53
-
}
54
-
}
55
-
56
-
customElements.define('bluesky-profile-card', BlueskyProfileCard);
-45
packages/bluesky-profile-card-embed/package.json
-45
packages/bluesky-profile-card-embed/package.json
···
1
-
{
2
-
"type": "module",
3
-
"name": "bluesky-profile-card-embed",
4
-
"description": "Custom element for embedding Bluesky profile cards",
5
-
"version": "1.0.1",
6
-
"author": "externdefs",
7
-
"license": "MIT",
8
-
"repository": {
9
-
"type": "git",
10
-
"url": "https://github.com/mary-ext/bluesky-embed",
11
-
"directory": "packages/bluesky-profile-card-embed"
12
-
},
13
-
"files": [
14
-
"dist/",
15
-
"themes/"
16
-
],
17
-
"exports": {
18
-
".": "./dist/wc.js",
19
-
"./core": "./dist/core.js",
20
-
"./style.css": "./dist/core.css",
21
-
"./themes/*": "./themes/*"
22
-
},
23
-
"scripts": {
24
-
"dev": "vite",
25
-
"build": "pnpm run check && vite build && rsync -aHAX --delete ../../themes/ themes/",
26
-
"check": "svelte-check --tsconfig ./tsconfig.json && tsc -p tsconfig.node.json",
27
-
"prepack": "pnpm run build"
28
-
},
29
-
"dependencies": {
30
-
"@atcute/bluesky": "^2.1.1",
31
-
"@atcute/bluesky-richtext-parser": "^1.0.7",
32
-
"@atcute/client": "^3.1.0"
33
-
},
34
-
"devDependencies": {
35
-
"@preact/preset-vite": "^2.10.2",
36
-
"@tsconfig/svelte": "^5.0.6",
37
-
"@types/node": "^24.10.1",
38
-
"internal": "workspace:^",
39
-
"preact": "^10.28.0",
40
-
"svelte": "catalog:",
41
-
"svelte-check": "^4.3.4",
42
-
"vite": "^7.2.6",
43
-
"vite-plugin-dts": "^4.5.4"
44
-
}
45
-
}
-58
packages/bluesky-profile-card-embed/src/app.tsx
-58
packages/bluesky-profile-card-embed/src/app.tsx
···
1
-
import { useEffect, useMemo, useState } from 'preact/hooks';
2
-
3
-
import type { ProfileCardData } from 'internal/types/profile-card.js';
4
-
import { fetchProfileCard, renderProfileCard } from '../lib/core';
5
-
6
-
const actor = `patak.dev`;
7
-
8
-
const App = () => {
9
-
const [state, setState] = useState<{ actor: string; data: ProfileCardData }>();
10
-
11
-
useEffect(() => {
12
-
if (state && state.actor === actor) {
13
-
return;
14
-
}
15
-
16
-
const controller = new AbortController();
17
-
const promise = fetchProfileCard({
18
-
actor: actor,
19
-
signal: controller.signal,
20
-
allowUnauthenticated: true,
21
-
});
22
-
23
-
promise.then((data) => {
24
-
setState({ actor, data });
25
-
});
26
-
27
-
return () => {
28
-
controller.abort();
29
-
};
30
-
}, [actor]);
31
-
32
-
return <div class="app">{state && <BlueskyProfileCard data={state.data} />}</div>;
33
-
};
34
-
35
-
export default App;
36
-
37
-
const BlueskyProfileCard = ({ data }: { data: ProfileCardData }) => {
38
-
const html = useMemo(() => renderProfileCard(data), [data, renderProfileCard]);
39
-
40
-
return (
41
-
<bluesky-profile-card
42
-
actor={data.profile?.did}
43
-
dangerouslySetInnerHTML={{ __html: html }}
44
-
></bluesky-profile-card>
45
-
);
46
-
};
47
-
48
-
declare module 'preact' {
49
-
namespace JSX {
50
-
interface BlueskyProfileCardAttributes extends HTMLAttributes<HTMLElement> {
51
-
actor?: string;
52
-
}
53
-
54
-
interface IntrinsicElements {
55
-
'bluesky-profile-card': BlueskyProfileCardAttributes;
56
-
}
57
-
}
58
-
}
-8
packages/bluesky-profile-card-embed/src/main.tsx
-8
packages/bluesky-profile-card-embed/src/main.tsx
-8
packages/bluesky-profile-card-embed/src/styles/main.css
-8
packages/bluesky-profile-card-embed/src/styles/main.css
-199
packages/bluesky-profile-card-embed/src/styles/normalize.css
-199
packages/bluesky-profile-card-embed/src/styles/normalize.css
···
1
-
/*! modern-normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize */
2
-
3
-
/*
4
-
Document
5
-
========
6
-
*/
7
-
8
-
/**
9
-
Use a better box model (opinionated).
10
-
*/
11
-
12
-
*,
13
-
::before,
14
-
::after {
15
-
box-sizing: border-box;
16
-
}
17
-
18
-
html {
19
-
line-height: 1.15; /* 1. Correct the line height in all browsers. */
20
-
/* Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) */
21
-
font-family: 'Inter', 'Roboto', ui-sans-serif, sans-serif, 'Noto Color Emoji', 'Twemoji Mozilla';
22
-
-webkit-text-size-adjust: 100%; /* 2. Prevent adjustments of font size after orientation changes in iOS. */
23
-
tab-size: 4; /* 3. Use a more readable tab size (opinionated). */
24
-
}
25
-
26
-
/*
27
-
Sections
28
-
========
29
-
*/
30
-
31
-
body {
32
-
margin: 0; /* Remove the margin in all browsers. */
33
-
}
34
-
35
-
/*
36
-
Text-level semantics
37
-
====================
38
-
*/
39
-
40
-
/**
41
-
Add the correct font weight in Chrome and Safari.
42
-
*/
43
-
44
-
b,
45
-
strong {
46
-
font-weight: bolder;
47
-
}
48
-
49
-
/**
50
-
1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
51
-
2. Correct the odd 'em' font sizing in all browsers.
52
-
*/
53
-
54
-
code,
55
-
kbd,
56
-
samp,
57
-
pre {
58
-
font-size: 1em; /* 2 */
59
-
font-family: 'JetBrains Mono NL', ui-monospace, monospace; /* 1 */
60
-
}
61
-
62
-
/**
63
-
Add the correct font size in all browsers.
64
-
*/
65
-
66
-
small {
67
-
font-size: 80%;
68
-
}
69
-
70
-
/**
71
-
Prevent 'sub' and 'sup' elements from affecting the line height in all browsers.
72
-
*/
73
-
74
-
sub,
75
-
sup {
76
-
position: relative;
77
-
vertical-align: baseline;
78
-
font-size: 75%;
79
-
line-height: 0;
80
-
}
81
-
82
-
sub {
83
-
bottom: -0.25em;
84
-
}
85
-
86
-
sup {
87
-
top: -0.5em;
88
-
}
89
-
90
-
/*
91
-
Tabular data
92
-
============
93
-
*/
94
-
95
-
/**
96
-
Correct table border color inheritance in Chrome and Safari. (https://issues.chromium.org/issues/40615503, https://bugs.webkit.org/show_bug.cgi?id=195016)
97
-
*/
98
-
99
-
table {
100
-
border-color: currentcolor;
101
-
}
102
-
103
-
/*
104
-
Forms
105
-
=====
106
-
*/
107
-
108
-
/**
109
-
1. Change the font styles in all browsers.
110
-
2. Remove the margin in Firefox and Safari.
111
-
*/
112
-
113
-
button,
114
-
input,
115
-
optgroup,
116
-
select,
117
-
textarea {
118
-
margin: 0; /* 2 */
119
-
font-size: 100%; /* 1 */
120
-
line-height: 1.15; /* 1 */
121
-
font-family: inherit; /* 1 */
122
-
}
123
-
124
-
/**
125
-
Correct the inability to style clickable types in iOS and Safari.
126
-
*/
127
-
128
-
button,
129
-
[type='button'],
130
-
[type='reset'],
131
-
[type='submit'] {
132
-
-webkit-appearance: button;
133
-
}
134
-
135
-
/**
136
-
Remove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.
137
-
*/
138
-
139
-
legend {
140
-
padding: 0;
141
-
}
142
-
143
-
/**
144
-
Add the correct vertical alignment in Chrome and Firefox.
145
-
*/
146
-
147
-
progress {
148
-
vertical-align: baseline;
149
-
}
150
-
151
-
/**
152
-
Correct the cursor style of increment and decrement buttons in Safari.
153
-
*/
154
-
155
-
::-webkit-inner-spin-button,
156
-
::-webkit-outer-spin-button {
157
-
height: auto;
158
-
}
159
-
160
-
/**
161
-
1. Correct the odd appearance in Chrome and Safari.
162
-
2. Correct the outline style in Safari.
163
-
*/
164
-
165
-
[type='search'] {
166
-
-webkit-appearance: textfield; /* 1 */
167
-
outline-offset: -2px; /* 2 */
168
-
}
169
-
170
-
/**
171
-
Remove the inner padding in Chrome and Safari on macOS.
172
-
*/
173
-
174
-
::-webkit-search-decoration {
175
-
-webkit-appearance: none;
176
-
}
177
-
178
-
/**
179
-
1. Correct the inability to style clickable types in iOS and Safari.
180
-
2. Change font properties to 'inherit' in Safari.
181
-
*/
182
-
183
-
::-webkit-file-upload-button {
184
-
-webkit-appearance: button; /* 1 */
185
-
font: inherit; /* 2 */
186
-
}
187
-
188
-
/*
189
-
Interactive
190
-
===========
191
-
*/
192
-
193
-
/*
194
-
Add the correct display in Chrome and Safari.
195
-
*/
196
-
197
-
summary {
198
-
display: list-item;
199
-
}
-8
packages/bluesky-profile-card-embed/svelte.config.js
-8
packages/bluesky-profile-card-embed/svelte.config.js
-14
packages/bluesky-profile-card-embed/tsconfig.build.json
-14
packages/bluesky-profile-card-embed/tsconfig.build.json
···
1
-
{
2
-
"extends": "@tsconfig/svelte/tsconfig.json",
3
-
"compilerOptions": {
4
-
"types": [],
5
-
"target": "ESNext",
6
-
"useDefineForClassFields": true,
7
-
"module": "ESNext",
8
-
"resolveJsonModule": true,
9
-
"isolatedModules": true,
10
-
"moduleDetection": "force",
11
-
"noEmit": true,
12
-
},
13
-
"include": ["lib"],
14
-
}
-17
packages/bluesky-profile-card-embed/tsconfig.json
-17
packages/bluesky-profile-card-embed/tsconfig.json
···
1
-
{
2
-
"extends": "@tsconfig/svelte/tsconfig.json",
3
-
"compilerOptions": {
4
-
"types": [],
5
-
"target": "ESNext",
6
-
"useDefineForClassFields": true,
7
-
"module": "ESNext",
8
-
"resolveJsonModule": true,
9
-
"isolatedModules": true,
10
-
"moduleDetection": "force",
11
-
"noEmit": true,
12
-
"jsx": "react-jsx",
13
-
"jsxImportSource": "preact",
14
-
},
15
-
"include": ["lib", "src"],
16
-
"references": [{ "path": "./tsconfig.node.json" }],
17
-
}
-14
packages/bluesky-profile-card-embed/tsconfig.node.json
-14
packages/bluesky-profile-card-embed/tsconfig.node.json
···
1
-
{
2
-
"compilerOptions": {
3
-
"composite": true,
4
-
"types": ["node"],
5
-
"skipLibCheck": true,
6
-
"module": "ESNext",
7
-
"target": "ESNext",
8
-
"moduleResolution": "Bundler",
9
-
"strict": true,
10
-
"noEmit": true,
11
-
"noUncheckedSideEffectImports": true,
12
-
},
13
-
"include": ["vite.config.ts"],
14
-
}
-103
packages/bluesky-profile-card-embed/vite.config.ts
-103
packages/bluesky-profile-card-embed/vite.config.ts
···
1
-
import * as path from 'node:path';
2
-
3
-
import { compile as compileSvelte } from 'svelte/compiler';
4
-
import { type Plugin, createFilter, defineConfig } from 'vite';
5
-
6
-
import preact from '@preact/preset-vite';
7
-
import dts from 'vite-plugin-dts';
8
-
9
-
export default defineConfig({
10
-
base: './',
11
-
build: {
12
-
outDir: 'dist/',
13
-
target: 'esnext',
14
-
minify: false,
15
-
cssMinify: false,
16
-
cssCodeSplit: true,
17
-
lib: {
18
-
entry: {
19
-
core: 'lib/core.ts',
20
-
wc: 'lib/wc.ts',
21
-
},
22
-
formats: ['es'],
23
-
},
24
-
rollupOptions: {
25
-
external: ['@atcute/client', '@atcute/bluesky-richtext-parser'],
26
-
},
27
-
},
28
-
esbuild: {
29
-
target: 'esnext',
30
-
},
31
-
plugins: [
32
-
svelte(),
33
-
preact(),
34
-
dts({
35
-
rollupTypes: true,
36
-
tsconfigPath: 'tsconfig.build.json',
37
-
beforeWriteFile(filePath, content) {
38
-
if (filePath.endsWith('/core.d.ts')) {
39
-
// Make sure the relevant types are present
40
-
return { content: `import '@atcute/bluesky/lexicons';\n${content}` };
41
-
}
42
-
},
43
-
}),
44
-
],
45
-
});
46
-
47
-
function svelte(): Plugin {
48
-
const filter = createFilter('**/*.svelte');
49
-
const stylesheets = new Map<string, string>();
50
-
51
-
return {
52
-
name: 'svelte',
53
-
resolveId(id) {
54
-
return stylesheets.has(id) ? id : null;
55
-
},
56
-
load(id) {
57
-
const css = stylesheets.get(id);
58
-
if (css !== undefined) {
59
-
this.addWatchFile(id.slice(0, -4));
60
-
return { code: css };
61
-
}
62
-
63
-
return null;
64
-
},
65
-
transform(source, id) {
66
-
if (!filter(id)) {
67
-
return null;
68
-
}
69
-
70
-
const result = compileSvelte(source, {
71
-
generate: 'server',
72
-
css: 'external',
73
-
cssHash({ hash, filename }) {
74
-
const prefix = `github:mary-ext/bluesky-profile-card-embed/`;
75
-
return `s-` + hash(prefix + path.relative(__dirname, filename));
76
-
},
77
-
runes: true,
78
-
filename: id,
79
-
});
80
-
81
-
{
82
-
const { js, css, warnings } = result;
83
-
84
-
let jsCode = js.code;
85
-
86
-
if (css) {
87
-
const cssId = `${id}.css`;
88
-
jsCode = jsCode + `\nimport ${JSON.stringify(cssId)};\n`;
89
-
stylesheets.set(cssId, css.code);
90
-
}
91
-
92
-
for (const warn of warnings) {
93
-
if (warn.code === 'state_referenced_locally') {
94
-
continue;
95
-
}
96
-
this.warn(warn);
97
-
}
98
-
99
-
return { code: jsCode };
100
-
}
101
-
},
102
-
};
103
-
}
-1
packages/bluesky-profile-feed-embed/.gitignore
-1
packages/bluesky-profile-feed-embed/.gitignore
···
1
-
themes/
-84
packages/bluesky-profile-feed-embed/README.md
-84
packages/bluesky-profile-feed-embed/README.md
···
1
-
# <bluesky-profile-feed-embed>
2
-
3
-
A custom element for embedding Bluesky profile feeds.
4
-
5
-
## Installation
6
-
7
-
### via npm
8
-
9
-
```
10
-
npm install bluesky-profile-feed-embed
11
-
```
12
-
13
-
then, import the package on your app.
14
-
15
-
```js
16
-
import 'bluesky-profile-feed-embed';
17
-
18
-
import 'bluesky-profile-feed-embed/style.css';
19
-
import 'bluesky-profile-feed-embed/themes/light.css';
20
-
```
21
-
22
-
## Usage
23
-
24
-
```html
25
-
<bluesky-profile-feed actor="did:plc:ragtjsm2j2vknwkz3zp4oxrd" include-pins>
26
-
<a
27
-
target="_blank"
28
-
href="https://bsky.app/profile/did:plc:ragtjsm2j2vknwkz3zp4oxrd"
29
-
class="bluesky-profile-feed-fallback"
30
-
>
31
-
Posts by Paul Frazee (@pfrazee.com)
32
-
</a>
33
-
</bluesky-profile-feed>
34
-
```
35
-
36
-
### Attributes
37
-
38
-
- `actor` **Required**
39
-
DID or handle of the account
40
-
- `include-pins` **Optional**
41
-
Whether to show pinned posts
42
-
- `allow-unauthenticated` **Optional**
43
-
Whether to allow unauthenticated viewing
44
-
- `service-uri` **Optional**
45
-
URL to an AppView service, defaults to `https://public.api.bsky.app`
46
-
47
-
### Events
48
-
49
-
- `loaded`
50
-
Fired when the embed has successfully loaded the post
51
-
- `error`
52
-
Fired when the embed fails to load the post
53
-
54
-
## SSR usage
55
-
56
-
The embeds are powered by a static HTML renderer, this renderer can be used directly in your
57
-
server-rendering framework of choice for a zero-JS experience.
58
-
59
-
```tsx
60
-
import { fetchProfileFeed, renderProfileFeed } from 'bluesky-profile-feed-embed/core';
61
-
62
-
import 'bluesky-post-embed/style.css';
63
-
import 'bluesky-post-embed/themes/light.css';
64
-
65
-
// fetch the profile
66
-
const controller = new AbortController();
67
-
const data = await fetchProfileFeed({
68
-
actor: `did:plc:ragtjsm2j2vknwkz3zp4oxrd`,
69
-
includePins: true,
70
-
signal: controller.signal,
71
-
});
72
-
73
-
// render the profile
74
-
const html = renderProfileFeed(data);
75
-
return (
76
-
<bluesky-profile-feed
77
-
src={data.thread?.post.uri}
78
-
dangerouslySetInnerHTML={{ __html: html }}
79
-
></bluesky-profile-feed>
80
-
);
81
-
```
82
-
83
-
Check out examples for [Astro](https://github.com/mary-ext/bluesky-embed-astro) and
84
-
[SvelteKit](https://github.com/mary-ext/bluesky-embed-sveltekit).
-100
packages/bluesky-profile-feed-embed/lib/bluesky-profile-feed.svelte
-100
packages/bluesky-profile-feed-embed/lib/bluesky-profile-feed.svelte
···
1
-
<script lang="ts">
2
-
import EmbedFrame from 'internal/components/embed-frame.svelte';
3
-
import FeedPost from 'internal/components/feed-post.svelte';
4
-
import ProfileFeedHeader from 'internal/components/profile-feed-header.svelte';
5
-
6
-
import type { ProfileFeedData } from 'internal/types/profile-feed.js';
7
-
import { NO_UNAUTHENTICATED_LABEL } from 'internal/utils/constants.js';
8
-
9
-
const { profile, feed, allowUnauthenticated }: ProfileFeedData = $props();
10
-
11
-
const isPwiForbidden =
12
-
!allowUnauthenticated && profile?.labels?.some((label) => label.val === NO_UNAUTHENTICATED_LABEL);
13
-
14
-
const items = feed.filter((item) => {
15
-
if (!profile) {
16
-
return false;
17
-
}
18
-
19
-
const reason = item.reason;
20
-
if (reason) {
21
-
if (reason.$type === 'app.bsky.feed.defs#reasonPin') {
22
-
return true;
23
-
}
24
-
25
-
if (reason.$type === 'app.bsky.feed.defs#reasonRepost') {
26
-
const author = item.post.author;
27
-
28
-
if (author.did !== profile.did) {
29
-
return (
30
-
allowUnauthenticated || !author.labels?.some((label) => label.val === NO_UNAUTHENTICATED_LABEL)
31
-
);
32
-
}
33
-
34
-
return true;
35
-
}
36
-
37
-
// Don't show anything we don't recognize
38
-
return false;
39
-
}
40
-
41
-
return !item.reply;
42
-
});
43
-
</script>
44
-
45
-
{#if profile === null}
46
-
{@render Message(`The profile can't be found, it may have been deleted.`)}
47
-
{:else if isPwiForbidden}
48
-
{@render Message(`The user has requested for their posts to not be displayed on external sites.`)}
49
-
{:else}
50
-
<EmbedFrame>
51
-
<ProfileFeedHeader {profile} />
52
-
53
-
{#if items.length > 0}
54
-
<div class="feed">
55
-
{#each items as item}
56
-
<FeedPost {item} />
57
-
{/each}
58
-
59
-
<div class="end-marker">
60
-
<div class="dot"></div>
61
-
</div>
62
-
</div>
63
-
{:else}
64
-
<div class="message">This user has not made any posts.</div>
65
-
{/if}
66
-
</EmbedFrame>
67
-
{/if}
68
-
69
-
{#snippet Message(msg: string)}
70
-
<EmbedFrame>
71
-
<div class="message">{msg}</div>
72
-
</EmbedFrame>
73
-
{/snippet}
74
-
75
-
<style>
76
-
.message {
77
-
margin: 0 auto;
78
-
padding: 32px 16px;
79
-
max-width: 380px;
80
-
color: var(--text-secondary);
81
-
text-align: center;
82
-
}
83
-
84
-
.feed {
85
-
max-height: var(--max-feed-height);
86
-
overflow-y: auto;
87
-
}
88
-
.end-marker {
89
-
display: grid;
90
-
place-items: center;
91
-
height: 48px;
92
-
93
-
.dot {
94
-
border-radius: 50%;
95
-
background: var(--text-secondary);
96
-
width: 4px;
97
-
height: 4px;
98
-
}
99
-
}
100
-
</style>
-87
packages/bluesky-profile-feed-embed/lib/core.ts
-87
packages/bluesky-profile-feed-embed/lib/core.ts
···
1
-
import '@atcute/bluesky/lexicons';
2
-
3
-
import { simpleFetchHandler, XRPC, XRPCError } from '@atcute/client';
4
-
import type { At } from '@atcute/client/lexicons';
5
-
import { render } from 'svelte/server';
6
-
7
-
import type { ProfileFeedData } from 'internal/types/profile-feed.js';
8
-
import { DEFAULT_APPVIEW_URL } from 'internal/utils/constants.js';
9
-
10
-
import BlueskyProfileFeed from './bluesky-profile-feed.svelte';
11
-
12
-
export type { ProfileFeedData };
13
-
14
-
export interface ProfileFeedFetchOptions {
15
-
/**
16
-
* Handle or DID identifier of the user
17
-
*/
18
-
actor: string;
19
-
/**
20
-
* Abort signal to cancel the request
21
-
*/
22
-
signal?: AbortSignal;
23
-
/**
24
-
* Include pinned posts
25
-
* @default false
26
-
*/
27
-
includePins?: boolean;
28
-
/**
29
-
* Allow unauthenticated viewing
30
-
* @default false
31
-
*/
32
-
allowUnauthenticated?: boolean;
33
-
/**
34
-
* AppView service to use
35
-
* @default "https://public.api.bsky.app"
36
-
*/
37
-
serviceUri?: string;
38
-
}
39
-
40
-
export const fetchProfileFeed = async (opts: ProfileFeedFetchOptions): Promise<ProfileFeedData> => {
41
-
const actor = opts.actor as At.Identifier;
42
-
const allowUnauthenticated = opts.allowUnauthenticated ?? false;
43
-
44
-
const rpc = new XRPC({ handler: simpleFetchHandler({ service: opts.serviceUri ?? DEFAULT_APPVIEW_URL }) });
45
-
46
-
const [{ data: profile }, { data: timeline }] = await Promise.all([
47
-
rpc
48
-
.get('app.bsky.actor.getProfile', {
49
-
signal: opts.signal,
50
-
params: { actor: actor as At.Identifier },
51
-
})
52
-
.catch((err) => {
53
-
if (err instanceof XRPCError) {
54
-
if (err.kind === 'InvalidRequest' && err.description === 'Profile not found') {
55
-
return { data: null };
56
-
}
57
-
}
58
-
59
-
return Promise.reject(err);
60
-
}),
61
-
rpc
62
-
.get('app.bsky.feed.getAuthorFeed', {
63
-
signal: opts.signal,
64
-
params: {
65
-
actor,
66
-
filter: 'posts_no_replies',
67
-
includePins: opts.includePins,
68
-
limit: 30,
69
-
},
70
-
})
71
-
.catch((err) => {
72
-
if (err instanceof XRPCError) {
73
-
if (err.kind === 'InvalidRequest' && err.description === 'Profile not found') {
74
-
return { data: { feed: [] } };
75
-
}
76
-
}
77
-
78
-
return Promise.reject(err);
79
-
}),
80
-
]);
81
-
82
-
return { profile: profile, feed: timeline.feed, allowUnauthenticated };
83
-
};
84
-
85
-
export const renderProfileFeed = (data: ProfileFeedData): string => {
86
-
return render(BlueskyProfileFeed, { props: data }).body;
87
-
};
-59
packages/bluesky-profile-feed-embed/lib/wc.ts
-59
packages/bluesky-profile-feed-embed/lib/wc.ts
···
1
-
import { fetchProfileFeed, renderProfileFeed } from './core';
2
-
3
-
export class BlueskyProfileFeed extends HTMLElement {
4
-
connectedCallback() {
5
-
this.load().then(
6
-
() => this.dispatchEvent(new CustomEvent('loaded')),
7
-
(err) => {
8
-
const defaulted = this.dispatchEvent(new CustomEvent('error', { detail: err }));
9
-
if (defaulted) {
10
-
throw err;
11
-
}
12
-
},
13
-
);
14
-
}
15
-
16
-
async load() {
17
-
const actor = this.getAttribute('actor')!;
18
-
const serviceUri = this.getAttribute('service-uri') || undefined;
19
-
const allowUnauthenticated = this.getAttribute('allow-unauthenticated') !== null;
20
-
const includePins = this.getAttribute('include-pins') !== null;
21
-
const silent = this.getAttribute('silent') !== null;
22
-
23
-
const data = await fetchProfileFeed({ actor, allowUnauthenticated, includePins, serviceUri }).catch(
24
-
(error) => {
25
-
if (silent) {
26
-
console.warn('Failed to fetch profile feed:', error);
27
-
return null;
28
-
}
29
-
throw error;
30
-
},
31
-
);
32
-
33
-
if (data === null) {
34
-
return;
35
-
}
36
-
37
-
const html = renderProfileFeed(data);
38
-
39
-
const root = this.shadowRoot;
40
-
41
-
if (!root) {
42
-
this.innerHTML = html;
43
-
} else {
44
-
const template = document.createElement('template');
45
-
template.innerHTML = html;
46
-
47
-
const fragment = template.content;
48
-
const slot = root.querySelector('slot');
49
-
50
-
if (slot) {
51
-
slot.replaceWith(fragment);
52
-
} else {
53
-
root.appendChild(fragment);
54
-
}
55
-
}
56
-
}
57
-
}
58
-
59
-
customElements.define('bluesky-profile-feed', BlueskyProfileFeed);
-43
packages/bluesky-profile-feed-embed/package.json
-43
packages/bluesky-profile-feed-embed/package.json
···
1
-
{
2
-
"type": "module",
3
-
"name": "bluesky-profile-feed-embed",
4
-
"description": "Custom element for embedding Bluesky profile feeds",
5
-
"version": "1.0.4",
6
-
"author": "externdefs",
7
-
"license": "MIT",
8
-
"repository": {
9
-
"type": "git",
10
-
"url": "https://github.com/mary-ext/bluesky-embed",
11
-
"directory": "packages/bluesky-profile-feed-embed"
12
-
},
13
-
"files": [
14
-
"dist/",
15
-
"themes/"
16
-
],
17
-
"exports": {
18
-
".": "./dist/wc.js",
19
-
"./core": "./dist/core.js",
20
-
"./style.css": "./dist/core.css",
21
-
"./themes/*": "./themes/*"
22
-
},
23
-
"scripts": {
24
-
"dev": "vite",
25
-
"build": "pnpm run check && vite build && rsync -aHAX --delete ../../themes/ themes/",
26
-
"check": "svelte-check --tsconfig ./tsconfig.json && tsc -p tsconfig.node.json",
27
-
"prepack": "pnpm run build"
28
-
},
29
-
"dependencies": {
30
-
"@atcute/bluesky": "^2.1.1",
31
-
"@atcute/bluesky-richtext-segmenter": "^2.0.4",
32
-
"@atcute/client": "^3.1.0"
33
-
},
34
-
"devDependencies": {
35
-
"@tsconfig/svelte": "^5.0.6",
36
-
"@types/node": "^24.10.1",
37
-
"internal": "workspace:^",
38
-
"svelte": "catalog:",
39
-
"svelte-check": "^4.3.4",
40
-
"vite": "^7.2.6",
41
-
"vite-plugin-dts": "^4.5.4"
42
-
}
43
-
}
-8
packages/bluesky-profile-feed-embed/svelte.config.js
-8
packages/bluesky-profile-feed-embed/svelte.config.js
-15
packages/bluesky-profile-feed-embed/tsconfig.json
-15
packages/bluesky-profile-feed-embed/tsconfig.json
···
1
-
{
2
-
"extends": "@tsconfig/svelte/tsconfig.json",
3
-
"compilerOptions": {
4
-
"types": [],
5
-
"target": "ESNext",
6
-
"useDefineForClassFields": true,
7
-
"module": "ESNext",
8
-
"resolveJsonModule": true,
9
-
"isolatedModules": true,
10
-
"moduleDetection": "force",
11
-
"noEmit": true,
12
-
},
13
-
"include": ["lib"],
14
-
"references": [{ "path": "./tsconfig.node.json" }],
15
-
}
-14
packages/bluesky-profile-feed-embed/tsconfig.node.json
-14
packages/bluesky-profile-feed-embed/tsconfig.node.json
···
1
-
{
2
-
"compilerOptions": {
3
-
"composite": true,
4
-
"types": ["node"],
5
-
"skipLibCheck": true,
6
-
"module": "ESNext",
7
-
"target": "ESNext",
8
-
"moduleResolution": "Bundler",
9
-
"strict": true,
10
-
"noEmit": true,
11
-
"noUncheckedSideEffectImports": true,
12
-
},
13
-
"include": ["vite.config.ts"],
14
-
}
-100
packages/bluesky-profile-feed-embed/vite.config.ts
-100
packages/bluesky-profile-feed-embed/vite.config.ts
···
1
-
import * as path from 'node:path';
2
-
3
-
import { compile as compileSvelte } from 'svelte/compiler';
4
-
import { type Plugin, createFilter, defineConfig } from 'vite';
5
-
6
-
import dts from 'vite-plugin-dts';
7
-
8
-
export default defineConfig({
9
-
base: './',
10
-
build: {
11
-
outDir: 'dist/',
12
-
target: 'esnext',
13
-
minify: false,
14
-
cssMinify: false,
15
-
cssCodeSplit: true,
16
-
lib: {
17
-
entry: {
18
-
core: 'lib/core.ts',
19
-
wc: 'lib/wc.ts',
20
-
},
21
-
formats: ['es'],
22
-
},
23
-
rollupOptions: {
24
-
external: ['@atcute/client', '@atcute/bluesky-richtext-segmenter'],
25
-
},
26
-
},
27
-
esbuild: {
28
-
target: 'esnext',
29
-
},
30
-
plugins: [
31
-
svelte(),
32
-
dts({
33
-
rollupTypes: true,
34
-
beforeWriteFile(filePath, content) {
35
-
if (filePath.endsWith('/core.d.ts')) {
36
-
// Make sure the relevant types are present
37
-
return { content: `import '@atcute/bluesky/lexicons';\n${content}` };
38
-
}
39
-
},
40
-
}),
41
-
],
42
-
});
43
-
44
-
function svelte(): Plugin {
45
-
const filter = createFilter('**/*.svelte');
46
-
const stylesheets = new Map<string, string>();
47
-
48
-
return {
49
-
name: 'svelte',
50
-
resolveId(id) {
51
-
return stylesheets.has(id) ? id : null;
52
-
},
53
-
load(id) {
54
-
const css = stylesheets.get(id);
55
-
if (css !== undefined) {
56
-
this.addWatchFile(id.slice(0, -4));
57
-
return { code: css };
58
-
}
59
-
60
-
return null;
61
-
},
62
-
transform(source, id) {
63
-
if (!filter(id)) {
64
-
return null;
65
-
}
66
-
67
-
const result = compileSvelte(source, {
68
-
generate: 'server',
69
-
css: 'external',
70
-
cssHash({ hash, filename }) {
71
-
const prefix = `github:mary-ext/bluesky-profile-feed-embed/`;
72
-
return `s-` + hash(prefix + path.relative(__dirname, filename));
73
-
},
74
-
runes: true,
75
-
filename: id,
76
-
});
77
-
78
-
{
79
-
const { js, css, warnings } = result;
80
-
81
-
let jsCode = js.code;
82
-
83
-
if (css) {
84
-
const cssId = `${id}.css`;
85
-
jsCode = jsCode + `\nimport ${JSON.stringify(cssId)};\n`;
86
-
stylesheets.set(cssId, css.code);
87
-
}
88
-
89
-
for (const warn of warnings) {
90
-
if (warn.code === 'state_referenced_locally') {
91
-
continue;
92
-
}
93
-
this.warn(warn);
94
-
}
95
-
96
-
return { code: jsCode };
97
-
}
98
-
},
99
-
};
100
-
}
-88
packages/internal/components/content-hider.svelte
-88
packages/internal/components/content-hider.svelte
···
1
-
<script lang="ts">
2
-
import type { Snippet } from 'svelte';
3
-
import type { LabelDefinition } from '../utils/labels';
4
-
5
-
interface Props {
6
-
warning: LabelDefinition | undefined;
7
-
children: Snippet;
8
-
}
9
-
10
-
const { warning, children }: Props = $props();
11
-
</script>
12
-
13
-
{#if !warning}
14
-
{@render children()}
15
-
{:else}
16
-
<details class="content-hider">
17
-
<summary class="gate">
18
-
<svg class="icon" fill="none" viewBox="0 0 24 24">
19
-
<path
20
-
stroke="currentColor"
21
-
stroke-linecap="square"
22
-
stroke-width="2"
23
-
d="M11 11h1v5m9-4a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
24
-
/>
25
-
<path
26
-
fill="currentColor"
27
-
stroke="currentColor"
28
-
stroke-width=".5"
29
-
d="M11.5 7.25h-.25v1.5h1.5v-1.5H11.5Z"
30
-
/>
31
-
</svg>
32
-
33
-
<span class="label">{warning.name}</span>
34
-
35
-
<span class="action"></span>
36
-
</summary>
37
-
38
-
{@render children()}
39
-
</details>
40
-
{/if}
41
-
42
-
<style>
43
-
.gate {
44
-
display: flex;
45
-
align-items: center;
46
-
gap: 12px;
47
-
cursor: pointer;
48
-
border: 1px solid var(--divider);
49
-
border-radius: 6px;
50
-
padding: 0 12px;
51
-
height: 44px;
52
-
53
-
.content-hider[open] & {
54
-
margin-bottom: 12px;
55
-
}
56
-
57
-
&:hover {
58
-
border-color: var(--divider-hover);
59
-
}
60
-
}
61
-
62
-
.icon {
63
-
width: 18px;
64
-
height: 18px;
65
-
color: var(--text-secondary);
66
-
}
67
-
.label {
68
-
flex-grow: 1;
69
-
overflow: hidden;
70
-
font-weight: 500;
71
-
user-select: none;
72
-
text-overflow: ellipsis;
73
-
}
74
-
75
-
.action {
76
-
color: var(--text-link);
77
-
font-weight: 500;
78
-
font-size: calc(var(--font-size) * 0.8125);
79
-
line-height: calc(var(--font-size) * 1.25);
80
-
81
-
&::before {
82
-
content: 'Show';
83
-
}
84
-
.content-hider[open] &::before {
85
-
content: 'Hide';
86
-
}
87
-
}
88
-
</style>
-50
packages/internal/components/embed-frame.svelte
-50
packages/internal/components/embed-frame.svelte
···
1
-
<script lang="ts">
2
-
import type { Snippet } from 'svelte';
3
-
4
-
interface Props {
5
-
children: Snippet;
6
-
}
7
-
8
-
const { children }: Props = $props();
9
-
</script>
10
-
11
-
<div class="bluesky-embed">
12
-
{@render children()}
13
-
</div>
14
-
15
-
<style>
16
-
.bluesky-embed {
17
-
position: relative;
18
-
box-sizing: border-box;
19
-
margin: 0 auto;
20
-
border: 1px solid var(--divider);
21
-
border-radius: 8px;
22
-
background: var(--background-primary);
23
-
min-width: 250px;
24
-
max-width: 550px;
25
-
overflow: hidden;
26
-
color: var(--text-primary);
27
-
font-weight: 400;
28
-
font-size: calc(var(--font-size) * 0.875);
29
-
line-height: calc(var(--font-size) * 1.25);
30
-
font-family: var(--font-family);
31
-
32
-
:global(:where(*)),
33
-
:global(:where(*::before)),
34
-
:global(:where(*::after)) {
35
-
box-sizing: border-box;
36
-
margin: 0;
37
-
padding: 0;
38
-
}
39
-
:global(:where(a)) {
40
-
color: inherit;
41
-
text-decoration: none;
42
-
}
43
-
44
-
:global(:where(.icon)) {
45
-
flex-shrink: 0;
46
-
width: 1em;
47
-
height: 1em;
48
-
}
49
-
}
50
-
</style>
-126
packages/internal/components/embeds/embeds.svelte
-126
packages/internal/components/embeds/embeds.svelte
···
1
-
<script lang="ts" module>
2
-
const collectionToLabel = (collection: string): string | null => {
3
-
switch (collection) {
4
-
case 'app.bsky.feed.post':
5
-
return 'post';
6
-
case 'app.bsky.feed.generator':
7
-
return 'feed';
8
-
case 'app.bsky.graph.list':
9
-
return 'list';
10
-
case 'app.bsky.graph.starterpack':
11
-
return 'starter pack';
12
-
case 'app.bsky.labeler.service':
13
-
return 'labeler';
14
-
}
15
-
16
-
return null;
17
-
};
18
-
</script>
19
-
20
-
<script lang="ts">
21
-
import type {
22
-
AppBskyEmbedExternal,
23
-
AppBskyEmbedImages,
24
-
AppBskyEmbedRecord,
25
-
AppBskyEmbedVideo,
26
-
AppBskyFeedDefs,
27
-
Brand,
28
-
} from '@atcute/client/lexicons';
29
-
30
-
import { findLabel } from '../../utils/labels';
31
-
import { parseAtUri } from '../../utils/syntax/at-url';
32
-
33
-
import ContentHider from '../content-hider.svelte';
34
-
35
-
import ExternalEmbed from './external-embed.svelte';
36
-
import FeedEmbed from './feed-embed.svelte';
37
-
import ImageEmbed from './image-embed.svelte';
38
-
import ListEmbed from './list-embed.svelte';
39
-
import QuoteEmbed from './quote-embed.svelte';
40
-
import StarterpackEmbed from './starterpack-embed.svelte';
41
-
import VideoEmbed from './video-embed.svelte';
42
-
43
-
type Embed = NonNullable<AppBskyFeedDefs.PostView['embed']>;
44
-
type MediaEmbed = Brand.Union<AppBskyEmbedExternal.View | AppBskyEmbedImages.View | AppBskyEmbedVideo.View>;
45
-
type RecordEmbed = AppBskyEmbedRecord.View;
46
-
47
-
interface Props {
48
-
post?: AppBskyFeedDefs.PostView;
49
-
embed: Embed;
50
-
large?: boolean;
51
-
}
52
-
53
-
const { post, embed, large = false }: Props = $props();
54
-
</script>
55
-
56
-
<div class="embeds">
57
-
{#if embed.$type === 'app.bsky.embed.recordWithMedia#view'}
58
-
{@render Media(embed.media)}
59
-
{@render Record(embed.record)}
60
-
{:else if embed.$type === 'app.bsky.embed.record#view'}
61
-
{@render Record(embed)}
62
-
{:else}
63
-
{@render Media(embed)}
64
-
{/if}
65
-
</div>
66
-
67
-
{#snippet Media(embed: MediaEmbed)}
68
-
{@const warning = post && findLabel(post.labels, post.author.did)}
69
-
70
-
<ContentHider {warning}>
71
-
{#if embed.$type === 'app.bsky.embed.external#view'}
72
-
<ExternalEmbed {embed} />
73
-
{:else if embed.$type === 'app.bsky.embed.images#view'}
74
-
<ImageEmbed {embed} standalone />
75
-
{:else if embed.$type === 'app.bsky.embed.video#view'}
76
-
<VideoEmbed {post} {embed} standalone />
77
-
{:else}
78
-
{@render Message(`Unsupported media embed`)}
79
-
{/if}
80
-
</ContentHider>
81
-
{/snippet}
82
-
83
-
{#snippet Record(embed: RecordEmbed)}
84
-
{@const record = embed.record}
85
-
86
-
{#if record.$type === 'app.bsky.embed.record#viewRecord'}
87
-
<QuoteEmbed embed={record} {large} />
88
-
{:else if record.$type === 'app.bsky.feed.defs#generatorView'}
89
-
<FeedEmbed embed={record} />
90
-
{:else if record.$type === 'app.bsky.graph.defs#listView'}
91
-
<ListEmbed embed={record} />
92
-
{:else if record.$type === 'app.bsky.graph.defs#starterPackViewBasic'}
93
-
<StarterpackEmbed embed={record} {large} />
94
-
{:else}
95
-
{@const uri = parseAtUri(record.uri)}
96
-
{@const resource = collectionToLabel(uri.collection)}
97
-
98
-
{@const isUnavailable =
99
-
resource &&
100
-
(record.$type === 'app.bsky.embed.record#viewNotFound' ||
101
-
record.$type === 'app.bsky.embed.record#viewBlocked' ||
102
-
record.$type === 'app.bsky.embed.record#viewDetached')}
103
-
104
-
{@render Message(isUnavailable ? `This ${resource} is unavailable` : `Unsupported record embed`)}
105
-
{/if}
106
-
{/snippet}
107
-
108
-
{#snippet Message(message: string)}
109
-
<div class="message">{message}</div>
110
-
{/snippet}
111
-
112
-
<style>
113
-
.embeds {
114
-
display: flex;
115
-
flex-direction: column;
116
-
gap: 12px;
117
-
margin: 12px 0 0 0;
118
-
}
119
-
120
-
.message {
121
-
border: 1px solid var(--divider);
122
-
border-radius: 6px;
123
-
padding: 12px;
124
-
color: var(--text-secondary);
125
-
}
126
-
</style>
-129
packages/internal/components/embeds/external-embed.svelte
-129
packages/internal/components/embeds/external-embed.svelte
···
1
-
<script lang="ts" module>
2
-
const safeParseUrl = (str: string): URL | null => {
3
-
let url: URL | null | undefined;
4
-
if ('parse' in URL) {
5
-
url = URL.parse(str);
6
-
} else {
7
-
try {
8
-
// @ts-expect-error: `'parse' in URL` is giving truthy
9
-
url = new URL(str);
10
-
} catch {}
11
-
}
12
-
13
-
if (url && (url.protocol === 'https:' || url.protocol === 'http:')) {
14
-
return url;
15
-
}
16
-
17
-
return null;
18
-
};
19
-
</script>
20
-
21
-
<script lang="ts">
22
-
import type { AppBskyEmbedExternal } from '@atcute/client/lexicons';
23
-
24
-
interface Props {
25
-
embed: AppBskyEmbedExternal.View;
26
-
}
27
-
28
-
const { embed }: Props = $props();
29
-
30
-
const external = embed.external;
31
-
32
-
const domain = safeParseUrl(external.uri)?.host;
33
-
</script>
34
-
35
-
<a target="_blank" href={domain && external.uri} rel="noopener noreferrer nofollow" class="external-embed">
36
-
{#if external.thumb}
37
-
<img loading="lazy" src={external.thumb} alt="" class="thumbnail" />
38
-
{/if}
39
-
40
-
<div class="meta">
41
-
<p class="title">{external.title}</p>
42
-
<p class="description">{external.description}</p>
43
-
44
-
{#if domain}
45
-
<div class="domain">
46
-
<!-- earth -->
47
-
<svg class="icon" fill="none" viewBox="0 0 24 24">
48
-
<path
49
-
stroke="currentColor"
50
-
stroke-linecap="round"
51
-
stroke-width="2"
52
-
d="m4.172 8.07 3.94 2.957.977-1.941 3.887-.978 1.15-4.6M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-6.078 4.865.973-1.946-2.869-1.928-1.89-.12-1.08 1.075 1.947 2.919h2.919Z"
53
-
/>
54
-
</svg>
55
-
56
-
<span class="domain-name">{domain}</span>
57
-
</div>
58
-
{/if}
59
-
</div>
60
-
</a>
61
-
62
-
<style>
63
-
.external-embed {
64
-
display: block;
65
-
border: 1px solid var(--divider);
66
-
border-radius: 6px;
67
-
overflow: hidden;
68
-
69
-
&:hover {
70
-
border-color: var(--divider-hover);
71
-
}
72
-
}
73
-
74
-
.thumbnail {
75
-
display: block;
76
-
border-bottom: 1px solid var(--divider);
77
-
background: #000000;
78
-
aspect-ratio: 1.91;
79
-
width: 100%;
80
-
81
-
.external-embed:hover & {
82
-
border-color: var(--divider-hover);
83
-
}
84
-
}
85
-
86
-
.meta {
87
-
padding: 12px;
88
-
}
89
-
90
-
.title {
91
-
display: -webkit-box;
92
-
overflow: hidden;
93
-
font-weight: 700;
94
-
white-space: pre-wrap;
95
-
-webkit-box-orient: vertical;
96
-
-webkit-line-clamp: 2;
97
-
line-clamp: 2;
98
-
overflow-wrap: break-word;
99
-
100
-
&:empty {
101
-
display: none;
102
-
}
103
-
}
104
-
.description {
105
-
display: -webkit-box;
106
-
overflow: hidden;
107
-
color: var(--text-secondary);
108
-
font-size: calc(var(--font-size) * 0.8125);
109
-
white-space: pre-wrap;
110
-
-webkit-box-orient: vertical;
111
-
-webkit-line-clamp: 2;
112
-
line-clamp: 2;
113
-
overflow-wrap: break-word;
114
-
115
-
&:empty {
116
-
display: none;
117
-
}
118
-
}
119
-
120
-
.domain {
121
-
display: flex;
122
-
align-items: center;
123
-
gap: 6px;
124
-
margin: 6px 0 0 0;
125
-
color: var(--text-secondary);
126
-
font-weight: 500;
127
-
font-size: calc(var(--font-size) * 0.75);
128
-
}
129
-
</style>
-100
packages/internal/components/embeds/feed-embed.svelte
-100
packages/internal/components/embeds/feed-embed.svelte
···
1
-
<script lang="ts">
2
-
import type { AppBskyFeedDefs } from '@atcute/client/lexicons';
3
-
4
-
import { getFeedUrl } from '../../utils/bsky-url';
5
-
import { parseAtUri } from '../../utils/syntax/at-url';
6
-
7
-
interface Props {
8
-
embed: AppBskyFeedDefs.GeneratorView;
9
-
}
10
-
11
-
const { embed: feed }: Props = $props();
12
-
13
-
const creator = feed.creator;
14
-
15
-
const feedUrl = getFeedUrl(creator.did, parseAtUri(feed.uri).rkey);
16
-
</script>
17
-
18
-
<a target="_blank" href={feedUrl} class="feed-embed">
19
-
<div class="main">
20
-
<div class="avatar-wrapper">
21
-
{#if feed.avatar}
22
-
<img loading="lazy" src={feed.avatar} alt="" class="avatar" />
23
-
{:else}
24
-
<svg viewBox="0 0 32 32" class="avatar">
25
-
<path fill="#0070FF" d="M0 0h32v32H0z" />
26
-
<path
27
-
fill="#fff"
28
-
d="M22.153 22.354a9.328 9.328 0 0 0 3.837-.491 3.076 3.076 0 0 0-4.802-2.79m.965 3.281a6.128 6.128 0 0 0-.965-3.28Zm-11.342-3.28a3.077 3.077 0 0 0-4.801 2.79 9.21 9.21 0 0 0 3.835.49m.966-3.28a6.127 6.127 0 0 0-.966 3.28Zm8.265-8.997a3.076 3.076 0 1 1-6.153 0 3.076 3.076 0 0 1 6.153 0Zm6.154 3.077a2.307 2.307 0 1 1-4.615 0 2.307 2.307 0 0 1 4.615 0Zm-13.847 0a2.307 2.307 0 1 1-4.614 0 2.307 2.307 0 0 1 4.614 0Z"
29
-
/>
30
-
<path fill="#fff" d="M22 22c0 3.314-2.686 3.5-6 3.5s-6-.186-6-3.5a6 6 0 0 1 12 0Z" />
31
-
</svg>
32
-
{/if}
33
-
</div>
34
-
35
-
<div class="info">
36
-
<p class="name">{feed.displayName}</p>
37
-
<p class="creator">Feed by @{creator.handle}</p>
38
-
</div>
39
-
</div>
40
-
41
-
<p class="description">{feed.description}</p>
42
-
</a>
43
-
44
-
<style>
45
-
.feed-embed {
46
-
display: flex;
47
-
flex-direction: column;
48
-
gap: 12px;
49
-
border: 1px solid var(--divider);
50
-
border-radius: 6px;
51
-
padding: 12px;
52
-
53
-
&:hover {
54
-
border-color: var(--divider-hover);
55
-
}
56
-
}
57
-
58
-
.main {
59
-
display: flex;
60
-
gap: 12px;
61
-
}
62
-
63
-
.avatar-wrapper {
64
-
margin: 2px 0 0 0;
65
-
border-radius: 6px;
66
-
background: var(--background-secondary);
67
-
width: 36px;
68
-
height: 36px;
69
-
overflow: hidden;
70
-
}
71
-
.avatar {
72
-
width: 100%;
73
-
height: 100%;
74
-
object-fit: cover;
75
-
}
76
-
77
-
.name {
78
-
font-weight: 700;
79
-
}
80
-
81
-
.creator {
82
-
color: var(--text-secondary);
83
-
font-size: calc(var(--font-size) * 0.8125);
84
-
}
85
-
86
-
.description {
87
-
display: -webkit-box;
88
-
overflow: hidden;
89
-
font-size: calc(var(--font-size) * 0.8125);
90
-
white-space: pre-wrap;
91
-
-webkit-box-orient: vertical;
92
-
-webkit-line-clamp: 2;
93
-
line-clamp: 2;
94
-
overflow-wrap: break-word;
95
-
96
-
&:empty {
97
-
display: none;
98
-
}
99
-
}
100
-
</style>
-183
packages/internal/components/embeds/image-embed.svelte
-183
packages/internal/components/embeds/image-embed.svelte
···
1
-
<script lang="ts" module>
2
-
const DEFAULT_RATIO = { width: 16, height: 9 };
3
-
</script>
4
-
5
-
<script lang="ts">
6
-
import type { AppBskyEmbedImages } from '@atcute/client/lexicons';
7
-
8
-
interface Props {
9
-
embed: AppBskyEmbedImages.View;
10
-
borderless?: boolean;
11
-
standalone?: boolean;
12
-
blur?: boolean;
13
-
}
14
-
15
-
const { embed, borderless, standalone, blur }: Props = $props();
16
-
17
-
const images = embed.images;
18
-
const length = images.length;
19
-
</script>
20
-
21
-
<div
22
-
class={'image-embed' +
23
-
(!borderless ? ` is-bordered` : ``) +
24
-
(standalone && length === 1 ? ` is-aligned` : ``)}
25
-
>
26
-
{#if length === 4}
27
-
<div class="grid">
28
-
<div class="col">
29
-
<div class="item wide tl">
30
-
{@render Image(0)}
31
-
</div>
32
-
<div class="item wide bl">
33
-
{@render Image(2)}
34
-
</div>
35
-
</div>
36
-
<div class="col">
37
-
<div class="item wide tr">
38
-
{@render Image(1)}
39
-
</div>
40
-
<div class="item wide br">
41
-
{@render Image(3)}
42
-
</div>
43
-
</div>
44
-
</div>
45
-
{:else if length === 3}
46
-
<div class="grid">
47
-
<div class="col square">
48
-
<div class="item tl bl">
49
-
{@render Image(0)}
50
-
</div>
51
-
</div>
52
-
<div class="col square">
53
-
<div class="item tr">
54
-
{@render Image(1)}
55
-
</div>
56
-
<div class="item br">
57
-
{@render Image(2)}
58
-
</div>
59
-
</div>
60
-
</div>
61
-
{:else if length === 2}
62
-
<div class="grid">
63
-
<div class="col">
64
-
<div class="item square tl bl">
65
-
{@render Image(0)}
66
-
</div>
67
-
</div>
68
-
<div class="col">
69
-
<div class="item square tr br">
70
-
{@render Image(1)}
71
-
</div>
72
-
</div>
73
-
</div>
74
-
{:else if length === 1}
75
-
{@const ratio = standalone && (images[0].aspectRatio || DEFAULT_RATIO)}
76
-
77
-
<div
78
-
class={`single-item tl tr bl br` + (ratio ? ` is-standalone` : ``)}
79
-
style={ratio ? `aspect-ratio: ${ratio.width}/${ratio.height}` : ``}
80
-
>
81
-
{@render Image(0)}
82
-
83
-
{#if ratio}
84
-
<div class="placeholder"></div>
85
-
{/if}
86
-
</div>
87
-
{/if}
88
-
</div>
89
-
90
-
{#snippet Image(index: number)}
91
-
{@const image = images[index]}
92
-
93
-
<img loading="lazy" src={image.thumb} alt={image.alt} class={`image` + (blur ? ` is-blurred` : ``)} />
94
-
{/snippet}
95
-
96
-
<style>
97
-
.is-aligned {
98
-
align-self: baseline;
99
-
max-width: 100%;
100
-
}
101
-
102
-
.grid {
103
-
display: flex;
104
-
gap: 2px;
105
-
}
106
-
.col {
107
-
display: flex;
108
-
flex: 1;
109
-
flex-direction: column;
110
-
gap: 2px;
111
-
}
112
-
113
-
.square {
114
-
aspect-ratio: 1;
115
-
}
116
-
.wide {
117
-
aspect-ratio: 1.5;
118
-
}
119
-
120
-
.item {
121
-
position: relative;
122
-
flex-grow: 1;
123
-
flex-shrink: 0;
124
-
overflow: hidden;
125
-
}
126
-
127
-
.is-bordered {
128
-
.tl,
129
-
.tr,
130
-
.bl,
131
-
.br {
132
-
border: 1px solid var(--divider);
133
-
}
134
-
135
-
.tl {
136
-
border-top-left-radius: 6px;
137
-
}
138
-
.tr {
139
-
border-top-right-radius: 6px;
140
-
}
141
-
.bl {
142
-
border-bottom-left-radius: 6px;
143
-
}
144
-
.br {
145
-
border-bottom-right-radius: 6px;
146
-
}
147
-
}
148
-
149
-
.single-item {
150
-
position: relative;
151
-
aspect-ratio: 16 / 9;
152
-
overflow: hidden;
153
-
154
-
.image {
155
-
object-fit: contain;
156
-
}
157
-
}
158
-
.is-standalone {
159
-
min-width: 64px;
160
-
max-width: 100%;
161
-
min-height: 64px;
162
-
max-height: 320px;
163
-
}
164
-
165
-
.image {
166
-
position: absolute;
167
-
inset: 0;
168
-
background: #000000;
169
-
width: 100%;
170
-
height: 100%;
171
-
object-fit: cover;
172
-
font-size: 0px;
173
-
}
174
-
.is-blurred {
175
-
scale: 125%;
176
-
filter: blur(24px);
177
-
}
178
-
179
-
.placeholder {
180
-
width: 100vw;
181
-
height: 100vh;
182
-
}
183
-
</style>
-113
packages/internal/components/embeds/list-embed.svelte
-113
packages/internal/components/embeds/list-embed.svelte
···
1
-
<script lang="ts" module>
2
-
const getPurpose = (purpose: AppBskyGraphDefs.ListPurpose) => {
3
-
switch (purpose) {
4
-
case 'app.bsky.graph.defs#curatelist':
5
-
return `User list`;
6
-
case 'app.bsky.graph.defs#modlist':
7
-
return `Moderation list`;
8
-
}
9
-
10
-
return `Unknown list`;
11
-
};
12
-
</script>
13
-
14
-
<script lang="ts">
15
-
import type { AppBskyGraphDefs } from '@atcute/client/lexicons';
16
-
17
-
import { getFeedUrl } from '../../utils/bsky-url';
18
-
import { parseAtUri } from '../../utils/syntax/at-url';
19
-
20
-
interface Props {
21
-
embed: AppBskyGraphDefs.ListView;
22
-
}
23
-
24
-
const { embed: list }: Props = $props();
25
-
26
-
const creator = list.creator;
27
-
28
-
const listUrl = getFeedUrl(creator.did, parseAtUri(list.uri).rkey);
29
-
</script>
30
-
31
-
<a target="_blank" href={listUrl} class="list-embed">
32
-
<div class="main">
33
-
<div class="avatar-wrapper">
34
-
{#if list.avatar}
35
-
<img loading="lazy" src={list.avatar} alt="" class="avatar" />
36
-
{:else}
37
-
<svg viewBox="0 0 32 32" class="avatar">
38
-
<path fill="#0070FF" d="M0 0h32v32H0z" />
39
-
<path
40
-
fill="#fff"
41
-
d="M22.153 22.354a9.328 9.328 0 0 0 3.837-.491 3.076 3.076 0 0 0-4.802-2.79m.965 3.281a6.128 6.128 0 0 0-.965-3.28Zm-11.342-3.28a3.077 3.077 0 0 0-4.801 2.79 9.21 9.21 0 0 0 3.835.49m.966-3.28a6.127 6.127 0 0 0-.966 3.28Zm8.265-8.997a3.076 3.076 0 1 1-6.153 0 3.076 3.076 0 0 1 6.153 0Zm6.154 3.077a2.307 2.307 0 1 1-4.615 0 2.307 2.307 0 0 1 4.615 0Zm-13.847 0a2.307 2.307 0 1 1-4.614 0 2.307 2.307 0 0 1 4.614 0Z"
42
-
/>
43
-
<path fill="#fff" d="M22 22c0 3.314-2.686 3.5-6 3.5s-6-.186-6-3.5a6 6 0 0 1 12 0Z" />
44
-
</svg>
45
-
{/if}
46
-
</div>
47
-
48
-
<div class="info">
49
-
<p class="name">{list.name}</p>
50
-
<p class="creator">{getPurpose(list.purpose)} by @{creator.handle}</p>
51
-
</div>
52
-
</div>
53
-
54
-
<p class="description">{list.description}</p>
55
-
</a>
56
-
57
-
<style>
58
-
.list-embed {
59
-
display: flex;
60
-
flex-direction: column;
61
-
gap: 12px;
62
-
border: 1px solid var(--divider);
63
-
border-radius: 6px;
64
-
padding: 12px;
65
-
66
-
&:hover {
67
-
border-color: var(--divider-hover);
68
-
}
69
-
}
70
-
71
-
.main {
72
-
display: flex;
73
-
gap: 12px;
74
-
}
75
-
76
-
.avatar-wrapper {
77
-
margin: 2px 0 0 0;
78
-
border-radius: 6px;
79
-
background: var(--background-secondary);
80
-
width: 36px;
81
-
height: 36px;
82
-
overflow: hidden;
83
-
}
84
-
.avatar {
85
-
width: 100%;
86
-
height: 100%;
87
-
object-fit: cover;
88
-
}
89
-
90
-
.name {
91
-
font-weight: 700;
92
-
}
93
-
94
-
.creator {
95
-
color: var(--text-secondary);
96
-
font-size: calc(var(--font-size) * 0.8125);
97
-
}
98
-
99
-
.description {
100
-
display: -webkit-box;
101
-
overflow: hidden;
102
-
font-size: calc(var(--font-size) * 0.8125);
103
-
white-space: pre-wrap;
104
-
-webkit-box-orient: vertical;
105
-
-webkit-line-clamp: 2;
106
-
line-clamp: 2;
107
-
overflow-wrap: break-word;
108
-
109
-
&:empty {
110
-
display: none;
111
-
}
112
-
}
113
-
</style>
-213
packages/internal/components/embeds/quote-embed.svelte
-213
packages/internal/components/embeds/quote-embed.svelte
···
1
-
<script lang="ts" module>
2
-
const getPostImage = (embed: AppBskyFeedDefs.PostView['embed']): AppBskyEmbedImages.View | undefined => {
3
-
if (embed) {
4
-
if (embed.$type === 'app.bsky.embed.images#view') {
5
-
return embed;
6
-
}
7
-
8
-
if (embed.$type === 'app.bsky.embed.recordWithMedia#view') {
9
-
return getPostImage(embed.media);
10
-
}
11
-
}
12
-
};
13
-
14
-
const getPostVideo = (embed: AppBskyFeedDefs.PostView['embed']): AppBskyEmbedVideo.View | undefined => {
15
-
if (embed) {
16
-
if (embed.$type === 'app.bsky.embed.video#view') {
17
-
return embed;
18
-
}
19
-
20
-
if (embed.$type === 'app.bsky.embed.recordWithMedia#view') {
21
-
return getPostVideo(embed.media);
22
-
}
23
-
}
24
-
};
25
-
</script>
26
-
27
-
<script lang="ts">
28
-
import type {
29
-
AppBskyEmbedImages,
30
-
AppBskyEmbedRecord,
31
-
AppBskyEmbedVideo,
32
-
AppBskyFeedDefs,
33
-
AppBskyFeedPost,
34
-
} from '@atcute/client/lexicons';
35
-
36
-
import { getPostUrl } from '../../utils/bsky-url';
37
-
import { formatShortDate } from '../../utils/date';
38
-
import { findLabel } from '../../utils/labels';
39
-
import { parseAtUri } from '../../utils/syntax/at-url';
40
-
41
-
import ImageEmbed from './image-embed.svelte';
42
-
import VideoEmbed from './video-embed.svelte';
43
-
44
-
interface Props {
45
-
embed: AppBskyEmbedRecord.ViewRecord;
46
-
large?: boolean;
47
-
}
48
-
49
-
const { embed: quote, large = false }: Props = $props();
50
-
51
-
const record = quote.value as AppBskyFeedPost.Record;
52
-
const text = record.text.trim();
53
-
54
-
const author = quote.author;
55
-
const authorName = author.displayName?.trim();
56
-
57
-
const embed = quote.embeds?.[0];
58
-
const image = getPostImage(embed);
59
-
const video = getPostVideo(embed);
60
-
61
-
const postUrl = getPostUrl(author.did, parseAtUri(quote.uri).rkey);
62
-
63
-
const isMediaBlurred = !!findLabel(quote.labels, author.did);
64
-
</script>
65
-
66
-
<a target="_blank" href={postUrl} class="quote-embed">
67
-
<div class="meta">
68
-
<div class="avatar-wrapper">
69
-
{#if author.avatar}
70
-
<img loading="lazy" src={author.avatar} alt="" class="avatar" />
71
-
{/if}
72
-
</div>
73
-
74
-
<span class="name-wrapper">
75
-
{#if authorName}
76
-
<bdi class="display-name-wrapper">
77
-
<span class="display-name">{authorName}</span>
78
-
</bdi>
79
-
{/if}
80
-
81
-
<span class="handle">@{author.handle}</span>
82
-
</span>
83
-
84
-
<span aria-hidden="true" class="dot">ยท</span>
85
-
86
-
<time datetime={record.createdAt} class="date">
87
-
{formatShortDate(record.createdAt)}
88
-
</time>
89
-
</div>
90
-
91
-
{#if text}
92
-
<div class="body">
93
-
{#if !large}
94
-
{#if image}
95
-
<div class="aside">
96
-
<ImageEmbed embed={image} blur={isMediaBlurred} />
97
-
</div>
98
-
{:else if video}
99
-
<div class="aside">
100
-
<VideoEmbed embed={video} blur={isMediaBlurred} />
101
-
</div>
102
-
{/if}
103
-
{/if}
104
-
105
-
<p class="text">{text}</p>
106
-
</div>
107
-
{:else}
108
-
<div class="divide"></div>
109
-
{/if}
110
-
111
-
{#if large || !text}
112
-
{#if image}
113
-
<ImageEmbed embed={image} borderless blur={isMediaBlurred} />
114
-
{:else if video}
115
-
<VideoEmbed embed={video} borderless blur={isMediaBlurred} />
116
-
{/if}
117
-
{/if}
118
-
</a>
119
-
120
-
<style>
121
-
.quote-embed {
122
-
display: block;
123
-
border: 1px solid var(--divider);
124
-
border-radius: 6px;
125
-
overflow: hidden;
126
-
127
-
&:hover {
128
-
border-color: var(--divider-hover);
129
-
}
130
-
}
131
-
132
-
.meta {
133
-
display: flex;
134
-
padding: 12px 12px 0 12px;
135
-
color: var(--text-secondary);
136
-
137
-
.avatar-wrapper {
138
-
flex-shrink: 0;
139
-
margin: 0 8px 0 0;
140
-
border-radius: 9999px;
141
-
background: var(--background-secondary);
142
-
width: 20px;
143
-
height: 20px;
144
-
overflow: hidden;
145
-
}
146
-
.avatar {
147
-
width: 100%;
148
-
height: 100%;
149
-
}
150
-
151
-
.name-wrapper {
152
-
display: flex;
153
-
gap: 4px;
154
-
max-width: 100%;
155
-
overflow: hidden;
156
-
text-overflow: ellipsis;
157
-
white-space: nowrap;
158
-
}
159
-
.display-name-wrapper {
160
-
overflow: hidden;
161
-
text-overflow: ellipsis;
162
-
}
163
-
.display-name {
164
-
color: var(--text-primary);
165
-
font-weight: 700;
166
-
}
167
-
.handle {
168
-
display: block;
169
-
overflow: hidden;
170
-
text-overflow: ellipsis;
171
-
white-space: nowrap;
172
-
}
173
-
174
-
.dot {
175
-
flex-shrink: 0;
176
-
margin: 0 6px;
177
-
}
178
-
179
-
.date {
180
-
white-space: nowrap;
181
-
}
182
-
}
183
-
184
-
.body {
185
-
display: flex;
186
-
align-items: flex-start;
187
-
}
188
-
189
-
.aside {
190
-
flex-grow: 1;
191
-
flex-basis: 0;
192
-
margin: 8px 0 12px 12px;
193
-
max-width: 20%;
194
-
}
195
-
196
-
.text {
197
-
display: -webkit-box;
198
-
margin: 8px 12px 12px 12px;
199
-
overflow: hidden;
200
-
-webkit-box-orient: vertical;
201
-
flex-grow: 4;
202
-
flex-basis: 0px;
203
-
min-width: 0px;
204
-
-webkit-line-clamp: 6;
205
-
line-clamp: 6;
206
-
white-space: pre-wrap;
207
-
overflow-wrap: break-word;
208
-
}
209
-
210
-
.divide {
211
-
padding: 6px 0;
212
-
}
213
-
</style>
-122
packages/internal/components/embeds/starterpack-embed.svelte
-122
packages/internal/components/embeds/starterpack-embed.svelte
···
1
-
<script lang="ts">
2
-
import type { AppBskyGraphDefs, AppBskyGraphStarterpack } from '@atcute/client/lexicons';
3
-
4
-
import { getStarterpackImgUrl, getStarterpackUrl } from '../../utils/bsky-url';
5
-
import { parseAtUri } from '../../utils/syntax/at-url';
6
-
7
-
interface Props {
8
-
embed: AppBskyGraphDefs.StarterPackViewBasic;
9
-
large?: boolean;
10
-
}
11
-
12
-
const { embed: pack, large = false }: Props = $props();
13
-
14
-
const record = pack.record as AppBskyGraphStarterpack.Record;
15
-
16
-
const creator = pack.creator;
17
-
const creatorDid = creator.did;
18
-
19
-
const rkey = parseAtUri(pack.uri).rkey;
20
-
const packUrl = getStarterpackUrl(creatorDid, rkey);
21
-
</script>
22
-
23
-
<a target="_blank" href={packUrl} class="starterpack-embed">
24
-
{#if large}
25
-
{@const imageUrl = getStarterpackImgUrl(creatorDid, rkey)}
26
-
27
-
<img loading="lazy" src={imageUrl} alt="" class="banner" />
28
-
{/if}
29
-
30
-
<div class="meta">
31
-
<div class="main">
32
-
<svg fill="none" viewBox="0 0 24 24" class="avatar">
33
-
<defs>
34
-
<linearGradient id="a" x1="0" x2="100%" y1="0" y2="0" gradientTransform="rotate(45)">
35
-
<stop offset="0" stop-color="#0A7AFF" />
36
-
<stop offset="1" stop-color="#59B9FF" />
37
-
</linearGradient>
38
-
</defs>
39
-
<path
40
-
fill="url(#a)"
41
-
fill-rule="evenodd"
42
-
d="M11.26 5.227 5.02 6.899c-.734.197-1.17.95-.973 1.685l1.672 6.24c.197.734.951 1.17 1.685.973l6.24-1.672a1.376 1.376 0 0 0 .973-1.685L12.945 6.2a1.375 1.375 0 0 0-1.685-.973Zm-6.566.459a2.632 2.632 0 0 0-1.86 3.223l1.672 6.24a2.632 2.632 0 0 0 3.223 1.861l6.24-1.672a2.631 2.631 0 0 0 1.861-3.223l-1.672-6.24a2.632 2.632 0 0 0-3.223-1.861l-6.24 1.672Z"
43
-
clip-rule="evenodd"
44
-
/>
45
-
<path
46
-
fill="url(#a)"
47
-
fill-rule="evenodd"
48
-
d="M15.138 18.411a4.606 4.606 0 1 0 0-9.211 4.606 4.606 0 0 0 0 9.211Zm0 1.257a5.862 5.862 0 1 0 0-11.724 5.862 5.862 0 0 0 0 11.724Z"
49
-
clip-rule="evenodd"
50
-
/>
51
-
</svg>
52
-
53
-
<div class="info">
54
-
<p class="name">{record.name}</p>
55
-
<p class="creator">Starter pack by @{creator.handle}</p>
56
-
</div>
57
-
</div>
58
-
59
-
<p class="description">{record.description}</p>
60
-
</div>
61
-
</a>
62
-
63
-
<style>
64
-
.starterpack-embed {
65
-
display: block;
66
-
border: 1px solid var(--divider);
67
-
border-radius: 6px;
68
-
overflow: hidden;
69
-
70
-
&:hover {
71
-
border-color: var(--divider-hover);
72
-
}
73
-
}
74
-
75
-
.banner {
76
-
display: block;
77
-
aspect-ratio: 1.91;
78
-
width: 100%;
79
-
}
80
-
81
-
.meta {
82
-
display: flex;
83
-
flex-direction: column;
84
-
gap: 12px;
85
-
padding: 12px;
86
-
}
87
-
88
-
.main {
89
-
display: flex;
90
-
gap: 12px;
91
-
}
92
-
93
-
.avatar {
94
-
margin: 2px;
95
-
width: 36px;
96
-
height: 36px;
97
-
}
98
-
99
-
.name {
100
-
font-weight: 700;
101
-
}
102
-
103
-
.creator {
104
-
color: var(--text-secondary);
105
-
font-size: calc(var(--font-size) * 0.8125);
106
-
}
107
-
108
-
.description {
109
-
display: -webkit-box;
110
-
overflow: hidden;
111
-
font-size: calc(var(--font-size) * 0.8125);
112
-
white-space: pre-wrap;
113
-
-webkit-box-orient: vertical;
114
-
-webkit-line-clamp: 2;
115
-
line-clamp: 2;
116
-
overflow-wrap: break-word;
117
-
118
-
&:empty {
119
-
display: none;
120
-
}
121
-
}
122
-
</style>
-120
packages/internal/components/embeds/video-embed.svelte
-120
packages/internal/components/embeds/video-embed.svelte
···
1
-
<script lang="ts">
2
-
import type { AppBskyEmbedVideo, AppBskyFeedDefs } from '@atcute/client/lexicons';
3
-
4
-
import { getPostUrl } from '../../utils/bsky-url';
5
-
import { parseAtUri } from '../../utils/syntax/at-url';
6
-
7
-
interface Props {
8
-
post?: AppBskyFeedDefs.PostView;
9
-
embed: AppBskyEmbedVideo.View;
10
-
borderless?: boolean;
11
-
standalone?: boolean;
12
-
blur?: boolean;
13
-
}
14
-
15
-
const { post, embed: video, borderless, standalone, blur }: Props = $props();
16
-
17
-
const ratio = standalone && video.aspectRatio;
18
-
19
-
const postUrl = post && getPostUrl(post.author.did, parseAtUri(post.uri).rkey);
20
-
</script>
21
-
22
-
{#if standalone}
23
-
<a
24
-
target="_blank"
25
-
href={postUrl}
26
-
class={`video-embed` + (!borderless ? ` is-bordered` : ``) + (standalone ? ` is-standalone` : ``)}
27
-
>
28
-
<div class="constrainer" style={ratio ? `aspect-ratio: ${ratio.width}/${ratio.height}` : ``}>
29
-
{@render Content()}
30
-
</div>
31
-
</a>
32
-
{:else}
33
-
<div
34
-
class={`video-embed` + (!borderless ? ` is-bordered` : ``)}
35
-
style={ratio ? `aspect-ratio: ${ratio.width}/${ratio.height}` : ``}
36
-
>
37
-
{@render Content()}
38
-
</div>
39
-
{/if}
40
-
41
-
{#snippet Content()}
42
-
<img loading="lazy" src={video.thumbnail} alt="" class={`thumbnail` + (blur ? ` is-blurred` : ``)} />
43
-
44
-
{#if ratio}
45
-
<div class="placeholder"></div>
46
-
{/if}
47
-
48
-
<div class="play">
49
-
<!-- play -->
50
-
<svg class="icon" fill="none" viewBox="0 0 24 24">
51
-
<path fill="currentColor" d="M22 12 5 2v20l17-10Z" />
52
-
</svg>
53
-
</div>
54
-
{/snippet}
55
-
56
-
<style>
57
-
.video-embed {
58
-
display: block;
59
-
position: relative;
60
-
background: #000000;
61
-
aspect-ratio: 16 / 9;
62
-
overflow: hidden;
63
-
}
64
-
.is-bordered {
65
-
border: 1px solid var(--divider);
66
-
border-radius: 6px;
67
-
}
68
-
.is-standalone {
69
-
align-self: baseline;
70
-
aspect-ratio: auto;
71
-
max-width: 100%;
72
-
}
73
-
74
-
.constrainer {
75
-
min-width: 64px;
76
-
max-width: 100%;
77
-
min-height: 64px;
78
-
max-height: 320px;
79
-
}
80
-
81
-
.thumbnail {
82
-
width: 100%;
83
-
height: 100%;
84
-
object-fit: contain;
85
-
}
86
-
.is-blurred {
87
-
scale: 125%;
88
-
filter: blur(24px);
89
-
}
90
-
91
-
.placeholder {
92
-
width: 100vw;
93
-
height: 100vh;
94
-
}
95
-
96
-
.play {
97
-
display: grid;
98
-
position: absolute;
99
-
top: 50%;
100
-
left: 50%;
101
-
place-items: center;
102
-
translate: -50% -50%;
103
-
border-radius: 50%;
104
-
background: rgba(64, 64, 64, 0.6);
105
-
aspect-ratio: 1 / 1;
106
-
height: 40%;
107
-
max-height: 48px;
108
-
color: #ffffff;
109
-
font-size: 20px;
110
-
111
-
.icon {
112
-
width: 40%;
113
-
height: 40%;
114
-
}
115
-
116
-
.is-standalone &:hover {
117
-
background: rgba(64, 64, 64, 0.8);
118
-
}
119
-
}
120
-
</style>
-400
packages/internal/components/feed-post.svelte
-400
packages/internal/components/feed-post.svelte
···
1
-
<script lang="ts">
2
-
import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/client/lexicons';
3
-
4
-
import { getPostUrl, getProfileUrl } from '../utils/bsky-url';
5
-
import { formatLongDate, formatShortDate } from '../utils/date';
6
-
import { parseAtUri } from '../utils/syntax/at-url';
7
-
8
-
import { formatCompactNumber, formatLongNumber } from '../utils/number';
9
-
import Embeds from './embeds/embeds.svelte';
10
-
import RichtextRenderer from './richtext-renderer.svelte';
11
-
12
-
interface Props {
13
-
item: AppBskyFeedDefs.FeedViewPost;
14
-
prev?: boolean;
15
-
next?: boolean;
16
-
}
17
-
18
-
const { item, prev = false, next = false }: Props = $props();
19
-
20
-
const reason = item.reason;
21
-
const post = item.post;
22
-
const parent = item.reply?.parent;
23
-
24
-
const author = post.author;
25
-
const authorUrl = getProfileUrl(author.did);
26
-
const authorName = author.displayName?.trim();
27
-
28
-
const record = post.record as AppBskyFeedPost.Record;
29
-
const postUrl = getPostUrl(author.did, parseAtUri(post.uri).rkey);
30
-
31
-
const replyCount = post.replyCount || 0;
32
-
const likeCount = post.likeCount || 0;
33
-
const repostCount = (post.repostCount || 0) + (post.quoteCount || 0);
34
-
</script>
35
-
36
-
<div class={`feed-post` + (!next ? ` is-leaf` : ``)}>
37
-
<div class="contexts">
38
-
{#if prev}
39
-
<div class="ascendant-line-wrapper">
40
-
<div class="line"></div>
41
-
</div>
42
-
{/if}
43
-
44
-
{#if reason}
45
-
{#if reason.$type === 'app.bsky.feed.defs#reasonRepost'}
46
-
{@const by = reason.by}
47
-
48
-
<div class="context">
49
-
<div class="aside">
50
-
<svg class="icon" viewBox="0 0 24 24" fill="none">
51
-
<path
52
-
d="M17 3L20 6L17 9M7 21L4 18L7 15M5 18H20V13M4 11V6H19"
53
-
stroke="currentColor"
54
-
stroke-width="2"
55
-
stroke-linecap="square"
56
-
/>
57
-
</svg>
58
-
</div>
59
-
<a href={getProfileUrl(by.did)} class="main">
60
-
<span dir="auto" class="name">{by.displayName}</span>
61
-
<span class="affix">{' '}reposted</span>
62
-
</a>
63
-
</div>
64
-
{:else if reason.$type === 'app.bsky.feed.defs#reasonPin'}
65
-
<div class="context">
66
-
<div class="aside">
67
-
<svg class="icon" fill="none" viewBox="0 0 24 24">
68
-
<path
69
-
stroke="currentColor"
70
-
stroke-linecap="square"
71
-
stroke-width="2"
72
-
d="M12 15H5v-2.5l.377-.377A7.25 7.25 0 0 0 7.5 6.997V3h9v3.997a7.25 7.25 0 0 0 2.123 5.127L19 12.5V15h-7Zm0 0v6"
73
-
/>
74
-
</svg>
75
-
</div>
76
-
<span class="main">Pinned</span>
77
-
</div>
78
-
{/if}
79
-
{/if}
80
-
</div>
81
-
82
-
<div class="content">
83
-
<div class="aside">
84
-
<a target="_blank" href={authorUrl} class="avatar-wrapper">
85
-
{#if author.avatar}
86
-
<img loading="lazy" src={author.avatar} alt="" class="avatar" />
87
-
{/if}
88
-
</a>
89
-
90
-
{#if next}
91
-
<div class="descendant-line"></div>
92
-
{/if}
93
-
</div>
94
-
95
-
<div class="main">
96
-
<div class="meta">
97
-
<a href={authorUrl} target="_blank" class="name-wrapper">
98
-
{#if authorName}
99
-
<bdi class="display-name-wrapper">
100
-
<span class="display-name">{authorName}</span>
101
-
</bdi>
102
-
{/if}
103
-
104
-
<span class="handle">@{author.handle}</span>
105
-
</a>
106
-
107
-
<span aria-hidden="true" class="dot"> ยท </span>
108
-
109
-
<a target="_blank" href={postUrl} title={formatLongDate(record.createdAt)} class="date">
110
-
<time datetime={record.createdAt}>{formatShortDate(record.createdAt)}</time>
111
-
</a>
112
-
</div>
113
-
114
-
{#if !prev && record.reply}
115
-
<p class="reply-context">
116
-
{#if parent && parent.$type === 'app.bsky.feed.defs#postView'}
117
-
{@const author = parent.author}
118
-
119
-
Replying to
120
-
<a target="_blank" href={getProfileUrl(author.did)} dir="auto">
121
-
{author.displayName?.trim() || `@${author.handle}`}
122
-
</a>
123
-
{:else}
124
-
Replying to an unknown post
125
-
{/if}
126
-
</p>
127
-
{/if}
128
-
129
-
<RichtextRenderer text={record.text} facets={record.facets} />
130
-
131
-
{#if post.embed}
132
-
<Embeds {post} embed={post.embed} />
133
-
{/if}
134
-
135
-
<div class="metrics">
136
-
<div
137
-
title={replyCount === 1
138
-
? `${formatLongNumber(replyCount)} reply`
139
-
: `${formatLongNumber(replyCount)} replies`}
140
-
class="stat"
141
-
>
142
-
<svg class="icon" fill="none" viewBox="0 0 24 24">
143
-
<path
144
-
stroke="currentColor"
145
-
stroke-linecap="square"
146
-
stroke-width="2"
147
-
d="M3.002 4h18v14h-9l-5 3v-3h-4V4Z"
148
-
/>
149
-
</svg>
150
-
151
-
<span class="count">
152
-
{formatCompactNumber(replyCount)}
153
-
</span>
154
-
</div>
155
-
156
-
<div
157
-
title={repostCount === 1
158
-
? `${formatLongNumber(repostCount)} repost`
159
-
: `${formatLongNumber(repostCount)} reposts`}
160
-
class="stat"
161
-
>
162
-
<svg class="icon" fill="none" viewBox="0 0 24 24">
163
-
<path
164
-
stroke="currentColor"
165
-
stroke-linecap="square"
166
-
stroke-width="2"
167
-
d="m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15"
168
-
/>
169
-
</svg>
170
-
171
-
<span class="count">
172
-
{formatCompactNumber(repostCount)}
173
-
</span>
174
-
</div>
175
-
176
-
<div
177
-
title={likeCount === 1
178
-
? `${formatLongNumber(likeCount)} like`
179
-
: `${formatLongNumber(likeCount)} likes`}
180
-
class="stat"
181
-
>
182
-
<svg class="icon" fill="none" viewBox="0 0 24 24">
183
-
<path
184
-
stroke="currentColor"
185
-
stroke-width="2"
186
-
d="M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z"
187
-
/>
188
-
</svg>
189
-
190
-
<span class="count">
191
-
{formatCompactNumber(likeCount)}
192
-
</span>
193
-
</div>
194
-
</div>
195
-
</div>
196
-
</div>
197
-
</div>
198
-
199
-
<style>
200
-
.feed-post {
201
-
padding: 0 16px;
202
-
}
203
-
.is-leaf {
204
-
border-bottom: 1px solid var(--divider);
205
-
}
206
-
207
-
.ascendant-line-wrapper {
208
-
display: flex;
209
-
flex-direction: column;
210
-
align-items: center;
211
-
width: 36px;
212
-
213
-
.line {
214
-
position: absolute;
215
-
top: 0;
216
-
bottom: 4px;
217
-
flex-grow: 1;
218
-
border-left: 2px solid var(--divider);
219
-
}
220
-
}
221
-
.descendant-line {
222
-
flex-grow: 1;
223
-
margin-top: 4px;
224
-
border-left: 2px solid var(--divider);
225
-
}
226
-
227
-
.contexts {
228
-
display: flex;
229
-
position: relative;
230
-
flex-direction: column;
231
-
padding: 8px 0 4px 0;
232
-
}
233
-
.context {
234
-
display: flex;
235
-
align-items: center;
236
-
gap: 12px;
237
-
color: var(--text-secondary);
238
-
font-size: 0.8125rem;
239
-
line-height: 1.25rem;
240
-
241
-
.aside {
242
-
display: flex;
243
-
flex-shrink: 0;
244
-
justify-content: flex-end;
245
-
width: 36px;
246
-
}
247
-
248
-
.main {
249
-
display: flex;
250
-
min-width: 0px;
251
-
252
-
&:hover {
253
-
text-decoration-line: underline;
254
-
}
255
-
}
256
-
257
-
.name {
258
-
overflow: hidden;
259
-
font-weight: 500;
260
-
text-overflow: ellipsis;
261
-
white-space: nowrap;
262
-
}
263
-
264
-
.affix {
265
-
flex-shrink: 0;
266
-
white-space: pre;
267
-
}
268
-
}
269
-
270
-
.content {
271
-
display: flex;
272
-
gap: 12px;
273
-
274
-
.aside {
275
-
display: flex;
276
-
flex-shrink: 0;
277
-
flex-direction: column;
278
-
align-items: center;
279
-
}
280
-
281
-
.main {
282
-
flex-grow: 1;
283
-
padding-bottom: 12px;
284
-
min-width: 0;
285
-
}
286
-
}
287
-
288
-
.avatar-wrapper {
289
-
display: block;
290
-
border-radius: 9999px;
291
-
background: var(--background-secondary);
292
-
width: 36px;
293
-
height: 36px;
294
-
overflow: hidden;
295
-
296
-
&:hover {
297
-
filter: brightness(0.85);
298
-
}
299
-
}
300
-
.avatar {
301
-
width: 100%;
302
-
height: 100%;
303
-
object-fit: cover;
304
-
}
305
-
306
-
.meta {
307
-
display: flex;
308
-
align-items: center;
309
-
margin: 0 0 2px 0;
310
-
color: var(--text-secondary);
311
-
312
-
.name-wrapper {
313
-
display: flex;
314
-
gap: 4px;
315
-
max-width: 100%;
316
-
overflow: hidden;
317
-
color: inherit;
318
-
text-decoration: none;
319
-
text-overflow: ellipsis;
320
-
white-space: nowrap;
321
-
}
322
-
323
-
.display-name-wrapper {
324
-
overflow: hidden;
325
-
text-overflow: ellipsis;
326
-
327
-
.name-wrapper:hover & {
328
-
text-decoration: underline;
329
-
}
330
-
}
331
-
332
-
.display-name {
333
-
color: var(--text-primary);
334
-
font-weight: 700;
335
-
}
336
-
337
-
.handle {
338
-
display: block;
339
-
overflow: hidden;
340
-
text-overflow: ellipsis;
341
-
white-space: nowrap;
342
-
}
343
-
344
-
.dot {
345
-
flex-shrink: 0;
346
-
margin: 0 6px;
347
-
}
348
-
349
-
.date {
350
-
color: inherit;
351
-
text-decoration: none;
352
-
white-space: nowrap;
353
-
354
-
&:hover {
355
-
text-decoration: underline;
356
-
}
357
-
}
358
-
}
359
-
360
-
.reply-context {
361
-
overflow: hidden;
362
-
color: var(--text-secondary);
363
-
font-size: calc(var(--font-size) * 0.8125);
364
-
text-overflow: ellipsis;
365
-
white-space: nowrap;
366
-
367
-
a {
368
-
color: inherit;
369
-
font-weight: 500;
370
-
371
-
&:hover {
372
-
text-decoration: underline;
373
-
}
374
-
}
375
-
}
376
-
377
-
.metrics {
378
-
display: flex;
379
-
align-items: center;
380
-
gap: 16px;
381
-
margin-top: 12px;
382
-
color: var(--text-secondary);
383
-
}
384
-
.stat {
385
-
display: flex;
386
-
align-items: center;
387
-
gap: 8px;
388
-
min-width: 0px;
389
-
max-width: 100%;
390
-
391
-
.count {
392
-
padding-right: 8px;
393
-
overflow: hidden;
394
-
font-size: calc(var(--font-size) * 0.8125);
395
-
line-height: calc(var(--font-size) * 1.25);
396
-
text-overflow: ellipsis;
397
-
white-space: nowrap;
398
-
}
399
-
}
400
-
</style>
-271
packages/internal/components/highlighted-post.svelte
-271
packages/internal/components/highlighted-post.svelte
···
1
-
<script lang="ts">
2
-
import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/client/lexicons';
3
-
4
-
import { getPostUrl, getProfileUrl } from '../utils/bsky-url';
5
-
import { formatLongDate } from '../utils/date';
6
-
import { findLabel } from '../utils/labels';
7
-
import { formatCompactNumber, formatLongNumber } from '../utils/number';
8
-
import { parseAtUri } from '../utils/syntax/at-url';
9
-
10
-
import Embeds from './embeds/embeds.svelte';
11
-
import RichTextRenderer from './richtext-renderer.svelte';
12
-
13
-
interface Props {
14
-
post: AppBskyFeedDefs.PostView;
15
-
parent: AppBskyFeedDefs.PostView | null;
16
-
prev?: boolean;
17
-
}
18
-
19
-
const { post, parent, prev = false }: Props = $props();
20
-
21
-
const author = post.author;
22
-
const authorUrl = getProfileUrl(author.did);
23
-
const authorName = author.displayName?.trim();
24
-
25
-
const record = post.record as AppBskyFeedPost.Record;
26
-
const postUrl = getPostUrl(author.did, parseAtUri(post.uri).rkey);
27
-
28
-
const replyCount = post.replyCount || 0;
29
-
const likeCount = post.likeCount || 0;
30
-
const repostCount = (post.repostCount || 0) + (post.quoteCount || 0);
31
-
32
-
const isAuthorBlurred = !!findLabel(author.labels, author.did);
33
-
</script>
34
-
35
-
<div class="highlighted-post">
36
-
<div class="meta">
37
-
<a href={authorUrl} target="_blank" class="avatar-wrapper">
38
-
{#if author.avatar}
39
-
<img
40
-
loading="lazy"
41
-
src={author.avatar}
42
-
alt=""
43
-
class={`avatar` + (isAuthorBlurred ? ` is-blurred` : ``)}
44
-
/>
45
-
{/if}
46
-
</a>
47
-
48
-
<a href={authorUrl} target="_blank" class="name-wrapper">
49
-
{#if authorName}
50
-
<bdi class="display-name-wrapper">
51
-
<span class="display-name">{authorName}</span>
52
-
</bdi>
53
-
{/if}
54
-
<span class="handle">@{author.handle}</span>
55
-
</a>
56
-
57
-
{#if !prev}
58
-
<svg class="logo" fill="none" viewBox="0 0 320 286">
59
-
<path
60
-
fill="#0A7AFF"
61
-
d="M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z"
62
-
/>
63
-
</svg>
64
-
{/if}
65
-
</div>
66
-
67
-
{#if !prev && record.reply}
68
-
<p class="context">
69
-
{#if parent}
70
-
{@const author = parent.author}
71
-
72
-
Replying to
73
-
<a target="_blank" href={getProfileUrl(author.did)} dir="auto">
74
-
{author.displayName?.trim() || `@${author.handle}`}
75
-
</a>
76
-
{:else}
77
-
Replying to an unknown post
78
-
{/if}
79
-
</p>
80
-
{/if}
81
-
82
-
<RichTextRenderer text={record.text} facets={record.facets} large />
83
-
84
-
{#if post.embed}
85
-
<Embeds {post} embed={post.embed} large />
86
-
{/if}
87
-
88
-
<time datetime={record.createdAt} class="date">
89
-
{formatLongDate(record.createdAt)}
90
-
</time>
91
-
92
-
<div class="stats">
93
-
<span
94
-
class="stat"
95
-
title={likeCount === 1 ? `${formatLongNumber(likeCount)} like` : `${formatLongNumber(likeCount)} likes`}
96
-
>
97
-
<!-- heart-2 -->
98
-
<svg class="icon" fill="none" viewBox="0 0 24 24">
99
-
<path
100
-
stroke="currentColor"
101
-
stroke-width="2"
102
-
d="M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z"
103
-
/>
104
-
</svg>
105
-
106
-
<span>{formatCompactNumber(likeCount)}</span>
107
-
</span>
108
-
109
-
<span
110
-
class="stat"
111
-
title={repostCount === 1
112
-
? `${formatLongNumber(repostCount)} repost`
113
-
: `${formatLongNumber(repostCount)} reposts`}
114
-
>
115
-
<!-- arrows-repeat-right-left -->
116
-
<svg class="icon" fill="none" viewBox="0 0 24 24">
117
-
<path
118
-
stroke="currentColor"
119
-
stroke-linecap="square"
120
-
stroke-width="2"
121
-
d="m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15"
122
-
/>
123
-
</svg>
124
-
125
-
<span>{formatCompactNumber(repostCount)}</span>
126
-
</span>
127
-
128
-
<div class="gap"></div>
129
-
130
-
<a href={postUrl} target="_blank" class="permalink">
131
-
<span>
132
-
{!replyCount
133
-
? `View on Bluesky`
134
-
: replyCount === 1
135
-
? `Read ${formatCompactNumber(replyCount)} reply on Bluesky`
136
-
: `Read ${formatCompactNumber(replyCount)} replies on Bluesky`}
137
-
</span>
138
-
</a>
139
-
</div>
140
-
</div>
141
-
142
-
<style>
143
-
.highlighted-post {
144
-
padding: 16px;
145
-
}
146
-
147
-
.meta {
148
-
display: flex;
149
-
align-items: center;
150
-
gap: 12px;
151
-
margin: 0 0 12px 0;
152
-
color: var(--text-secondary);
153
-
}
154
-
155
-
.avatar-wrapper {
156
-
display: block;
157
-
flex-shrink: 0;
158
-
border-radius: 9999px;
159
-
background: var(--background-secondary);
160
-
width: 40px;
161
-
height: 40px;
162
-
overflow: hidden;
163
-
164
-
&:hover {
165
-
filter: brightness(0.85);
166
-
}
167
-
}
168
-
169
-
.avatar {
170
-
width: 100%;
171
-
height: 100%;
172
-
object-fit: cover;
173
-
}
174
-
.is-blurred {
175
-
scale: 125%;
176
-
filter: blur(4px);
177
-
}
178
-
179
-
.name-wrapper {
180
-
display: block;
181
-
flex-grow: 1;
182
-
max-width: 100%;
183
-
overflow: hidden;
184
-
color: inherit;
185
-
text-overflow: ellipsis;
186
-
white-space: nowrap;
187
-
}
188
-
.display-name-wrapper {
189
-
overflow: hidden;
190
-
text-overflow: ellipsis;
191
-
192
-
.name-wrapper:hover & {
193
-
text-decoration: underline;
194
-
}
195
-
}
196
-
.display-name {
197
-
color: var(--text-primary);
198
-
font-weight: 700;
199
-
}
200
-
.handle {
201
-
display: block;
202
-
overflow: hidden;
203
-
text-overflow: ellipsis;
204
-
white-space: nowrap;
205
-
}
206
-
207
-
.logo {
208
-
width: 32px;
209
-
height: 32px;
210
-
}
211
-
212
-
.context {
213
-
overflow: hidden;
214
-
color: var(--text-secondary);
215
-
font-size: calc(var(--font-size) * 0.8125);
216
-
text-overflow: ellipsis;
217
-
white-space: nowrap;
218
-
219
-
a {
220
-
color: inherit;
221
-
font-weight: 500;
222
-
223
-
&:hover {
224
-
text-decoration: underline;
225
-
}
226
-
}
227
-
}
228
-
229
-
.date {
230
-
display: flex;
231
-
flex-wrap: wrap;
232
-
align-items: center;
233
-
gap: 8px;
234
-
margin: 12px 0 0;
235
-
border-bottom: 1px solid var(--divider);
236
-
padding: 0 0 12px 0;
237
-
color: var(--text-secondary);
238
-
}
239
-
240
-
.stats {
241
-
display: flex;
242
-
flex-wrap: wrap;
243
-
align-items: center;
244
-
gap: 8px 16px;
245
-
margin: 0 0 -16px 0;
246
-
padding: 12px 0;
247
-
color: var(--text-secondary);
248
-
249
-
.gap {
250
-
flex: 1 1 auto;
251
-
}
252
-
253
-
.permalink {
254
-
display: flex;
255
-
align-items: center;
256
-
gap: 4px;
257
-
color: var(--text-link);
258
-
font-weight: 700;
259
-
260
-
&:hover {
261
-
text-decoration: underline;
262
-
}
263
-
}
264
-
}
265
-
.stat {
266
-
display: flex;
267
-
align-items: center;
268
-
gap: 8px;
269
-
font-weight: 500;
270
-
}
271
-
</style>
-226
packages/internal/components/post.svelte
-226
packages/internal/components/post.svelte
···
1
-
<script lang="ts">
2
-
import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/client/lexicons';
3
-
4
-
import { getPostUrl, getProfileUrl } from '../utils/bsky-url';
5
-
import { formatLongDate, formatShortDate } from '../utils/date';
6
-
import { findLabel } from '../utils/labels';
7
-
import { parseAtUri } from '../utils/syntax/at-url';
8
-
9
-
import Embeds from './embeds/embeds.svelte';
10
-
import RichtextRenderer from './richtext-renderer.svelte';
11
-
12
-
interface Props {
13
-
post: AppBskyFeedDefs.PostView;
14
-
parent?: AppBskyFeedDefs.PostView | null;
15
-
prev?: boolean;
16
-
}
17
-
18
-
const { post, parent, prev }: Props = $props();
19
-
20
-
const author = post.author;
21
-
const authorUrl = getProfileUrl(author.did);
22
-
const authorName = author.displayName?.trim();
23
-
24
-
const record = post.record as AppBskyFeedPost.Record;
25
-
const postUrl = getPostUrl(author.did, parseAtUri(post.uri).rkey);
26
-
27
-
const isAuthorBlurred = !!findLabel(author.labels, author.did);
28
-
</script>
29
-
30
-
<div class="post">
31
-
{#if !prev}
32
-
<svg class="logo" fill="none" viewBox="0 0 320 286">
33
-
<path
34
-
fill="#0A7AFF"
35
-
d="M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z"
36
-
/>
37
-
</svg>
38
-
{/if}
39
-
40
-
<div class="aside">
41
-
<a target="_blank" href={authorUrl} class="avatar-wrapper">
42
-
{#if author.avatar}
43
-
<img
44
-
loading="lazy"
45
-
src={author.avatar}
46
-
alt=""
47
-
class={`avatar` + (isAuthorBlurred ? ` is-blurred` : ``)}
48
-
/>
49
-
{/if}
50
-
</a>
51
-
52
-
<div class="line"></div>
53
-
</div>
54
-
55
-
<div class="main">
56
-
<div class="meta">
57
-
<a href={authorUrl} target="_blank" class="name-wrapper">
58
-
{#if authorName}
59
-
<bdi class="display-name-wrapper">
60
-
<span class="display-name">{authorName}</span>
61
-
</bdi>
62
-
{/if}
63
-
64
-
<span class="handle">@{author.handle}</span>
65
-
</a>
66
-
67
-
<span aria-hidden="true" class="dot"> ยท </span>
68
-
69
-
<a target="_blank" href={postUrl} title={formatLongDate(record.createdAt)} class="date">
70
-
<time datetime={record.createdAt}>{formatShortDate(record.createdAt)}</time>
71
-
</a>
72
-
</div>
73
-
74
-
{#if !prev && record.reply}
75
-
<p class="context">
76
-
{#if parent}
77
-
{@const author = parent.author}
78
-
79
-
Replying to
80
-
<a target="_blank" href={getProfileUrl(author.did)} dir="auto">
81
-
{author.displayName?.trim() || `@${author.handle}`}
82
-
</a>
83
-
{:else}
84
-
Replying to an unknown post
85
-
{/if}
86
-
</p>
87
-
{/if}
88
-
89
-
<RichtextRenderer text={record.text} facets={record.facets} />
90
-
91
-
{#if post.embed}
92
-
<Embeds {post} embed={post.embed} />
93
-
{/if}
94
-
</div>
95
-
</div>
96
-
97
-
<style>
98
-
.post {
99
-
display: flex;
100
-
position: relative;
101
-
gap: 12px;
102
-
padding: 12px 16px 0 16px;
103
-
}
104
-
105
-
.logo {
106
-
position: absolute;
107
-
top: 12px;
108
-
right: 12px;
109
-
width: 24px;
110
-
height: 24px;
111
-
}
112
-
113
-
.aside {
114
-
flex-shrink: 0;
115
-
}
116
-
117
-
.avatar-wrapper {
118
-
display: block;
119
-
border-radius: 9999px;
120
-
background: var(--background-secondary);
121
-
width: 40px;
122
-
height: 40px;
123
-
overflow: hidden;
124
-
125
-
&:hover {
126
-
filter: brightness(0.85);
127
-
}
128
-
}
129
-
130
-
.avatar {
131
-
width: 100%;
132
-
height: 100%;
133
-
object-fit: cover;
134
-
}
135
-
.is-blurred {
136
-
scale: 125%;
137
-
filter: blur(4px);
138
-
}
139
-
140
-
.line {
141
-
position: absolute;
142
-
top: 56px;
143
-
bottom: -12px;
144
-
left: 35px;
145
-
border-left: 2px solid var(--divider);
146
-
}
147
-
148
-
.main {
149
-
display: flex;
150
-
flex-grow: 1;
151
-
flex-direction: column;
152
-
min-width: 0px;
153
-
}
154
-
155
-
.meta {
156
-
display: flex;
157
-
align-items: center;
158
-
margin: 0 0 2px 0;
159
-
padding: 0 calc(24px + 8px) 0 0;
160
-
color: var(--text-secondary);
161
-
162
-
.name-wrapper {
163
-
display: flex;
164
-
gap: 4px;
165
-
max-width: 100%;
166
-
overflow: hidden;
167
-
color: inherit;
168
-
text-decoration: none;
169
-
text-overflow: ellipsis;
170
-
white-space: nowrap;
171
-
}
172
-
173
-
.display-name-wrapper {
174
-
overflow: hidden;
175
-
text-overflow: ellipsis;
176
-
177
-
.name-wrapper:hover & {
178
-
text-decoration: underline;
179
-
}
180
-
}
181
-
182
-
.display-name {
183
-
color: var(--text-primary);
184
-
font-weight: 700;
185
-
}
186
-
187
-
.handle {
188
-
display: block;
189
-
overflow: hidden;
190
-
text-overflow: ellipsis;
191
-
white-space: nowrap;
192
-
}
193
-
194
-
.dot {
195
-
flex-shrink: 0;
196
-
margin: 0 6px;
197
-
}
198
-
199
-
.date {
200
-
color: inherit;
201
-
text-decoration: none;
202
-
white-space: nowrap;
203
-
204
-
&:hover {
205
-
text-decoration: underline;
206
-
}
207
-
}
208
-
}
209
-
210
-
.context {
211
-
overflow: hidden;
212
-
color: var(--text-secondary);
213
-
font-size: calc(var(--font-size) * 0.8125);
214
-
text-overflow: ellipsis;
215
-
white-space: nowrap;
216
-
217
-
a {
218
-
color: inherit;
219
-
font-weight: 500;
220
-
221
-
&:hover {
222
-
text-decoration: underline;
223
-
}
224
-
}
225
-
}
226
-
</style>
-204
packages/internal/components/profile-card.svelte
-204
packages/internal/components/profile-card.svelte
···
1
-
<script lang="ts">
2
-
import type { AppBskyActorDefs } from '@atcute/client/lexicons';
3
-
4
-
import { getProfileUrl } from '../utils/bsky-url';
5
-
import { findLabel } from '../utils/labels';
6
-
import { formatCompactNumber } from '../utils/number';
7
-
import RichtextRawRenderer from './richtext-raw-renderer.svelte';
8
-
9
-
interface Props {
10
-
profile: AppBskyActorDefs.ProfileViewDetailed;
11
-
}
12
-
13
-
const { profile }: Props = $props();
14
-
15
-
const url = getProfileUrl(profile.did);
16
-
const isBlurred = findLabel(profile.labels, profile.did);
17
-
</script>
18
-
19
-
<div class="profile-card has-banner">
20
-
<div class="banner-wrapper">
21
-
{#if profile.banner}
22
-
<img loading="lazy" src={profile.banner} alt="" class={`banner` + (isBlurred ? ` is-blurred` : ``)} />
23
-
{/if}
24
-
</div>
25
-
26
-
<div class="contents">
27
-
<div class="header">
28
-
<a href={url} target="_blank" class="avatar-wrapper">
29
-
{#if profile.avatar}
30
-
<img
31
-
loading="lazy"
32
-
src={profile.avatar}
33
-
alt=""
34
-
class={`avatar` + (isBlurred ? ` is-blurred` : ``)}
35
-
/>
36
-
{/if}
37
-
</a>
38
-
39
-
<div class="actions">
40
-
<a href={url} target="_blank" class="follow-button">
41
-
<svg class="icon" fill="none" viewBox="0 0 24 24">
42
-
<path
43
-
stroke="currentColor"
44
-
stroke-linecap="square"
45
-
stroke-width="2"
46
-
d="M12 4v8m0 0v8m0-8H4m8 0h8"
47
-
/>
48
-
</svg>
49
-
<span>Follow</span>
50
-
</a>
51
-
52
-
<svg class="logo" fill="none" viewBox="0 0 320 286">
53
-
<path
54
-
fill="#0A7AFF"
55
-
d="M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z"
56
-
/>
57
-
</svg>
58
-
</div>
59
-
</div>
60
-
61
-
<div class="name-wrapper">
62
-
<p dir="auto" class="display-name">{profile.displayName?.trim() || profile.handle.slice(0, 64)}</p>
63
-
<p class="handle">@{profile.handle}</p>
64
-
</div>
65
-
66
-
<div class="stats">
67
-
<span class="stat-entry">
68
-
<span class="stat-count">{formatCompactNumber(profile.followersCount || 0)}</span>
69
-
<span> {profile.followersCount === 1 ? `Follower` : `Followers`}</span>
70
-
</span>
71
-
72
-
<span class="stat-entry">
73
-
<span class="stat-count">{formatCompactNumber(profile.followsCount || 0)}</span>
74
-
<span> Following</span>
75
-
</span>
76
-
</div>
77
-
78
-
{#if profile.description?.trim()}
79
-
<RichtextRawRenderer text={profile.description} />
80
-
{/if}
81
-
</div>
82
-
</div>
83
-
84
-
<style>
85
-
.profile-card {
86
-
display: flex;
87
-
flex-direction: column;
88
-
}
89
-
90
-
.is-blurred {
91
-
scale: 125%;
92
-
filter: blur(4px);
93
-
}
94
-
95
-
.banner-wrapper {
96
-
background: var(--background-secondary);
97
-
aspect-ratio: 3 / 1;
98
-
overflow: hidden;
99
-
}
100
-
.banner {
101
-
width: 100%;
102
-
height: 100%;
103
-
object-fit: cover;
104
-
}
105
-
106
-
.contents {
107
-
display: flex;
108
-
position: relative;
109
-
flex-direction: column;
110
-
gap: 8px;
111
-
padding: 12px 16px 16px;
112
-
}
113
-
.logo {
114
-
width: 24px;
115
-
height: 24px;
116
-
}
117
-
118
-
.header {
119
-
display: flex;
120
-
justify-content: space-between;
121
-
align-items: end;
122
-
}
123
-
.actions {
124
-
display: flex;
125
-
align-items: center;
126
-
gap: 16px;
127
-
}
128
-
129
-
.avatar-wrapper {
130
-
display: block;
131
-
flex-shrink: 0;
132
-
outline: 2px solid var(--background-primary);
133
-
border-radius: 9999px;
134
-
background: var(--background-secondary);
135
-
width: 90px;
136
-
height: 90px;
137
-
overflow: hidden;
138
-
139
-
.has-banner & {
140
-
margin-top: calc(-90px + 34px);
141
-
}
142
-
}
143
-
.avatar {
144
-
width: 100%;
145
-
height: 100%;
146
-
object-fit: cover;
147
-
148
-
.avatar-wrapper:hover & {
149
-
filter: brightness(0.85);
150
-
151
-
&.is-blurred {
152
-
filter: brightness(0.85) blur(4px);
153
-
}
154
-
}
155
-
}
156
-
157
-
.follow-button {
158
-
display: flex;
159
-
align-items: center;
160
-
gap: 6px;
161
-
border-radius: 9999px;
162
-
background: var(--button);
163
-
padding: 9px 12px;
164
-
color: var(--button-text);
165
-
font-weight: 600;
166
-
font-size: calc(var(--font-size) * 0.8125);
167
-
line-height: calc(var(--font-size) * 1);
168
-
user-select: none;
169
-
170
-
.icon {
171
-
font-size: 16px;
172
-
}
173
-
174
-
&:hover {
175
-
background: var(--button-hover);
176
-
}
177
-
}
178
-
179
-
.display-name {
180
-
font-weight: 700;
181
-
font-size: calc(var(--font-size) * 1.25);
182
-
line-height: calc(var(--font-size) * 1.75);
183
-
overflow-wrap: break-word;
184
-
}
185
-
.handle {
186
-
color: var(--text-secondary);
187
-
overflow-wrap: break-word;
188
-
}
189
-
190
-
.stats {
191
-
display: flex;
192
-
flex-wrap: wrap;
193
-
gap: 20px;
194
-
195
-
min-width: 0;
196
-
}
197
-
.stat-entry {
198
-
color: var(--text-secondary);
199
-
}
200
-
.stat-count {
201
-
color: var(--text-primary);
202
-
font-weight: 700;
203
-
}
204
-
</style>
-54
packages/internal/components/profile-feed-header.svelte
-54
packages/internal/components/profile-feed-header.svelte
···
1
-
<script lang="ts">
2
-
import type { AppBskyActorDefs } from '@atcute/client/lexicons';
3
-
4
-
import { getProfileUrl } from '../utils/bsky-url';
5
-
6
-
interface Props {
7
-
profile: AppBskyActorDefs.ProfileViewDetailed;
8
-
}
9
-
10
-
const { profile }: Props = $props();
11
-
</script>
12
-
13
-
<div class="profile-feed-header">
14
-
<a target="_blank" href={getProfileUrl(profile.did)} class="title">Posts from @{profile.handle}</a>
15
-
16
-
<svg class="logo" fill="none" viewBox="0 0 320 286">
17
-
<path
18
-
fill="#0A7AFF"
19
-
d="M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z"
20
-
/>
21
-
</svg>
22
-
</div>
23
-
24
-
<style>
25
-
.profile-feed-header {
26
-
display: flex;
27
-
justify-content: space-between;
28
-
align-items: center;
29
-
gap: 16px;
30
-
container-type: inline-size;
31
-
border-bottom: 1px solid var(--divider);
32
-
padding: 12px 16px;
33
-
}
34
-
35
-
.title {
36
-
padding: 4px 0;
37
-
min-width: 0;
38
-
overflow: hidden;
39
-
font-weight: 600;
40
-
font-size: calc(var(--font-size) * 1);
41
-
line-height: calc(var(--font-size) * 1.5);
42
-
text-overflow: ellipsis;
43
-
white-space: nowrap;
44
-
45
-
&:hover {
46
-
text-decoration: underline;
47
-
}
48
-
}
49
-
50
-
.logo {
51
-
width: 24px;
52
-
height: 24px;
53
-
}
54
-
</style>
-53
packages/internal/components/richtext-raw-renderer.svelte
-53
packages/internal/components/richtext-raw-renderer.svelte
···
1
-
<script lang="ts" module>
2
-
const HTTP_RE = /^https?:\/\//;
3
-
</script>
4
-
5
-
<script lang="ts">
6
-
import { tokenize } from '@atcute/bluesky-richtext-parser';
7
-
8
-
import { getHashtagUrl, getProfileUrl } from '../utils/bsky-url';
9
-
10
-
interface Props {
11
-
text: string;
12
-
}
13
-
14
-
const { text }: Props = $props();
15
-
</script>
16
-
17
-
<p class="rich-text is-small">
18
-
{#each tokenize(text) as token}
19
-
{#if token.type === 'autolink'}
20
-
<a target="_blank" href={token.url} rel="noopener nofollow" class="link">
21
-
{token.raw.replace(HTTP_RE, '')}
22
-
</a>
23
-
{:else if token.type === 'mention'}
24
-
<a target="_blank" href={getProfileUrl(token.handle)} class="mention">{token.raw}</a>
25
-
{:else if token.type === 'topic'}
26
-
<a target="_blank" href={getHashtagUrl(token.name)} class="hashtag">{token.raw}</a>
27
-
{:else}
28
-
{token.raw}
29
-
{/if}
30
-
{/each}
31
-
</p>
32
-
33
-
<style>
34
-
.rich-text {
35
-
overflow: hidden;
36
-
white-space: pre-wrap;
37
-
overflow-wrap: break-word;
38
-
39
-
&:empty {
40
-
display: none;
41
-
}
42
-
}
43
-
44
-
.link,
45
-
.mention,
46
-
.hashtag {
47
-
color: var(--text-link);
48
-
49
-
&:hover {
50
-
text-decoration: underline;
51
-
}
52
-
}
53
-
</style>
-66
packages/internal/components/richtext-renderer.svelte
-66
packages/internal/components/richtext-renderer.svelte
···
1
-
<script lang="ts" module>
2
-
import { segmentize, type Facet, type FacetFeature } from '@atcute/bluesky-richtext-segmenter';
3
-
4
-
import { getHashtagUrl, getProfileUrl } from '../utils/bsky-url';
5
-
6
-
const grabFirstSupported = (features: FacetFeature[] | undefined): FacetFeature | undefined => {
7
-
return features?.find(
8
-
(feature) =>
9
-
feature.$type === 'app.bsky.richtext.facet#link' ||
10
-
feature.$type === 'app.bsky.richtext.facet#mention' ||
11
-
feature.$type === 'app.bsky.richtext.facet#tag',
12
-
);
13
-
};
14
-
</script>
15
-
16
-
<script lang="ts">
17
-
interface Props {
18
-
text: string;
19
-
facets?: Facet[];
20
-
large?: boolean;
21
-
}
22
-
23
-
const { text, facets, large }: Props = $props();
24
-
</script>
25
-
26
-
<p class={`rich-text` + (large ? ` is-large` : ` is-small`)}>
27
-
{#each segmentize(text, facets) as segment}
28
-
{@const feature = grabFirstSupported(segment.features)}
29
-
30
-
{#if !feature}
31
-
{segment.text}
32
-
{:else if feature.$type === 'app.bsky.richtext.facet#link'}
33
-
<a target="_blank" href={feature.uri} rel="noopener nofollow" class="link">{segment.text}</a>
34
-
{:else if feature.$type === 'app.bsky.richtext.facet#mention'}
35
-
<a target="_blank" href={getProfileUrl(feature.did)} class="mention">{segment.text}</a>
36
-
{:else if feature.$type === 'app.bsky.richtext.facet#tag'}
37
-
<a target="_blank" href={getHashtagUrl(feature.tag)} class="hashtag">{segment.text}</a>
38
-
{/if}
39
-
{/each}
40
-
</p>
41
-
42
-
<style>
43
-
.rich-text {
44
-
overflow: hidden;
45
-
white-space: pre-wrap;
46
-
overflow-wrap: break-word;
47
-
48
-
&:empty {
49
-
display: none;
50
-
}
51
-
}
52
-
.is-large {
53
-
font-size: calc(var(--font-size) * 1);
54
-
line-height: calc(var(--font-size) * 1.5);
55
-
}
56
-
57
-
.link,
58
-
.mention,
59
-
.hashtag {
60
-
color: var(--text-link);
61
-
62
-
&:hover {
63
-
text-decoration: underline;
64
-
}
65
-
}
66
-
</style>
-34
packages/internal/package.json
-34
packages/internal/package.json
···
1
-
{
2
-
"private": true,
3
-
"type": "module",
4
-
"name": "internal",
5
-
"version": "0.1.0",
6
-
"exports": {
7
-
"./components/*": "./components/*",
8
-
"./types/*": "./types/*",
9
-
"./utils/*": "./utils/*"
10
-
},
11
-
"peerDependencies": {
12
-
"@atcute/bluesky": "^1.0.9",
13
-
"@atcute/bluesky-richtext-parser": "^1.0.7",
14
-
"@atcute/bluesky-richtext-segmenter": "^1.0.5",
15
-
"@atcute/client": "^2.0.6",
16
-
"svelte": "catalog:"
17
-
},
18
-
"peerDependenciesMeta": {
19
-
"@atcute/bluesky-richtext-parser": {
20
-
"optional": true
21
-
},
22
-
"@atcute/bluesky-richtext-segmenter": {
23
-
"optional": true
24
-
}
25
-
},
26
-
"devDependencies": {
27
-
"@atcute/bluesky": "^2.1.1",
28
-
"@atcute/bluesky-richtext-parser": "^1.0.7",
29
-
"@atcute/bluesky-richtext-segmenter": "^2.0.4",
30
-
"@atcute/client": "^3.1.0",
31
-
"@tsconfig/svelte": "^5.0.6",
32
-
"svelte": "catalog:"
33
-
}
34
-
}
-8
packages/internal/svelte.config.js
-8
packages/internal/svelte.config.js
-13
packages/internal/tsconfig.json
-13
packages/internal/tsconfig.json
···
1
-
{
2
-
"extends": "@tsconfig/svelte/tsconfig.json",
3
-
"compilerOptions": {
4
-
"types": ["@atcute/bluesky/lexicons"],
5
-
"target": "ESNext",
6
-
"useDefineForClassFields": true,
7
-
"module": "ESNext",
8
-
"resolveJsonModule": true,
9
-
"isolatedModules": true,
10
-
"moduleDetection": "force",
11
-
"noEmit": true,
12
-
},
13
-
}
-7
packages/internal/types/post.ts
-7
packages/internal/types/post.ts
-6
packages/internal/types/profile-card.ts
-6
packages/internal/types/profile-card.ts
-7
packages/internal/types/profile-feed.ts
-7
packages/internal/types/profile-feed.ts
-27
packages/internal/utils/bsky-url.ts
-27
packages/internal/utils/bsky-url.ts
···
1
-
export const getProfileUrl = (author: string): string => {
2
-
return `https://bsky.app/profile/${author}`;
3
-
};
4
-
5
-
export const getPostUrl = (author: string, rkey: string): string => {
6
-
return `https://bsky.app/profile/${author}/post/${rkey}`;
7
-
};
8
-
9
-
export const getHashtagUrl = (tag: string): string => {
10
-
return `https://bsky.app/hashtag/${tag}`;
11
-
};
12
-
13
-
export const getFeedUrl = (author: string, rkey: string): string => {
14
-
return `https://bsky.app/profile/${author}/feed/${rkey}`;
15
-
};
16
-
17
-
export const getListUrl = (author: string, rkey: string): string => {
18
-
return `https://bsky.app/profile/${author}/list/${rkey}`;
19
-
};
20
-
21
-
export const getStarterpackUrl = (author: string, rkey: string): string => {
22
-
return `https://bsky.app/starter-pack/${author}/${rkey}`;
23
-
};
24
-
25
-
export const getStarterpackImgUrl = (author: string, rkey: string): string => {
26
-
return `https://ogcard.cdn.bsky.app/start/${author}/${rkey}`;
27
-
};
-3
packages/internal/utils/constants.ts
-3
packages/internal/utils/constants.ts
-44
packages/internal/utils/date.ts
-44
packages/internal/utils/date.ts
···
1
-
let startOfYear = 0;
2
-
let endOfYear = 0;
3
-
4
-
const fmtAbsoluteLong = new Intl.DateTimeFormat('en-US', { dateStyle: 'long', timeStyle: 'short' });
5
-
const fmtAbsShortWithYear = new Intl.DateTimeFormat('en-US', { dateStyle: 'medium' });
6
-
const fmtAbsShort = new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric' });
7
-
8
-
export const formatShortDate = (date: string | number): string => {
9
-
const inst = new Date(date);
10
-
const time = inst.getTime();
11
-
12
-
if (isNaN(time)) {
13
-
return 'N/A';
14
-
}
15
-
16
-
const now = Date.now();
17
-
if (now > endOfYear) {
18
-
const date = new Date(now);
19
-
20
-
date.setMonth(0, 1);
21
-
date.setHours(0, 0, 0);
22
-
startOfYear = date.getTime();
23
-
24
-
date.setFullYear(date.getFullYear() + 1, 0, 0);
25
-
date.setHours(23, 59, 59, 999);
26
-
endOfYear = date.getTime();
27
-
}
28
-
29
-
if (time >= startOfYear && time <= endOfYear) {
30
-
return fmtAbsShort.format(inst);
31
-
}
32
-
33
-
return fmtAbsShortWithYear.format(inst);
34
-
};
35
-
36
-
export const formatLongDate = (date: string | number): string => {
37
-
const inst = new Date(date);
38
-
39
-
if (isNaN(inst.getTime())) {
40
-
return 'N/A';
41
-
}
42
-
43
-
return fmtAbsoluteLong.format(inst);
44
-
};
-60
packages/internal/utils/labels.ts
-60
packages/internal/utils/labels.ts
···
1
-
import type { At, ComAtprotoLabelDefs } from '@atcute/client/lexicons';
2
-
3
-
export const FlagsNone = 0;
4
-
export const FlagsNoSelf = 1 << 0;
5
-
6
-
type Label = ComAtprotoLabelDefs.Label;
7
-
8
-
export interface LabelDefinition {
9
-
name: string;
10
-
flags: number;
11
-
}
12
-
13
-
export const LABEL_MAPPING: Record<string, LabelDefinition> = {
14
-
'!hide': {
15
-
name: `Hidden by moderators`,
16
-
flags: FlagsNoSelf,
17
-
},
18
-
'!warn': {
19
-
name: `Content warning`,
20
-
flags: FlagsNoSelf,
21
-
},
22
-
23
-
porn: {
24
-
name: `Adult content`,
25
-
flags: FlagsNone,
26
-
},
27
-
sexual: {
28
-
name: `Sexually suggestive`,
29
-
flags: FlagsNone,
30
-
},
31
-
'graphic-media': {
32
-
name: `Graphic media`,
33
-
flags: FlagsNone,
34
-
},
35
-
nudity: {
36
-
name: `Nudity`,
37
-
flags: FlagsNone,
38
-
},
39
-
};
40
-
41
-
export const findLabel = (labels: Label[] | undefined, authorDid: At.Did): LabelDefinition | undefined => {
42
-
if (labels?.length) {
43
-
for (let idx = 0, len = labels.length; idx < len; idx++) {
44
-
const label = labels[idx];
45
-
const val = label.val;
46
-
47
-
if (!(val in LABEL_MAPPING)) {
48
-
continue;
49
-
}
50
-
51
-
const def = LABEL_MAPPING[val];
52
-
53
-
if (def.flags & FlagsNoSelf && label.src === authorDid) {
54
-
continue;
55
-
}
56
-
57
-
return def;
58
-
}
59
-
}
60
-
};
-18
packages/internal/utils/number.ts
-18
packages/internal/utils/number.ts
···
1
-
const long = new Intl.NumberFormat('en-US');
2
-
const compact = new Intl.NumberFormat('en-US', { notation: 'compact' });
3
-
4
-
export const formatCompactNumber = (value: number) => {
5
-
if (value < 1_000) {
6
-
return '' + value;
7
-
}
8
-
9
-
if (value < 100_000) {
10
-
return long.format(value);
11
-
}
12
-
13
-
return compact.format(value);
14
-
};
15
-
16
-
export const formatLongNumber = (value: number) => {
17
-
return long.format(value);
18
-
};
-27
packages/internal/utils/syntax/at-url.ts
-27
packages/internal/utils/syntax/at-url.ts
···
1
-
export const AT_URI_RE =
2
-
/^at:\/\/((?:did:[a-zA-Z0-9._:%-]+)|(?:[a-zA-Z0-9][a-zA-Z0-9-.]*))(?:\/([a-zA-Z0-9.-]+)(?:\/([a-zA-Z0-9_~.:-]{1,512}))?)?\/?(?:\?([^#\s]*))?(?:#([^\s]*))?$/;
3
-
4
-
export interface ParsedAtUri {
5
-
repo: string;
6
-
collection: string;
7
-
rkey: string;
8
-
query: string;
9
-
fragment: string;
10
-
}
11
-
12
-
export const parseAtUri = (str: string): ParsedAtUri => {
13
-
const match = AT_URI_RE.exec(str);
14
-
if (!match) {
15
-
throw new InvalidAtUriError(`invalid at-uri: ${str}`);
16
-
}
17
-
18
-
return {
19
-
repo: match[1],
20
-
collection: match[2] ?? '',
21
-
rkey: match[3] ?? '',
22
-
query: match[4] ?? '',
23
-
fragment: match[5] ?? '',
24
-
};
25
-
};
26
-
27
-
export class InvalidAtUriError extends Error {}
-1
packages/svelte-site/.gitignore
-1
packages/svelte-site/.gitignore
···
1
-
pages/
-66
packages/svelte-site/README.md
-66
packages/svelte-site/README.md
···
1
-
# Svelte + TS + Vite
2
-
3
-
This template should help get you started developing with Svelte and TypeScript in Vite.
4
-
5
-
## Recommended IDE Setup
6
-
7
-
[VS Code](https://code.visualstudio.com/) +
8
-
[Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
9
-
10
-
## Need an official Svelte framework?
11
-
12
-
Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy
13
-
anywhere with its serverless-first approach and adapt to various platforms, with out of the box
14
-
support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS,
15
-
Tailwind CSS, and more.
16
-
17
-
## Technical considerations
18
-
19
-
**Why use this over SvelteKit?**
20
-
21
-
- It brings its own routing solution which might not be preferable for some users.
22
-
- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app.
23
-
24
-
This template contains as little as possible to get started with Vite + TypeScript + Svelte, while
25
-
taking into account the developer experience with regards to HMR and intellisense. It demonstrates
26
-
capabilities on par with the other `create-vite` templates and is a good starting point for
27
-
beginners dipping their toes into a Vite + Svelte project.
28
-
29
-
Should you later need the extended capabilities and extensibility provided by SvelteKit, the
30
-
template has been structured similarly to SvelteKit so that it is easy to migrate.
31
-
32
-
**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?**
33
-
34
-
Setting `compilerOptions.types` shuts out all other types not explicitly listed in the
35
-
configuration. Using triple-slash references keeps the default TypeScript setting of accepting type
36
-
information from the entire workspace, while also adding `svelte` and `vite/client` type
37
-
information.
38
-
39
-
**Why include `.vscode/extensions.json`?**
40
-
41
-
Other templates indirectly recommend extensions via the README, but this file allows VS Code to
42
-
prompt the user to install the recommended extension upon opening the project.
43
-
44
-
**Why enable `allowJs` in the TS template?**
45
-
46
-
While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not
47
-
prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force
48
-
`checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase
49
-
is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there
50
-
are valid use cases in which a mixed codebase may be relevant.
51
-
52
-
**Why is HMR not preserving my local component state?**
53
-
54
-
HMR state preservation comes with a number of gotchas! It has been disabled by default in both
55
-
`svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read
56
-
the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr).
57
-
58
-
If you have state that's important to retain within a component, consider creating an external store
59
-
which would not be replaced by HMR.
60
-
61
-
```ts
62
-
// store.ts
63
-
// An extremely simple external store
64
-
import { writable } from 'svelte/store';
65
-
export default writable(0);
66
-
```
-12
packages/svelte-site/index.html
-12
packages/svelte-site/index.html
···
1
-
<!doctype html>
2
-
<html lang="en">
3
-
<head>
4
-
<meta charset="UTF-8" />
5
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
-
<title>Bluesky embed</title>
7
-
</head>
8
-
<body>
9
-
<div id="app"></div>
10
-
<script type="module" src="./src/main.ts"></script>
11
-
</body>
12
-
</html>
-30
packages/svelte-site/package.json
-30
packages/svelte-site/package.json
···
1
-
{
2
-
"name": "svelte-site",
3
-
"private": true,
4
-
"version": "0.0.0",
5
-
"type": "module",
6
-
"scripts": {
7
-
"dev": "vite",
8
-
"build": "vite build",
9
-
"preview": "vite preview",
10
-
"check": "svelte-check --tsconfig ./tsconfig.json && tsc -p tsconfig.node.json",
11
-
"publish": "pnpm run build && ./scripts/publish.sh"
12
-
},
13
-
"dependencies": {
14
-
"@atcute/bluesky": "^2.1.1",
15
-
"@atcute/client": "^3.1.0",
16
-
"bluesky-post-embed": "workspace:^",
17
-
"bluesky-profile-card-embed": "workspace:^",
18
-
"bluesky-profile-feed-embed": "workspace:^",
19
-
"internal": "workspace:^"
20
-
},
21
-
"devDependencies": {
22
-
"@sveltejs/vite-plugin-svelte": "^6.2.1",
23
-
"@tsconfig/svelte": "^5.0.6",
24
-
"svelte": "^5.45.5",
25
-
"svelte-check": "^4.3.4",
26
-
"terser": "^5.44.1",
27
-
"tslib": "^2.8.1",
28
-
"vite": "^7.2.6"
29
-
}
30
-
}
-18
packages/svelte-site/scripts/publish.sh
-18
packages/svelte-site/scripts/publish.sh
···
1
-
#!/usr/bin/env bash
2
-
3
-
set -euo pipefail
4
-
5
-
if [[ -n $(git status --porcelain) ]]; then
6
-
echo 'Working directory is not clean'
7
-
git status --short
8
-
exit 1
9
-
fi
10
-
11
-
GIT_COMMIT=$(git rev-parse HEAD)
12
-
13
-
rsync -aHAX --delete --exclude=.git --exclude=.nojekyll dist/ pages/
14
-
touch pages/.nojekyll
15
-
16
-
git -C pages/ add .
17
-
git -C pages/ commit -m "deploy: ${GIT_COMMIT}"
18
-
git -C pages/ push
-159
packages/svelte-site/src/App.svelte
-159
packages/svelte-site/src/App.svelte
···
1
-
<script lang="ts" module>
2
-
const PostDisplay = () => import('./components/display/PostDisplay.svelte');
3
-
const ProfileCardDisplay = () => import('./components/display/ProfileCardDisplay.svelte');
4
-
const ProfileFeedDisplay = () => import('./components/display/ProfileFeedDisplay.svelte');
5
-
</script>
6
-
7
-
<script lang="ts">
8
-
import { extract_url } from './lib/matcher';
9
-
10
-
import Banner from './components/Banner.svelte';
11
-
import CircularSpinner from './components/CircularSpinner.svelte';
12
-
import Field from './components/Field.svelte';
13
-
import Lazy from './components/Lazy.svelte';
14
-
import TextInput from './components/TextInput.svelte';
15
-
16
-
const DEFAULT_URL = 'https://bsky.app/profile/did:plc:ragtjsm2j2vknwkz3zp4oxrd/post/3kj2umze7zj2n';
17
-
// const DEFAULT_URL = 'https://bsky.app/profile/did:plc:ragtjsm2j2vknwkz3zp4oxrd';
18
-
19
-
let url = $state('');
20
-
let profile_type = $state<'card' | 'feed'>('feed');
21
-
22
-
const matched = $derived(extract_url(url || DEFAULT_URL));
23
-
</script>
24
-
25
-
<div class="app">
26
-
<h1 class="header">
27
-
<code><bluesky-embed></code>
28
-
</h1>
29
-
30
-
<Field label="Bluesky post or profile URL">
31
-
<TextInput type="url" bind:value={url} placeholder={DEFAULT_URL} />
32
-
</Field>
33
-
34
-
{#if matched && matched.type === 'profile'}
35
-
<fieldset class="choices">
36
-
<label class="choice">
37
-
<input type="radio" name="profile-type" value="feed" bind:group={profile_type} />
38
-
<span>Profile feed</span>
39
-
</label>
40
-
41
-
<label class="choice">
42
-
<input type="radio" name="profile-type" value="card" bind:group={profile_type} />
43
-
<span>Profile card</span>
44
-
</label>
45
-
</fieldset>
46
-
{/if}
47
-
48
-
<main class="main">
49
-
{#if !matched}
50
-
<Banner type="alert">Invalid URL, did you type it correctly?</Banner>
51
-
{:else if matched.type === 'post'}
52
-
<Lazy loader={PostDisplay} fallback={LazyFallback} boundary={LazyBoundary}>
53
-
{#snippet children(Component)}
54
-
<Component {matched} />
55
-
{/snippet}
56
-
</Lazy>
57
-
{:else if matched.type === 'profile'}
58
-
<Lazy
59
-
loader={profile_type === 'card' ? ProfileCardDisplay : ProfileFeedDisplay}
60
-
fallback={LazyFallback}
61
-
boundary={LazyBoundary}
62
-
>
63
-
{#snippet children(Component)}
64
-
<Component {matched} />
65
-
{/snippet}
66
-
</Lazy>
67
-
{/if}
68
-
</main>
69
-
70
-
<footer class="footer">
71
-
<span>
72
-
made with โค๏ธ by <a href="https://bsky.app/profile/did:plc:ia76kvnndjutgedggx2ibrem">@mary.my.id</a>
73
-
</span>
74
-
<span aria-hidden="true"> ยท </span>
75
-
<span>
76
-
<a href="https://github.com/mary-ext/bluesky-embed">source code</a>
77
-
</span>
78
-
<span aria-hidden="true"> ยท </span>
79
-
<span>MIT License</span>
80
-
</footer>
81
-
</div>
82
-
83
-
{#snippet LazyFallback()}
84
-
<CircularSpinner />
85
-
{/snippet}
86
-
87
-
{#snippet LazyBoundary(err: unknown)}
88
-
<Banner type="alert">
89
-
{'' + err}
90
-
</Banner>
91
-
{/snippet}
92
-
93
-
<style>
94
-
.app {
95
-
margin: 0 auto;
96
-
padding: 36px 16px;
97
-
width: 100%;
98
-
max-width: calc(550px + (16 * 2px));
99
-
}
100
-
101
-
.header {
102
-
margin: 24px 0;
103
-
}
104
-
105
-
.main {
106
-
margin: 36px 0;
107
-
}
108
-
109
-
.choices {
110
-
display: flex;
111
-
flex-direction: column;
112
-
gap: 8px;
113
-
margin: 16px 0 36px 0;
114
-
border: 0;
115
-
padding: 0;
116
-
}
117
-
.choice {
118
-
display: flex;
119
-
align-items: center;
120
-
gap: 8px;
121
-
font-size: 0.875rem;
122
-
line-height: 1.25rem;
123
-
124
-
input {
125
-
appearance: none;
126
-
outline: 2px none #2563eb;
127
-
outline-offset: 2px;
128
-
border: 1px solid #9ca3af;
129
-
border-radius: 8px;
130
-
width: 16px;
131
-
height: 16px;
132
-
133
-
&:checked {
134
-
border: 0;
135
-
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
136
-
background-color: #2563eb;
137
-
}
138
-
&:focus {
139
-
outline-style: solid;
140
-
}
141
-
}
142
-
}
143
-
144
-
.footer {
145
-
display: flex;
146
-
flex-wrap: wrap;
147
-
gap: 0.5rem;
148
-
margin: 36px 0 0 0;
149
-
border-top: 1px solid #d1d5db;
150
-
padding: 36px 0 0 0;
151
-
color: #4b5563;
152
-
font-size: 0.875rem;
153
-
line-height: 1.25rem;
154
-
155
-
a {
156
-
color: #2563eb;
157
-
}
158
-
}
159
-
</style>
-42
packages/svelte-site/src/components/Banner.svelte
-42
packages/svelte-site/src/components/Banner.svelte
···
1
-
<script lang="ts">
2
-
import type { Snippet } from 'svelte';
3
-
4
-
interface Props {
5
-
type: 'alert' | 'inform';
6
-
children: Snippet<[]>;
7
-
}
8
-
9
-
let { type, children }: Props = $props();
10
-
</script>
11
-
12
-
<div class="banner" class:type-alert={type === 'alert'} class:type-inform={type === 'inform'}>
13
-
{@render children()}
14
-
</div>
15
-
16
-
<style>
17
-
.banner {
18
-
border: 1px solid;
19
-
border-radius: 4px;
20
-
padding: 10px 12px;
21
-
font-weight: 500;
22
-
font-size: 0.875rem;
23
-
line-height: 1.25rem;
24
-
25
-
:global(a) {
26
-
color: inherit;
27
-
font-weight: 600;
28
-
}
29
-
}
30
-
31
-
.type-alert {
32
-
border-color: #fca5a5;
33
-
background: #fee2e2;
34
-
color: #991b1b;
35
-
}
36
-
37
-
.type-inform {
38
-
border-color: #bfdbfe;
39
-
background: #dbeafe;
40
-
color: #1e40af;
41
-
}
42
-
</style>
-42
packages/svelte-site/src/components/CircularSpinner.svelte
-42
packages/svelte-site/src/components/CircularSpinner.svelte
···
1
-
<script lang="ts">
2
-
interface Props {}
3
-
4
-
let {}: Props = $props();
5
-
</script>
6
-
7
-
<svg viewBox="0 0 32 32" class="circular-spinner">
8
-
<circle cx="16" cy="16" fill="none" r="14" stroke-width="4" class="background" />
9
-
<circle
10
-
cx="16"
11
-
cy="16"
12
-
fill="none"
13
-
r="14"
14
-
stroke-width="4"
15
-
stroke-dasharray="80px"
16
-
stroke-dashoffset="60px"
17
-
class="accented"
18
-
/>
19
-
</svg>
20
-
21
-
<style>
22
-
.circular-spinner {
23
-
display: block;
24
-
animation: spin 1s linear infinite;
25
-
margin: 0 auto;
26
-
width: 24px;
27
-
height: 24px;
28
-
}
29
-
@keyframes spin {
30
-
to {
31
-
transform: rotate(360deg);
32
-
}
33
-
}
34
-
35
-
.accented {
36
-
stroke: #2563eb;
37
-
}
38
-
.background {
39
-
opacity: 20%;
40
-
stroke: #2563eb;
41
-
}
42
-
</style>
-100
packages/svelte-site/src/components/CodeBlock.svelte
-100
packages/svelte-site/src/components/CodeBlock.svelte
···
1
-
<script lang="ts">
2
-
interface Props {
3
-
code: string;
4
-
}
5
-
6
-
let { code }: Props = $props();
7
-
</script>
8
-
9
-
<div class="code-block">
10
-
<pre><code>{code}</code></pre>
11
-
12
-
<div class="actions">
13
-
<button
14
-
title="Copy"
15
-
aria-label="Copy"
16
-
class="action-button"
17
-
onclick={() => {
18
-
navigator.clipboard.writeText(code).catch(() => alert(`Failed to copy to clipboard`));
19
-
}}
20
-
>
21
-
<svg class="icon" fill="none" viewBox="0 0 24 24">
22
-
<path
23
-
stroke="currentColor"
24
-
stroke-linecap="square"
25
-
stroke-width="2"
26
-
d="M15 5h4v16H5V5h4m0-2h6v4H9V3Z"
27
-
/>
28
-
</svg>
29
-
</button>
30
-
</div>
31
-
</div>
32
-
33
-
<style>
34
-
.code-block {
35
-
display: flex;
36
-
gap: 12px;
37
-
border: 1px solid #d1d5db;
38
-
border-radius: 4px;
39
-
background: #f9fafb;
40
-
padding: 12px;
41
-
overflow: hidden;
42
-
overflow-x: auto;
43
-
44
-
pre {
45
-
flex-grow: 1;
46
-
margin: 0;
47
-
font-size: 0.75rem;
48
-
line-height: 1.25rem;
49
-
}
50
-
}
51
-
52
-
.actions {
53
-
position: sticky;
54
-
top: 0;
55
-
right: 0;
56
-
}
57
-
.action-button {
58
-
display: flex;
59
-
justify-content: center;
60
-
align-items: center;
61
-
cursor: pointer;
62
-
box-shadow:
63
-
0 1px 3px 0 rgb(0 0 0 / 0.1),
64
-
0 1px 2px -1px rgb(0 0 0 / 0.1);
65
-
border: 1px solid #d1d5db;
66
-
border-radius: 4px;
67
-
background: #ffffff;
68
-
padding: 0;
69
-
width: 32px;
70
-
height: 32px;
71
-
color: #4b5563;
72
-
73
-
@media (pointer: fine) {
74
-
opacity: 0;
75
-
transition: 75ms ease-in;
76
-
77
-
.code-block:hover &,
78
-
.code-block:focus-within & {
79
-
opacity: 1;
80
-
}
81
-
82
-
&:hover {
83
-
border-color: #9ca3af;
84
-
background: #e5e7eb;
85
-
color: #1f2937;
86
-
}
87
-
}
88
-
89
-
&:active {
90
-
border-color: #9ca3af;
91
-
background: #e5e7eb;
92
-
color: #1f2937;
93
-
}
94
-
}
95
-
96
-
.icon {
97
-
width: 16px;
98
-
height: 16px;
99
-
}
100
-
</style>
-36
packages/svelte-site/src/components/Field.svelte
-36
packages/svelte-site/src/components/Field.svelte
···
1
-
<script lang="ts">
2
-
import type { Snippet } from 'svelte';
3
-
4
-
interface Props {
5
-
label: string;
6
-
children: Snippet;
7
-
}
8
-
9
-
let { label, children }: Props = $props();
10
-
</script>
11
-
12
-
<div class="field">
13
-
<label class="input-wrapper">
14
-
<span class="label">{label}</span>
15
-
{@render children()}
16
-
</label>
17
-
</div>
18
-
19
-
<style>
20
-
.field {
21
-
display: flex;
22
-
flex-direction: column;
23
-
gap: 8px;
24
-
}
25
-
26
-
.input-wrapper {
27
-
display: contents;
28
-
}
29
-
30
-
.label {
31
-
color: #4b5563;
32
-
font-weight: 600;
33
-
font-size: 0.875rem;
34
-
line-height: 1.25rem;
35
-
}
36
-
</style>
-37
packages/svelte-site/src/components/Lazy.svelte
-37
packages/svelte-site/src/components/Lazy.svelte
···
1
-
<script lang="ts" module>
2
-
import type { Snippet, Component } from 'svelte';
3
-
4
-
type SvelteComponentModule<C extends Component = Component> = { default: C };
5
-
type LoaderFunction<C extends Component = Component> = () => Promise<SvelteComponentModule<C>>;
6
-
7
-
const map = new WeakMap<LoaderFunction, Promise<Component>>();
8
-
const get_promise = <C extends Component>(fn: LoaderFunction<C>): Promise<C> => {
9
-
let promise = map.get(fn) satisfies Promise<Component> | undefined;
10
-
if (promise === undefined) {
11
-
map.set(fn, (promise = fn().then((mod) => mod.default)));
12
-
}
13
-
14
-
return promise as Promise<C>;
15
-
};
16
-
</script>
17
-
18
-
<script lang="ts" generics="C extends Component<any>">
19
-
interface Props {
20
-
loader: LoaderFunction<C>;
21
-
children: Snippet<[component: C]>;
22
-
fallback: Snippet<[]>;
23
-
boundary: Snippet<[error: unknown]>;
24
-
}
25
-
26
-
let { loader, children, fallback, boundary }: Props = $props();
27
-
28
-
const promise = $derived(get_promise(loader));
29
-
</script>
30
-
31
-
{#await promise}
32
-
{@render fallback()}
33
-
{:then component}
34
-
{@render children(component)}
35
-
{:catch err}
36
-
{@render boundary(err)}
37
-
{/await}
-30
packages/svelte-site/src/components/TextInput.svelte
-30
packages/svelte-site/src/components/TextInput.svelte
···
1
-
<script lang="ts">
2
-
interface Props {
3
-
type?: 'text' | 'url';
4
-
value?: string;
5
-
placeholder?: string;
6
-
}
7
-
8
-
let { type, value = $bindable(), placeholder }: Props = $props();
9
-
</script>
10
-
11
-
<input {type} {placeholder} bind:value class="text-input" />
12
-
13
-
<style>
14
-
.text-input {
15
-
outline: 2px none #2563eb;
16
-
outline-offset: -1px;
17
-
border: 1px solid #9ca3af;
18
-
border-radius: 4px;
19
-
padding: 8px 12px;
20
-
font-size: 0.875rem;
21
-
line-height: 1.25rem;
22
-
23
-
&::placeholder {
24
-
color: #9ca3af;
25
-
}
26
-
&:focus {
27
-
outline-style: solid;
28
-
}
29
-
}
30
-
</style>
-115
packages/svelte-site/src/components/display/PostDisplay.svelte
-115
packages/svelte-site/src/components/display/PostDisplay.svelte
···
1
-
<script lang="ts">
2
-
import { onDestroy } from 'svelte';
3
-
4
-
import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/client/lexicons';
5
-
import { fetchPost as fetch_post } from 'bluesky-post-embed/core';
6
-
7
-
import { getPostUrl } from 'internal/utils/bsky-url.ts';
8
-
import { formatLongDate } from 'internal/utils/date.ts';
9
-
import { parseAtUri } from 'internal/utils/syntax/at-url.ts';
10
-
11
-
import { escape_html } from '../../lib/html';
12
-
import type { ExtractedPostInfo } from '../../lib/matcher';
13
-
14
-
import Banner from '../Banner.svelte';
15
-
import CircularSpinner from '../CircularSpinner.svelte';
16
-
import CodeBlock from '../CodeBlock.svelte';
17
-
import BlueskyPost from '../embeds/BlueskyPost.svelte';
18
-
import Guide from '../guides/Guide.svelte';
19
-
import GuideInstructions from '../guides/GuideInstructions.svelte';
20
-
21
-
interface Props {
22
-
matched: ExtractedPostInfo;
23
-
}
24
-
25
-
let { matched }: Props = $props();
26
-
27
-
let controller: AbortController | undefined;
28
-
const promise = $derived.by(() => {
29
-
controller?.abort();
30
-
controller = new AbortController();
31
-
32
-
const signal = controller.signal;
33
-
const uri = `at://${matched.author}/app.bsky.feed.post/${matched.rkey}`;
34
-
35
-
return fetch_post({ uri, signal });
36
-
});
37
-
38
-
onDestroy(() => {
39
-
controller?.abort();
40
-
});
41
-
42
-
const JSDELIVR_URL = `https://cdn.jsdelivr.net/npm/bluesky-post-embed@^1.0.0`;
43
-
const get_prerequisite_markup = () => {
44
-
return `<!-- Core web component and styling -->
45
-
<script type="module" src="${JSDELIVR_URL}/+esm"></${'script'}>
46
-
<link rel="stylesheet" href="${JSDELIVR_URL}/dist/core.min.css">
47
-
48
-
<!-- Built-in themes -->
49
-
<link rel="stylesheet" href="${JSDELIVR_URL}/themes/light.min.css" media="(prefers-color-scheme: light)">
50
-
<link rel="stylesheet" href="${JSDELIVR_URL}/themes/dim.min.css" media="(prefers-color-scheme: dark)">
51
-
52
-
<!-- Fallback/placeholder elements if JS script is taking a while to load or is failing -->
53
-
<style>
54
-
.bluesky-post-fallback {
55
-
margin: 16px 0;
56
-
border-left: 3px solid var(--divider);
57
-
padding: 4px 8px;
58
-
white-space: pre-wrap;
59
-
overflow-wrap: break-word;
60
-
}
61
-
.bluesky-post-fallback p {
62
-
margin: 0 0 8px 0;
63
-
}
64
-
</${'style'}>
65
-
`;
66
-
};
67
-
68
-
const get_markup = (post: AppBskyFeedDefs.PostView) => {
69
-
const author = post.author;
70
-
const record = post.record as AppBskyFeedPost.Record;
71
-
72
-
return `<bluesky-post src="${escape_html(post.uri)}">
73
-
<blockquote class="bluesky-post-fallback">
74
-
<p dir="auto">${escape_html(record.text)}</p>
75
-
โ ${author.displayName?.trim() ? `${escape_html(author.displayName)} (@${escape_html(author.handle)})` : `@${escape_html(author.handle)}`}
76
-
<a href="${escape_html(getPostUrl(author.did, parseAtUri(post.uri).rkey))}">${formatLongDate(post.indexedAt)}</a>
77
-
</blockquote>
78
-
</bluesky-post>
79
-
`;
80
-
};
81
-
</script>
82
-
83
-
{#await promise}
84
-
<CircularSpinner />
85
-
{:then data}
86
-
<BlueskyPost {data} />
87
-
88
-
{#if data.thread}
89
-
<Guide title="How do I embed this to my website?">
90
-
<Banner type="inform">
91
-
Doing server-side rendering? Check out examples for
92
-
<a href="https://github.com/mary-ext/bluesky-embed-astro">Astro</a> and
93
-
<a href="https://github.com/mary-ext/bluesky-embed-sveltekit">SvelteKit</a>.
94
-
</Banner>
95
-
96
-
<GuideInstructions>
97
-
<li>
98
-
<p>
99
-
Insert the following scripts and stylesheets to the <code><head></code> of your website.
100
-
</p>
101
-
<CodeBlock code={get_prerequisite_markup()} />
102
-
</li>
103
-
104
-
<li>
105
-
<p>Insert the following markup in wherever you want the post to be.</p>
106
-
<CodeBlock code={get_markup(data.thread.post)} />
107
-
</li>
108
-
</GuideInstructions>
109
-
</Guide>
110
-
{/if}
111
-
{:catch err}
112
-
<Banner type="alert">
113
-
{'' + err}
114
-
</Banner>
115
-
{/await}
-93
packages/svelte-site/src/components/display/ProfileCardDisplay.svelte
-93
packages/svelte-site/src/components/display/ProfileCardDisplay.svelte
···
1
-
<script lang="ts">
2
-
import { onDestroy } from 'svelte';
3
-
4
-
import type { AppBskyActorDefs } from '@atcute/client/lexicons';
5
-
import { fetchProfileCard as fetch_profile_card } from 'bluesky-profile-card-embed/core';
6
-
7
-
import { escape_html } from '../../lib/html';
8
-
import type { ExtractedProfileInfo } from '../../lib/matcher';
9
-
10
-
import Banner from '../Banner.svelte';
11
-
import CircularSpinner from '../CircularSpinner.svelte';
12
-
import CodeBlock from '../CodeBlock.svelte';
13
-
import BlueskyProfileCard from '../embeds/BlueskyProfileCard.svelte';
14
-
import Guide from '../guides/Guide.svelte';
15
-
import GuideInstructions from '../guides/GuideInstructions.svelte';
16
-
17
-
interface Props {
18
-
matched: ExtractedProfileInfo;
19
-
}
20
-
21
-
let { matched }: Props = $props();
22
-
23
-
let controller: AbortController | undefined;
24
-
const promise = $derived.by(() => {
25
-
controller?.abort();
26
-
controller = new AbortController();
27
-
28
-
const signal = controller.signal;
29
-
const actor = matched.actor;
30
-
31
-
return fetch_profile_card({ actor, signal });
32
-
});
33
-
34
-
onDestroy(() => {
35
-
controller?.abort();
36
-
});
37
-
38
-
const get_prerequisite_markup = () => {
39
-
const JSDELIVR_URL = `https://cdn.jsdelivr.net/npm/bluesky-profile-card-embed@^1.0.0`;
40
-
41
-
return `<!-- Core web component and styling -->
42
-
<script type="module" src="${JSDELIVR_URL}/+esm"></${'script'}>
43
-
<link rel="stylesheet" href="${JSDELIVR_URL}/dist/core.min.css">
44
-
45
-
<!-- Built-in themes -->
46
-
<link rel="stylesheet" href="${JSDELIVR_URL}/themes/light.min.css" media="(prefers-color-scheme: light)">
47
-
<link rel="stylesheet" href="${JSDELIVR_URL}/themes/dim.min.css" media="(prefers-color-scheme: dark)">
48
-
`;
49
-
};
50
-
51
-
const get_markup = (profile: AppBskyActorDefs.ProfileViewDetailed) => {
52
-
const url = `https://bsky.app/profile/${profile.did}`;
53
-
54
-
return `<bluesky-profile-card actor="${escape_html(profile.did)}">
55
-
<a target="_blank" href="${escape_html(url)}" class="bluesky-profile-card-fallback">
56
-
${
57
-
profile.displayName?.trim()
58
-
? `Follow ${escape_html(profile.displayName)} (@${escape_html(profile.handle)}) on Bluesky`
59
-
: `Follow @${escape_html(profile.handle)} on Bluesky`
60
-
}
61
-
</a>
62
-
</bluesky-profile-card>
63
-
`;
64
-
};
65
-
</script>
66
-
67
-
{#await promise}
68
-
<CircularSpinner />
69
-
{:then data}
70
-
<BlueskyProfileCard {data} />
71
-
72
-
{#if data.profile}
73
-
<Guide title="How do I embed this to my website?">
74
-
<GuideInstructions>
75
-
<li>
76
-
<p>
77
-
Insert the following scripts and stylesheets to the <code><head></code> of your website.
78
-
</p>
79
-
<CodeBlock code={get_prerequisite_markup()} />
80
-
</li>
81
-
82
-
<li>
83
-
<p>Insert the following markup in wherever you want the profile feed to be.</p>
84
-
<CodeBlock code={get_markup(data.profile)} />
85
-
</li>
86
-
</GuideInstructions>
87
-
</Guide>
88
-
{/if}
89
-
{:catch err}
90
-
<Banner type="alert">
91
-
{'' + err}
92
-
</Banner>
93
-
{/await}
-93
packages/svelte-site/src/components/display/ProfileFeedDisplay.svelte
-93
packages/svelte-site/src/components/display/ProfileFeedDisplay.svelte
···
1
-
<script lang="ts">
2
-
import { onDestroy } from 'svelte';
3
-
4
-
import type { AppBskyActorDefs } from '@atcute/client/lexicons';
5
-
import { fetchProfileFeed as fetch_profile_feed } from 'bluesky-profile-feed-embed/core';
6
-
7
-
import { escape_html } from '../../lib/html';
8
-
import type { ExtractedProfileInfo } from '../../lib/matcher';
9
-
10
-
import Banner from '../Banner.svelte';
11
-
import CircularSpinner from '../CircularSpinner.svelte';
12
-
import CodeBlock from '../CodeBlock.svelte';
13
-
import BlueskyProfileFeed from '../embeds/BlueskyProfileFeed.svelte';
14
-
import Guide from '../guides/Guide.svelte';
15
-
import GuideInstructions from '../guides/GuideInstructions.svelte';
16
-
17
-
interface Props {
18
-
matched: ExtractedProfileInfo;
19
-
}
20
-
21
-
let { matched }: Props = $props();
22
-
23
-
let controller: AbortController | undefined;
24
-
const promise = $derived.by(() => {
25
-
controller?.abort();
26
-
controller = new AbortController();
27
-
28
-
const signal = controller.signal;
29
-
const actor = matched.actor;
30
-
31
-
return fetch_profile_feed({ actor, signal });
32
-
});
33
-
34
-
onDestroy(() => {
35
-
controller?.abort();
36
-
});
37
-
38
-
const get_prerequisite_markup = () => {
39
-
const JSDELIVR_URL = `https://cdn.jsdelivr.net/npm/bluesky-profile-feed-embed@^1.0.0`;
40
-
41
-
return `<!-- Core web component and styling -->
42
-
<script type="module" src="${JSDELIVR_URL}/+esm"></${'script'}>
43
-
<link rel="stylesheet" href="${JSDELIVR_URL}/dist/core.min.css">
44
-
45
-
<!-- Built-in themes -->
46
-
<link rel="stylesheet" href="${JSDELIVR_URL}/themes/light.min.css" media="(prefers-color-scheme: light)">
47
-
<link rel="stylesheet" href="${JSDELIVR_URL}/themes/dim.min.css" media="(prefers-color-scheme: dark)">
48
-
`;
49
-
};
50
-
51
-
const get_markup = (profile: AppBskyActorDefs.ProfileViewDetailed) => {
52
-
const url = `https://bsky.app/profile/${profile.did}`;
53
-
54
-
return `<bluesky-profile-feed actor="${escape_html(profile.did)}" include-pins>
55
-
<a target="_blank" href="${escape_html(url)}" class="bluesky-profile-feed-fallback">
56
-
${
57
-
profile.displayName?.trim()
58
-
? `Posts by ${escape_html(profile.displayName)} (@${escape_html(profile.handle)})`
59
-
: `Posts by @${escape_html(profile.handle)}`
60
-
}
61
-
</a>
62
-
</bluesky-profile-feed>
63
-
`;
64
-
};
65
-
</script>
66
-
67
-
{#await promise}
68
-
<CircularSpinner />
69
-
{:then data}
70
-
<BlueskyProfileFeed {data} />
71
-
72
-
{#if data.profile}
73
-
<Guide title="How do I embed this to my website?">
74
-
<GuideInstructions>
75
-
<li>
76
-
<p>
77
-
Insert the following scripts and stylesheets to the <code><head></code> of your website.
78
-
</p>
79
-
<CodeBlock code={get_prerequisite_markup()} />
80
-
</li>
81
-
82
-
<li>
83
-
<p>Insert the following markup in wherever you want the profile feed to be.</p>
84
-
<CodeBlock code={get_markup(data.profile)} />
85
-
</li>
86
-
</GuideInstructions>
87
-
</Guide>
88
-
{/if}
89
-
{:catch err}
90
-
<Banner type="alert">
91
-
{'' + err}
92
-
</Banner>
93
-
{/await}
-12
packages/svelte-site/src/components/embeds/BlueskyPost.svelte
-12
packages/svelte-site/src/components/embeds/BlueskyPost.svelte
···
1
-
<script lang="ts">
2
-
import { type PostData, renderPost } from 'bluesky-post-embed/core';
3
-
import 'bluesky-post-embed/style.css';
4
-
5
-
interface Props {
6
-
data: PostData;
7
-
}
8
-
9
-
let { data }: Props = $props();
10
-
</script>
11
-
12
-
<bluesky-post src={data.thread?.post.uri}>{@html renderPost(data)}</bluesky-post>
-12
packages/svelte-site/src/components/embeds/BlueskyProfileCard.svelte
-12
packages/svelte-site/src/components/embeds/BlueskyProfileCard.svelte
···
1
-
<script lang="ts">
2
-
import { type ProfileCardData, renderProfileCard } from 'bluesky-profile-card-embed/core';
3
-
import 'bluesky-profile-card-embed/style.css';
4
-
5
-
interface Props {
6
-
data: ProfileCardData;
7
-
}
8
-
9
-
let { data }: Props = $props();
10
-
</script>
11
-
12
-
<bluesky-profile-card actor={data.profile?.did}>{@html renderProfileCard(data)}</bluesky-profile-card>
-12
packages/svelte-site/src/components/embeds/BlueskyProfileFeed.svelte
-12
packages/svelte-site/src/components/embeds/BlueskyProfileFeed.svelte
···
1
-
<script lang="ts">
2
-
import { type ProfileFeedData, renderProfileFeed } from 'bluesky-profile-feed-embed/core';
3
-
import 'bluesky-profile-feed-embed/style.css';
4
-
5
-
interface Props {
6
-
data: ProfileFeedData;
7
-
}
8
-
9
-
let { data }: Props = $props();
10
-
</script>
11
-
12
-
<bluesky-profile-feed actor={data.profile?.did}>{@html renderProfileFeed(data)}</bluesky-profile-feed>
-26
packages/svelte-site/src/components/guides/Guide.svelte
-26
packages/svelte-site/src/components/guides/Guide.svelte
···
1
-
<script lang="ts">
2
-
import type { Snippet } from 'svelte';
3
-
4
-
interface Props {
5
-
title: string;
6
-
children: Snippet<[]>;
7
-
}
8
-
9
-
let { title, children }: Props = $props();
10
-
</script>
11
-
12
-
<div class="guide">
13
-
<h4 class="guide-header">{title}</h4>
14
-
15
-
{@render children()}
16
-
</div>
17
-
18
-
<style>
19
-
.guide {
20
-
margin: 36px 0 0 0;
21
-
border-top: 1px solid #d1d5db;
22
-
}
23
-
.guide-header {
24
-
margin: 36px 0 16px 0;
25
-
}
26
-
</style>
-26
packages/svelte-site/src/components/guides/GuideInstructions.svelte
-26
packages/svelte-site/src/components/guides/GuideInstructions.svelte
···
1
-
<script lang="ts">
2
-
import type { Snippet } from 'svelte';
3
-
4
-
interface Props {
5
-
children: Snippet<[]>;
6
-
}
7
-
8
-
let { children }: Props = $props();
9
-
</script>
10
-
11
-
<ol class="guide-instructions">
12
-
{@render children()}
13
-
</ol>
14
-
15
-
<style>
16
-
.guide-instructions {
17
-
margin: 24px 0 0 0;
18
-
padding: 0 0 0 22px;
19
-
font-size: 0.875rem;
20
-
line-height: 1.25rem;
21
-
22
-
:global(li + li) {
23
-
margin: 24px 0 0 0;
24
-
}
25
-
}
26
-
</style>
-4
packages/svelte-site/src/lib/component.ts
-4
packages/svelte-site/src/lib/component.ts
-3
packages/svelte-site/src/lib/html.ts
-3
packages/svelte-site/src/lib/html.ts
-60
packages/svelte-site/src/lib/matcher.ts
-60
packages/svelte-site/src/lib/matcher.ts
···
1
-
import { is_at_identifier, is_tid } from './strings';
2
-
3
-
export interface ExtractedPostInfo {
4
-
type: 'post';
5
-
author: string;
6
-
rkey: string;
7
-
}
8
-
9
-
export interface ExtractedProfileInfo {
10
-
type: 'profile';
11
-
actor: string;
12
-
}
13
-
14
-
export type ExtractedInfo = ExtractedPostInfo | ExtractedProfileInfo;
15
-
16
-
export const extract_url = (str: string): ExtractedInfo | null => {
17
-
const url = safe_parse_url(str);
18
-
if (!url) {
19
-
return null;
20
-
}
21
-
22
-
let match: RegExpExecArray | null | undefined;
23
-
if (url.host === 'bsky.app' || url.host === 'staging.bsky.app' || url.host === 'main.bsky.dev') {
24
-
if ((match = /^\/profile\/([^/]+)\/post\/([^/]+)\/?$/.exec(url.pathname))) {
25
-
if (!is_at_identifier(match[1]) || !is_tid(match[2])) {
26
-
return null;
27
-
}
28
-
29
-
return { type: 'post', author: match[1], rkey: match[2] };
30
-
}
31
-
32
-
if ((match = /^\/profile\/([^/]+)\/?$/.exec(url.pathname))) {
33
-
if (!is_at_identifier(match[1])) {
34
-
return null;
35
-
}
36
-
37
-
return { type: 'profile', actor: match[1] };
38
-
}
39
-
}
40
-
41
-
return null;
42
-
};
43
-
44
-
const safe_parse_url = (str: string): URL | null => {
45
-
let url: URL | null | undefined;
46
-
if ('parse' in URL) {
47
-
url = URL.parse(str);
48
-
} else {
49
-
try {
50
-
// @ts-expect-error: `'parse' in URL` is giving truthy
51
-
url = new URL(str);
52
-
} catch {}
53
-
}
54
-
55
-
if (url && (url.protocol === 'https:' || url.protocol === 'http:')) {
56
-
return url;
57
-
}
58
-
59
-
return null;
60
-
};
-28
packages/svelte-site/src/lib/strings.ts
-28
packages/svelte-site/src/lib/strings.ts
···
1
-
export const RECORD_KEY_RE = /^(?!\.{1,2}$)[a-zA-Z0-9_~.:-]{1,512}$/;
2
-
3
-
export const is_record_key = (str: string): boolean => {
4
-
return str.length >= 1 && str.length <= 512 && RECORD_KEY_RE.test(str);
5
-
};
6
-
7
-
export const TID_RE = /^[234567abcdefghij][234567abcdefghijklmnopqrstuvwxyz]{12}$/;
8
-
9
-
export const is_tid = (str: string): boolean => {
10
-
return str.length === 13 && TID_RE.test(str);
11
-
};
12
-
13
-
export const DID_RE = /^did:([a-z]+):([a-zA-Z0-9._:%-]*[a-zA-Z0-9._-])$/;
14
-
15
-
export const is_did = (str: string): boolean => {
16
-
return str.length >= 7 && str.length <= 2048 && DID_RE.test(str);
17
-
};
18
-
19
-
export const HANDLE_RE =
20
-
/^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/;
21
-
22
-
export const is_handle = (str: string): boolean => {
23
-
return str.length >= 3 && str.length <= 253 && HANDLE_RE.test(str);
24
-
};
25
-
26
-
export const is_at_identifier = (str: string): boolean => {
27
-
return is_did(str) || is_handle(str);
28
-
};
-10
packages/svelte-site/src/main.ts
-10
packages/svelte-site/src/main.ts
-199
packages/svelte-site/src/styles/normalize.css
-199
packages/svelte-site/src/styles/normalize.css
···
1
-
/*! modern-normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize */
2
-
3
-
/*
4
-
Document
5
-
========
6
-
*/
7
-
8
-
/**
9
-
Use a better box model (opinionated).
10
-
*/
11
-
12
-
*,
13
-
::before,
14
-
::after {
15
-
box-sizing: border-box;
16
-
}
17
-
18
-
html {
19
-
line-height: 1.15; /* 1. Correct the line height in all browsers. */
20
-
/* Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) */
21
-
font-family: 'Inter', 'Roboto', ui-sans-serif, sans-serif, 'Noto Color Emoji', 'Twemoji Mozilla';
22
-
-webkit-text-size-adjust: 100%; /* 2. Prevent adjustments of font size after orientation changes in iOS. */
23
-
tab-size: 4; /* 3. Use a more readable tab size (opinionated). */
24
-
}
25
-
26
-
/*
27
-
Sections
28
-
========
29
-
*/
30
-
31
-
body {
32
-
margin: 0; /* Remove the margin in all browsers. */
33
-
}
34
-
35
-
/*
36
-
Text-level semantics
37
-
====================
38
-
*/
39
-
40
-
/**
41
-
Add the correct font weight in Chrome and Safari.
42
-
*/
43
-
44
-
b,
45
-
strong {
46
-
font-weight: bolder;
47
-
}
48
-
49
-
/**
50
-
1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
51
-
2. Correct the odd 'em' font sizing in all browsers.
52
-
*/
53
-
54
-
code,
55
-
kbd,
56
-
samp,
57
-
pre {
58
-
font-size: 1em; /* 2 */
59
-
font-family: 'JetBrains Mono NL', ui-monospace, monospace; /* 1 */
60
-
}
61
-
62
-
/**
63
-
Add the correct font size in all browsers.
64
-
*/
65
-
66
-
small {
67
-
font-size: 80%;
68
-
}
69
-
70
-
/**
71
-
Prevent 'sub' and 'sup' elements from affecting the line height in all browsers.
72
-
*/
73
-
74
-
sub,
75
-
sup {
76
-
position: relative;
77
-
vertical-align: baseline;
78
-
font-size: 75%;
79
-
line-height: 0;
80
-
}
81
-
82
-
sub {
83
-
bottom: -0.25em;
84
-
}
85
-
86
-
sup {
87
-
top: -0.5em;
88
-
}
89
-
90
-
/*
91
-
Tabular data
92
-
============
93
-
*/
94
-
95
-
/**
96
-
Correct table border color inheritance in Chrome and Safari. (https://issues.chromium.org/issues/40615503, https://bugs.webkit.org/show_bug.cgi?id=195016)
97
-
*/
98
-
99
-
table {
100
-
border-color: currentcolor;
101
-
}
102
-
103
-
/*
104
-
Forms
105
-
=====
106
-
*/
107
-
108
-
/**
109
-
1. Change the font styles in all browsers.
110
-
2. Remove the margin in Firefox and Safari.
111
-
*/
112
-
113
-
button,
114
-
input,
115
-
optgroup,
116
-
select,
117
-
textarea {
118
-
margin: 0; /* 2 */
119
-
font-size: 100%; /* 1 */
120
-
line-height: 1.15; /* 1 */
121
-
font-family: inherit; /* 1 */
122
-
}
123
-
124
-
/**
125
-
Correct the inability to style clickable types in iOS and Safari.
126
-
*/
127
-
128
-
button,
129
-
[type='button'],
130
-
[type='reset'],
131
-
[type='submit'] {
132
-
-webkit-appearance: button;
133
-
}
134
-
135
-
/**
136
-
Remove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.
137
-
*/
138
-
139
-
legend {
140
-
padding: 0;
141
-
}
142
-
143
-
/**
144
-
Add the correct vertical alignment in Chrome and Firefox.
145
-
*/
146
-
147
-
progress {
148
-
vertical-align: baseline;
149
-
}
150
-
151
-
/**
152
-
Correct the cursor style of increment and decrement buttons in Safari.
153
-
*/
154
-
155
-
::-webkit-inner-spin-button,
156
-
::-webkit-outer-spin-button {
157
-
height: auto;
158
-
}
159
-
160
-
/**
161
-
1. Correct the odd appearance in Chrome and Safari.
162
-
2. Correct the outline style in Safari.
163
-
*/
164
-
165
-
[type='search'] {
166
-
-webkit-appearance: textfield; /* 1 */
167
-
outline-offset: -2px; /* 2 */
168
-
}
169
-
170
-
/**
171
-
Remove the inner padding in Chrome and Safari on macOS.
172
-
*/
173
-
174
-
::-webkit-search-decoration {
175
-
-webkit-appearance: none;
176
-
}
177
-
178
-
/**
179
-
1. Correct the inability to style clickable types in iOS and Safari.
180
-
2. Change font properties to 'inherit' in Safari.
181
-
*/
182
-
183
-
::-webkit-file-upload-button {
184
-
-webkit-appearance: button; /* 1 */
185
-
font: inherit; /* 2 */
186
-
}
187
-
188
-
/*
189
-
Interactive
190
-
===========
191
-
*/
192
-
193
-
/*
194
-
Add the correct display in Chrome and Safari.
195
-
*/
196
-
197
-
summary {
198
-
display: list-item;
199
-
}
-2
packages/svelte-site/src/vite-env.d.ts
-2
packages/svelte-site/src/vite-env.d.ts
-7
packages/svelte-site/svelte.config.js
-7
packages/svelte-site/svelte.config.js
-21
packages/svelte-site/tsconfig.json
-21
packages/svelte-site/tsconfig.json
···
1
-
{
2
-
"extends": "@tsconfig/svelte/tsconfig.json",
3
-
"compilerOptions": {
4
-
"target": "ESNext",
5
-
"useDefineForClassFields": true,
6
-
"module": "ESNext",
7
-
"resolveJsonModule": true,
8
-
/**
9
-
* Typecheck JS in `.svelte` and `.js` files by default.
10
-
* Disable checkJs if you'd like to use dynamic types in JS.
11
-
* Note that setting allowJs false does not prevent the use
12
-
* of JS in `.svelte` files.
13
-
*/
14
-
"allowJs": true,
15
-
"checkJs": true,
16
-
"isolatedModules": true,
17
-
"moduleDetection": "force",
18
-
},
19
-
"include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
20
-
"references": [{ "path": "./tsconfig.node.json" }],
21
-
}
-13
packages/svelte-site/tsconfig.node.json
-13
packages/svelte-site/tsconfig.node.json
···
1
-
{
2
-
"compilerOptions": {
3
-
"composite": true,
4
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
5
-
"skipLibCheck": true,
6
-
"module": "ESNext",
7
-
"moduleResolution": "bundler",
8
-
"strict": true,
9
-
"noEmit": true,
10
-
"noUncheckedSideEffectImports": true,
11
-
},
12
-
"include": ["vite.config.ts"],
13
-
}
-15
packages/svelte-site/vite.config.ts
-15
packages/svelte-site/vite.config.ts
···
1
-
import { defineConfig } from 'vite';
2
-
import { svelte } from '@sveltejs/vite-plugin-svelte';
3
-
4
-
// https://vite.dev/config/
5
-
export default defineConfig({
6
-
base: './',
7
-
build: {
8
-
target: 'esnext',
9
-
minify: 'terser',
10
-
},
11
-
esbuild: {
12
-
target: 'esnext',
13
-
},
14
-
plugins: [svelte()],
15
-
});
-1041
patches/svelte.patch
-1041
patches/svelte.patch
···
1
-
diff --git a/src/compiler/phases/3-transform/server/visitors/AwaitBlock.js b/src/compiler/phases/3-transform/server/visitors/AwaitBlock.js
2
-
index b8d2e421440a0f8e5b12c9cb55ed65ab0f5e7a8a..76bb16136e17cb010069eb7fd4d84cb600ad138c 100644
3
-
--- a/src/compiler/phases/3-transform/server/visitors/AwaitBlock.js
4
-
+++ b/src/compiler/phases/3-transform/server/visitors/AwaitBlock.js
5
-
@@ -33,5 +33,5 @@ export function AwaitBlock(node, context) {
6
-
);
7
-
}
8
-
9
-
- context.state.template.push(statement, block_close);
10
-
+ context.state.template.push(statement);
11
-
}
12
-
diff --git a/src/compiler/phases/3-transform/server/visitors/EachBlock.js b/src/compiler/phases/3-transform/server/visitors/EachBlock.js
13
-
index 3c0a8c167696960efa186179da60c47eca0db2e2..8e96d467f6f20af90226ddb16db383e4e3be70ed 100644
14
-
--- a/src/compiler/phases/3-transform/server/visitors/EachBlock.js
15
-
+++ b/src/compiler/phases/3-transform/server/visitors/EachBlock.js
16
-
@@ -47,21 +47,16 @@ export function EachBlock(node, context) {
17
-
);
18
-
19
-
if (node.fallback) {
20
-
- const open = b.stmt(b.call(b.id('$$renderer.push'), block_open));
21
-
-
22
-
const fallback = /** @type {BlockStatement} */ (context.visit(node.fallback));
23
-
24
-
- fallback.body.unshift(b.stmt(b.call(b.id('$$renderer.push'), block_open_else)));
25
-
-
26
-
block.body.push(
27
-
b.if(
28
-
b.binary('!==', b.member(array_id, 'length'), b.literal(0)),
29
-
- b.block([open, for_loop]),
30
-
+ b.block([for_loop]),
31
-
fallback
32
-
)
33
-
);
34
-
} else {
35
-
- state.template.push(block_open);
36
-
block.body.push(for_loop);
37
-
}
38
-
39
-
@@ -71,10 +66,9 @@ export function EachBlock(node, context) {
40
-
block,
41
-
node.metadata.expression.blockers(),
42
-
node.metadata.expression.has_await
43
-
- ),
44
-
- block_close
45
-
+ )
46
-
);
47
-
} else {
48
-
- state.template.push(...block.body, block_close);
49
-
+ state.template.push(...block.body);
50
-
}
51
-
}
52
-
diff --git a/src/compiler/phases/3-transform/server/visitors/Fragment.js b/src/compiler/phases/3-transform/server/visitors/Fragment.js
53
-
index ef5bd985ae5d6bcae838a58f68145fd070b73179..bdc556ee8547d4bfccdee0e6c10260a6f9769fba 100644
54
-
--- a/src/compiler/phases/3-transform/server/visitors/Fragment.js
55
-
+++ b/src/compiler/phases/3-transform/server/visitors/Fragment.js
56
-
@@ -36,11 +36,6 @@ export function Fragment(node, context) {
57
-
context.visit(node, state);
58
-
}
59
-
60
-
- if (is_text_first) {
61
-
- // insert `<!---->` to prevent this from being glued to the previous fragment
62
-
- state.template.push(empty_comment);
63
-
- }
64
-
-
65
-
process_children(trimmed, { ...context, state });
66
-
67
-
if (state.async_consts && state.async_consts.thunks.length > 0) {
68
-
diff --git a/src/compiler/phases/3-transform/server/visitors/IfBlock.js b/src/compiler/phases/3-transform/server/visitors/IfBlock.js
69
-
index e8418343be9b2fcba39add8762f5139e37cc7e11..3fccb04a180be2e499c2d71e3b6ac250bc7c30b6 100644
70
-
--- a/src/compiler/phases/3-transform/server/visitors/IfBlock.js
71
-
+++ b/src/compiler/phases/3-transform/server/visitors/IfBlock.js
72
-
@@ -16,10 +16,6 @@ export function IfBlock(node, context) {
73
-
? /** @type {BlockStatement} */ (context.visit(node.alternate))
74
-
: b.block([]);
75
-
76
-
- consequent.body.unshift(b.stmt(b.call(b.id('$$renderer.push'), block_open)));
77
-
-
78
-
- alternate.body.unshift(b.stmt(b.call(b.id('$$renderer.push'), block_open_else)));
79
-
-
80
-
/** @type {Statement} */
81
-
let statement = b.if(test, consequent, alternate);
82
-
83
-
@@ -35,5 +31,5 @@ export function IfBlock(node, context) {
84
-
);
85
-
}
86
-
87
-
- context.state.template.push(statement, block_close);
88
-
+ context.state.template.push(statement);
89
-
}
90
-
diff --git a/src/compiler/phases/3-transform/server/visitors/KeyBlock.js b/src/compiler/phases/3-transform/server/visitors/KeyBlock.js
91
-
index 1396aa8fada3c5ccbc469a9983af646765bd35e2..02906b5eda4b4a7c2d90243a9d2e28bca606f4d9 100644
92
-
--- a/src/compiler/phases/3-transform/server/visitors/KeyBlock.js
93
-
+++ b/src/compiler/phases/3-transform/server/visitors/KeyBlock.js
94
-
@@ -8,15 +8,7 @@ import { block_close, block_open, empty_comment } from './shared/utils.js';
95
-
* @param {ComponentContext} context
96
-
*/
97
-
export function KeyBlock(node, context) {
98
-
- const is_async = node.metadata.expression.is_async();
99
-
-
100
-
- if (is_async) context.state.template.push(block_open);
101
-
-
102
-
context.state.template.push(
103
-
- empty_comment,
104
-
/** @type {BlockStatement} */ (context.visit(node.fragment)),
105
-
- empty_comment
106
-
);
107
-
-
108
-
- if (is_async) context.state.template.push(block_close);
109
-
}
110
-
diff --git a/src/compiler/phases/3-transform/server/visitors/RenderTag.js b/src/compiler/phases/3-transform/server/visitors/RenderTag.js
111
-
index 6d7cef0d95a943d6251101289a821537b259162e..9b4576a8e571aed73046e84ebfa47c276eef7439 100644
112
-
--- a/src/compiler/phases/3-transform/server/visitors/RenderTag.js
113
-
+++ b/src/compiler/phases/3-transform/server/visitors/RenderTag.js
114
-
@@ -44,8 +44,4 @@ export function RenderTag(node, context) {
115
-
}
116
-
117
-
context.state.template.push(statement);
118
-
-
119
-
- if (!context.state.skip_hydration_boundaries) {
120
-
- context.state.template.push(empty_comment);
121
-
- }
122
-
}
123
-
diff --git a/src/compiler/phases/3-transform/server/visitors/SlotElement.js b/src/compiler/phases/3-transform/server/visitors/SlotElement.js
124
-
index d0f8e25d021a70589c6fd191139438a1a95bc45c..4455b964948500ab0f8e8468e7f7fd74139f1d1c 100644
125
-
--- a/src/compiler/phases/3-transform/server/visitors/SlotElement.js
126
-
+++ b/src/compiler/phases/3-transform/server/visitors/SlotElement.js
127
-
@@ -73,5 +73,5 @@ export function SlotElement(node, context) {
128
-
)
129
-
: b.stmt(slot);
130
-
131
-
- context.state.template.push(block_open, statement, block_close);
132
-
+ context.state.template.push(statement);
133
-
}
134
-
diff --git a/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js b/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js
135
-
index 8a30e765c23008f35ba7a5e43d3c0905f309f555..b5f66aea25087751a864ce515f5f021794ce3d01 100644
136
-
--- a/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js
137
-
+++ b/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js
138
-
@@ -45,8 +45,8 @@ export function SvelteBoundary(node, context) {
139
-
context.state.template.push(
140
-
b.if(
141
-
callee,
142
-
- b.block(build_template([block_open_else, b.stmt(pending), block_close])),
143
-
- b.block(build_template([block_open, block, block_close]))
144
-
+ b.block(build_template([b.stmt(pending)])),
145
-
+ b.block(build_template([block]))
146
-
)
147
-
);
148
-
} else {
149
-
@@ -62,10 +62,10 @@ export function SvelteBoundary(node, context) {
150
-
b.id('$$renderer')
151
-
)
152
-
: /** @type {BlockStatement} */ (context.visit(pending_snippet.body));
153
-
- context.state.template.push(block_open_else, pending, block_close);
154
-
+ context.state.template.push(pending);
155
-
}
156
-
} else {
157
-
const block = /** @type {BlockStatement} */ (context.visit(node.fragment));
158
-
- context.state.template.push(block_open, block, block_close);
159
-
+ context.state.template.push(block);
160
-
}
161
-
}
162
-
diff --git a/src/compiler/phases/3-transform/server/visitors/shared/component.js b/src/compiler/phases/3-transform/server/visitors/shared/component.js
163
-
index a90b5e41dfb2e746a12c2dbd5f149c9fbcac5d54..846edda2d005f1b1abbfa64029ae90e12f2a2acc 100644
164
-
--- a/src/compiler/phases/3-transform/server/visitors/shared/component.js
165
-
+++ b/src/compiler/phases/3-transform/server/visitors/shared/component.js
166
-
@@ -335,26 +335,13 @@ export function build_inline_component(node, expression, context) {
167
-
statement = create_async_block(
168
-
b.block([
169
-
optimiser.apply(),
170
-
- dynamic && custom_css_props.length === 0
171
-
- ? b.stmt(b.call('$$renderer.push', empty_comment))
172
-
- : b.empty,
173
-
+ b.empty,
174
-
statement
175
-
]),
176
-
optimiser.blockers(),
177
-
optimiser.has_await
178
-
);
179
-
- } else if (dynamic && custom_css_props.length === 0) {
180
-
- context.state.template.push(empty_comment);
181
-
}
182
-
183
-
context.state.template.push(statement);
184
-
-
185
-
- if (
186
-
- !is_async &&
187
-
- !context.state.skip_hydration_boundaries &&
188
-
- custom_css_props.length === 0 &&
189
-
- optimiser.expressions.length === 0
190
-
- ) {
191
-
- context.state.template.push(empty_comment);
192
-
- }
193
-
}
194
-
diff --git a/src/compiler/phases/3-transform/server/visitors/shared/utils.js b/src/compiler/phases/3-transform/server/visitors/shared/utils.js
195
-
index 4736a7c5daf27c6c2dd7c8f0e5136d668f178a95..b2e94a6f257614ed9e2e85f3ff77fa4ed9e3debd 100644
196
-
--- a/src/compiler/phases/3-transform/server/visitors/shared/utils.js
197
-
+++ b/src/compiler/phases/3-transform/server/visitors/shared/utils.js
198
-
@@ -116,6 +116,12 @@ export function build_template(template) {
199
-
const statements = [];
200
-
201
-
const flush = () => {
202
-
+ // Skip empty pushes
203
-
+ if (expressions.length === 0 && strings.every((s) => s === '')) {
204
-
+ strings = [];
205
-
+ return;
206
-
+ }
207
-
+
208
-
statements.push(
209
-
b.stmt(
210
-
b.call(
211
-
@@ -326,9 +332,11 @@ export function create_push(expression, metadata, needs_hydration_markers = fals
212
-
* @returns {Statement}
213
-
*/
214
-
export function call_component_renderer(body, component_fn_id) {
215
-
- return b.stmt(
216
-
- b.call('$$renderer.component', b.arrow([b.id('$$renderer')], body, false), component_fn_id)
217
-
- );
218
-
+ // Just emit the body directly - no component() wrapper needed for sync rendering
219
-
+ if (body.type === 'BlockStatement') {
220
-
+ return body;
221
-
+ }
222
-
+ return b.stmt(body);
223
-
}
224
-
225
-
/**
226
-
diff --git a/src/internal/server/index.js b/src/internal/server/index.js
227
-
index c0dbdbda14f6f6c98d47686e275f91034c1eaa6b..13b18b1625d48820f9960d473a8d0c1d07757f3f 100644
228
-
--- a/src/internal/server/index.js
229
-
+++ b/src/internal/server/index.js
230
-
@@ -17,7 +17,7 @@ import { DEV } from 'esm-env';
231
-
import { EMPTY_COMMENT, BLOCK_CLOSE, BLOCK_OPEN, BLOCK_OPEN_ELSE } from './hydration.js';
232
-
import { validate_store } from '../shared/validate.js';
233
-
import { is_boolean_attribute, is_raw_text_element, is_void } from '../../utils.js';
234
-
-import { Renderer } from './renderer.js';
235
-
+export { render } from './renderer.js';
236
-
237
-
// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
238
-
// https://infra.spec.whatwg.org/#noncharacter
239
-
@@ -51,17 +51,6 @@ export function element(renderer, tag, attributes_fn = noop, children_fn = noop)
240
-
renderer.push('<!---->');
241
-
}
242
-
243
-
-/**
244
-
- * Only available on the server and when compiling with the `server` option.
245
-
- * Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app.
246
-
- * @template {Record<string, any>} Props
247
-
- * @param {Component<Props> | ComponentType<SvelteComponent<Props>>} component
248
-
- * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string }} [options]
249
-
- * @returns {RenderOutput}
250
-
- */
251
-
-export function render(component, options = {}) {
252
-
- return Renderer.render(/** @type {Component<Props>} */ (component), options);
253
-
-}
254
-
255
-
/**
256
-
* @param {string} hash
257
-
@@ -411,12 +400,7 @@ export { await_block as await };
258
-
259
-
/** @param {any} array_like_or_iterator */
260
-
export function ensure_array_like(array_like_or_iterator) {
261
-
- if (array_like_or_iterator) {
262
-
- return array_like_or_iterator.length !== undefined
263
-
- ? array_like_or_iterator
264
-
- : Array.from(array_like_or_iterator);
265
-
- }
266
-
- return [];
267
-
+ return array_like_or_iterator;
268
-
}
269
-
270
-
/**
271
-
diff --git a/src/internal/server/renderer.js b/src/internal/server/renderer.js
272
-
index 0cfb1a7a93518729d04c26214140eaab29de4870..c36c956d1edff831a5d00f214184b882f96e0985 100644
273
-
--- a/src/internal/server/renderer.js
274
-
+++ b/src/internal/server/renderer.js
275
-
@@ -1,741 +1,18 @@
276
-
/** @import { Component } from 'svelte' */
277
-
-/** @import { HydratableContext, RenderOutput, SSRContext, SyncRenderOutput } from './types.js' */
278
-
-/** @import { MaybePromise } from '#shared' */
279
-
-import { async_mode_flag } from '../flags/index.js';
280
-
-import { abort } from './abort-signal.js';
281
-
-import { pop, push, set_ssr_context, ssr_context, save } from './context.js';
282
-
-import * as e from './errors.js';
283
-
-import * as w from './warnings.js';
284
-
-import { BLOCK_CLOSE, BLOCK_OPEN } from './hydration.js';
285
-
-import { attributes } from './index.js';
286
-
-import { get_render_context, with_render_context, init_render_context } from './render-context.js';
287
-
-import { DEV } from 'esm-env';
288
-
-
289
-
-/** @typedef {'head' | 'body'} RendererType */
290
-
-/** @typedef {{ [key in RendererType]: string }} AccumulatedContent */
291
-
-
292
-
-/**
293
-
- * @typedef {string | Renderer} RendererItem
294
-
- */
295
-
+/** @import { RenderOutput } from './types.js' */
296
-
297
-
/**
298
-
- * Renderers are basically a tree of `string | Renderer`s, where each `Renderer` in the tree represents
299
-
- * work that may or may not have completed. A renderer can be {@link collect}ed to aggregate the
300
-
- * content from itself and all of its children, but this will throw if any of the children are
301
-
- * performing asynchronous work. To asynchronously collect a renderer, just `await` it.
302
-
- *
303
-
- * The `string` values within a renderer are always associated with the {@link type} of that renderer. To switch types,
304
-
- * call {@link child} with a different `type` argument.
305
-
+ * @template {Record<string, any>} Props
306
-
+ * @param {Component<Props>} component
307
-
+ * @param {{ props?: Omit<Props, '$$slots' | '$$events'> }} [options]
308
-
+ * @returns {RenderOutput}
309
-
*/
310
-
-export class Renderer {
311
-
- /**
312
-
- * The contents of the renderer.
313
-
- * @type {RendererItem[]}
314
-
- */
315
-
- #out = [];
316
-
-
317
-
- /**
318
-
- * Any `onDestroy` callbacks registered during execution of this renderer.
319
-
- * @type {(() => void)[] | undefined}
320
-
- */
321
-
- #on_destroy = undefined;
322
-
-
323
-
- /**
324
-
- * Whether this renderer is a component body.
325
-
- * @type {boolean}
326
-
- */
327
-
- #is_component_body = false;
328
-
-
329
-
- /**
330
-
- * The type of string content that this renderer is accumulating.
331
-
- * @type {RendererType}
332
-
- */
333
-
- type;
334
-
-
335
-
- /** @type {Renderer | undefined} */
336
-
- #parent;
337
-
-
338
-
- /**
339
-
- * Asynchronous work associated with this renderer
340
-
- * @type {Promise<void> | undefined}
341
-
- */
342
-
- promise = undefined;
343
-
-
344
-
- /**
345
-
- * State which is associated with the content tree as a whole.
346
-
- * It will be re-exposed, uncopied, on all children.
347
-
- * @type {SSRState}
348
-
- * @readonly
349
-
- */
350
-
- global;
351
-
-
352
-
- /**
353
-
- * State that is local to the branch it is declared in.
354
-
- * It will be shallow-copied to all children.
355
-
- *
356
-
- * @type {{ select_value: string | undefined }}
357
-
- */
358
-
- local;
359
-
-
360
-
- /**
361
-
- * @param {SSRState} global
362
-
- * @param {Renderer | undefined} [parent]
363
-
- */
364
-
- constructor(global, parent) {
365
-
- this.#parent = parent;
366
-
-
367
-
- this.global = global;
368
-
- this.local = parent ? { ...parent.local } : { select_value: undefined };
369
-
- this.type = parent ? parent.type : 'body';
370
-
- }
371
-
-
372
-
- /**
373
-
- * @param {(renderer: Renderer) => void} fn
374
-
- */
375
-
- head(fn) {
376
-
- const head = new Renderer(this.global, this);
377
-
- head.type = 'head';
378
-
-
379
-
- this.#out.push(head);
380
-
- head.child(fn);
381
-
- }
382
-
-
383
-
- /**
384
-
- * @param {Array<Promise<void>>} blockers
385
-
- * @param {(renderer: Renderer) => void} fn
386
-
- */
387
-
- async_block(blockers, fn) {
388
-
- this.#out.push(BLOCK_OPEN);
389
-
- this.async(blockers, fn);
390
-
- this.#out.push(BLOCK_CLOSE);
391
-
- }
392
-
-
393
-
- /**
394
-
- * @param {Array<Promise<void>>} blockers
395
-
- * @param {(renderer: Renderer) => void} fn
396
-
- */
397
-
- async(blockers, fn) {
398
-
- let callback = fn;
399
-
-
400
-
- if (blockers.length > 0) {
401
-
- const context = ssr_context;
402
-
-
403
-
- callback = (renderer) => {
404
-
- return Promise.all(blockers).then(() => {
405
-
- const previous_context = ssr_context;
406
-
-
407
-
- try {
408
-
- set_ssr_context(context);
409
-
- return fn(renderer);
410
-
- } finally {
411
-
- set_ssr_context(previous_context);
412
-
- }
413
-
- });
414
-
- };
415
-
- }
416
-
-
417
-
- this.child(callback);
418
-
- }
419
-
-
420
-
- /**
421
-
- * @param {Array<() => void>} thunks
422
-
- */
423
-
- run(thunks) {
424
-
- const context = ssr_context;
425
-
-
426
-
- let promise = Promise.resolve(thunks[0]());
427
-
- const promises = [promise];
428
-
-
429
-
- for (const fn of thunks.slice(1)) {
430
-
- promise = promise.then(() => {
431
-
- const previous_context = ssr_context;
432
-
- set_ssr_context(context);
433
-
-
434
-
- try {
435
-
- return fn();
436
-
- } finally {
437
-
- set_ssr_context(previous_context);
438
-
- }
439
-
- });
440
-
-
441
-
- promises.push(promise);
442
-
- }
443
-
-
444
-
- return promises;
445
-
- }
446
-
-
447
-
- /**
448
-
- * Create a child renderer. The child renderer inherits the state from the parent,
449
-
- * but has its own content.
450
-
- * @param {(renderer: Renderer) => MaybePromise<void>} fn
451
-
- */
452
-
- child(fn) {
453
-
- const child = new Renderer(this.global, this);
454
-
- this.#out.push(child);
455
-
-
456
-
- const parent = ssr_context;
457
-
-
458
-
- set_ssr_context({
459
-
- ...ssr_context,
460
-
- p: parent,
461
-
- c: null,
462
-
- r: child
463
-
- });
464
-
-
465
-
- const result = fn(child);
466
-
-
467
-
- set_ssr_context(parent);
468
-
-
469
-
- if (result instanceof Promise) {
470
-
- if (child.global.mode === 'sync') {
471
-
- e.await_invalid();
472
-
- }
473
-
- // just to avoid unhandled promise rejections -- we'll end up throwing in `collect_async` if something fails
474
-
- result.catch(() => {});
475
-
- child.promise = result;
476
-
- }
477
-
-
478
-
- return child;
479
-
- }
480
-
-
481
-
- /**
482
-
- * Create a component renderer. The component renderer inherits the state from the parent,
483
-
- * but has its own content. It is treated as an ordering boundary for ondestroy callbacks.
484
-
- * @param {(renderer: Renderer) => MaybePromise<void>} fn
485
-
- * @param {Function} [component_fn]
486
-
- * @returns {void}
487
-
- */
488
-
- component(fn, component_fn) {
489
-
- push(component_fn);
490
-
- const child = this.child(fn);
491
-
- child.#is_component_body = true;
492
-
- pop();
493
-
- }
494
-
-
495
-
- /**
496
-
- * @param {Record<string, any>} attrs
497
-
- * @param {(renderer: Renderer) => void} fn
498
-
- * @param {string | undefined} [css_hash]
499
-
- * @param {Record<string, boolean> | undefined} [classes]
500
-
- * @param {Record<string, string> | undefined} [styles]
501
-
- * @param {number | undefined} [flags]
502
-
- * @returns {void}
503
-
- */
504
-
- select(attrs, fn, css_hash, classes, styles, flags) {
505
-
- const { value, ...select_attrs } = attrs;
506
-
-
507
-
- this.push(`<select${attributes(select_attrs, css_hash, classes, styles, flags)}>`);
508
-
- this.child((renderer) => {
509
-
- renderer.local.select_value = value;
510
-
- fn(renderer);
511
-
- });
512
-
- this.push('</select>');
513
-
- }
514
-
-
515
-
- /**
516
-
- * @param {Record<string, any>} attrs
517
-
- * @param {string | number | boolean | ((renderer: Renderer) => void)} body
518
-
- * @param {string | undefined} [css_hash]
519
-
- * @param {Record<string, boolean> | undefined} [classes]
520
-
- * @param {Record<string, string> | undefined} [styles]
521
-
- * @param {number | undefined} [flags]
522
-
- */
523
-
- option(attrs, body, css_hash, classes, styles, flags) {
524
-
- this.#out.push(`<option${attributes(attrs, css_hash, classes, styles, flags)}`);
525
-
-
526
-
- /**
527
-
- * @param {Renderer} renderer
528
-
- * @param {any} value
529
-
- * @param {{ head?: string, body: any }} content
530
-
- */
531
-
- const close = (renderer, value, { head, body }) => {
532
-
- if ('value' in attrs) {
533
-
- value = attrs.value;
534
-
- }
535
-
-
536
-
- if (value === this.local.select_value) {
537
-
- renderer.#out.push(' selected');
538
-
- }
539
-
-
540
-
- renderer.#out.push(`>${body}</option>`);
541
-
-
542
-
- // super edge case, but may as well handle it
543
-
- if (head) {
544
-
- renderer.head((child) => child.push(head));
545
-
- }
546
-
- };
547
-
-
548
-
- if (typeof body === 'function') {
549
-
- this.child((renderer) => {
550
-
- const r = new Renderer(this.global, this);
551
-
- body(r);
552
-
-
553
-
- if (this.global.mode === 'async') {
554
-
- return r.#collect_content_async().then((content) => {
555
-
- close(renderer, content.body.replaceAll('<!---->', ''), content);
556
-
- });
557
-
- } else {
558
-
- const content = r.#collect_content();
559
-
- close(renderer, content.body.replaceAll('<!---->', ''), content);
560
-
- }
561
-
- });
562
-
- } else {
563
-
- close(this, body, { body });
564
-
- }
565
-
- }
566
-
-
567
-
- /**
568
-
- * @param {(renderer: Renderer) => void} fn
569
-
- */
570
-
- title(fn) {
571
-
- const path = this.get_path();
572
-
-
573
-
- /** @param {string} head */
574
-
- const close = (head) => {
575
-
- this.global.set_title(head, path);
576
-
- };
577
-
-
578
-
- this.child((renderer) => {
579
-
- const r = new Renderer(renderer.global, renderer);
580
-
- fn(r);
581
-
-
582
-
- if (renderer.global.mode === 'async') {
583
-
- return r.#collect_content_async().then((content) => {
584
-
- close(content.head);
585
-
- });
586
-
- } else {
587
-
- const content = r.#collect_content();
588
-
- close(content.head);
589
-
- }
590
-
- });
591
-
- }
592
-
-
593
-
- /**
594
-
- * @param {string | (() => Promise<string>)} content
595
-
- */
596
-
- push(content) {
597
-
- if (typeof content === 'function') {
598
-
- this.child(async (renderer) => renderer.push(await content()));
599
-
- } else {
600
-
- this.#out.push(content);
601
-
- }
602
-
- }
603
-
-
604
-
- /**
605
-
- * @param {() => void} fn
606
-
- */
607
-
- on_destroy(fn) {
608
-
- (this.#on_destroy ??= []).push(fn);
609
-
- }
610
-
-
611
-
- /**
612
-
- * @returns {number[]}
613
-
- */
614
-
- get_path() {
615
-
- return this.#parent ? [...this.#parent.get_path(), this.#parent.#out.indexOf(this)] : [];
616
-
- }
617
-
-
618
-
- /**
619
-
- * @deprecated this is needed for legacy component bindings
620
-
- */
621
-
- copy() {
622
-
- const copy = new Renderer(this.global, this.#parent);
623
-
- copy.#out = this.#out.map((item) => (item instanceof Renderer ? item.copy() : item));
624
-
- copy.promise = this.promise;
625
-
- return copy;
626
-
- }
627
-
-
628
-
- /**
629
-
- * @param {Renderer} other
630
-
- * @deprecated this is needed for legacy component bindings
631
-
- */
632
-
- subsume(other) {
633
-
- if (this.global.mode !== other.global.mode) {
634
-
- throw new Error(
635
-
- "invariant: A renderer cannot switch modes. If you're seeing this, there's a compiler bug. File an issue!"
636
-
- );
637
-
- }
638
-
-
639
-
- this.local = other.local;
640
-
- this.#out = other.#out.map((item) => {
641
-
- if (item instanceof Renderer) {
642
-
- item.subsume(item);
643
-
- }
644
-
- return item;
645
-
- });
646
-
- this.promise = other.promise;
647
-
- this.type = other.type;
648
-
- }
649
-
-
650
-
- get length() {
651
-
- return this.#out.length;
652
-
- }
653
-
-
654
-
- /**
655
-
- * Only available on the server and when compiling with the `server` option.
656
-
- * Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app.
657
-
- * @template {Record<string, any>} Props
658
-
- * @param {Component<Props>} component
659
-
- * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string }} [options]
660
-
- * @returns {RenderOutput}
661
-
- */
662
-
- static render(component, options = {}) {
663
-
- /** @type {AccumulatedContent | undefined} */
664
-
- let sync;
665
-
- /** @type {Promise<AccumulatedContent> | undefined} */
666
-
- let async;
667
-
-
668
-
- const result = /** @type {RenderOutput} */ ({});
669
-
- // making these properties non-enumerable so that console.logging
670
-
- // doesn't trigger a sync render
671
-
- Object.defineProperties(result, {
672
-
- html: {
673
-
- get: () => {
674
-
- return (sync ??= Renderer.#render(component, options)).body;
675
-
- }
676
-
- },
677
-
- head: {
678
-
- get: () => {
679
-
- return (sync ??= Renderer.#render(component, options)).head;
680
-
- }
681
-
- },
682
-
- body: {
683
-
- get: () => {
684
-
- return (sync ??= Renderer.#render(component, options)).body;
685
-
- }
686
-
- },
687
-
- then: {
688
-
- value:
689
-
- /**
690
-
- * this is not type-safe, but honestly it's the best I can do right now, and it's a straightforward function.
691
-
- *
692
-
- * @template TResult1
693
-
- * @template [TResult2=never]
694
-
- * @param { (value: SyncRenderOutput) => TResult1 } onfulfilled
695
-
- * @param { (reason: unknown) => TResult2 } onrejected
696
-
- */
697
-
- (onfulfilled, onrejected) => {
698
-
- if (!async_mode_flag) {
699
-
- const result = (sync ??= Renderer.#render(component, options));
700
-
- const user_result = onfulfilled({
701
-
- head: result.head,
702
-
- body: result.body,
703
-
- html: result.body
704
-
- });
705
-
- return Promise.resolve(user_result);
706
-
- }
707
-
- async ??= init_render_context().then(() =>
708
-
- with_render_context(() => Renderer.#render_async(component, options))
709
-
- );
710
-
- return async.then((result) => {
711
-
- Object.defineProperty(result, 'html', {
712
-
- // eslint-disable-next-line getter-return
713
-
- get: () => {
714
-
- e.html_deprecated();
715
-
- }
716
-
- });
717
-
- return onfulfilled(/** @type {SyncRenderOutput} */ (result));
718
-
- }, onrejected);
719
-
- }
720
-
- }
721
-
- });
722
-
-
723
-
- return result;
724
-
- }
725
-
-
726
-
- /**
727
-
- * Collect all of the `onDestroy` callbacks registered during rendering. In an async context, this is only safe to call
728
-
- * after awaiting `collect_async`.
729
-
- *
730
-
- * Child renderers are "porous" and don't affect execution order, but component body renderers
731
-
- * create ordering boundaries. Within a renderer, callbacks run in order until hitting a component boundary.
732
-
- * @returns {Iterable<() => void>}
733
-
- */
734
-
- *#collect_on_destroy() {
735
-
- for (const component of this.#traverse_components()) {
736
-
- yield* component.#collect_ondestroy();
737
-
- }
738
-
- }
739
-
-
740
-
- /**
741
-
- * Performs a depth-first search of renderers, yielding the deepest components first, then additional components as we backtrack up the tree.
742
-
- * @returns {Iterable<Renderer>}
743
-
- */
744
-
- *#traverse_components() {
745
-
- for (const child of this.#out) {
746
-
- if (typeof child !== 'string') {
747
-
- yield* child.#traverse_components();
748
-
- }
749
-
- }
750
-
- if (this.#is_component_body) {
751
-
- yield this;
752
-
- }
753
-
- }
754
-
-
755
-
- /**
756
-
- * @returns {Iterable<() => void>}
757
-
- */
758
-
- *#collect_ondestroy() {
759
-
- if (this.#on_destroy) {
760
-
- for (const fn of this.#on_destroy) {
761
-
- yield fn;
762
-
- }
763
-
- }
764
-
- for (const child of this.#out) {
765
-
- if (child instanceof Renderer && !child.#is_component_body) {
766
-
- yield* child.#collect_ondestroy();
767
-
- }
768
-
- }
769
-
- }
770
-
-
771
-
- /**
772
-
- * Render a component. Throws if any of the children are performing asynchronous work.
773
-
- *
774
-
- * @template {Record<string, any>} Props
775
-
- * @param {Component<Props>} component
776
-
- * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string }} options
777
-
- * @returns {AccumulatedContent}
778
-
- */
779
-
- static #render(component, options) {
780
-
- var previous_context = ssr_context;
781
-
- try {
782
-
- const renderer = Renderer.#open_render('sync', component, options);
783
-
-
784
-
- const content = renderer.#collect_content();
785
-
- return Renderer.#close_render(content, renderer);
786
-
- } finally {
787
-
- abort();
788
-
- set_ssr_context(previous_context);
789
-
- }
790
-
- }
791
-
-
792
-
- /**
793
-
- * Render a component.
794
-
- *
795
-
- * @template {Record<string, any>} Props
796
-
- * @param {Component<Props>} component
797
-
- * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string }} options
798
-
- * @returns {Promise<AccumulatedContent>}
799
-
- */
800
-
- static async #render_async(component, options) {
801
-
- const previous_context = ssr_context;
802
-
-
803
-
- try {
804
-
- const renderer = Renderer.#open_render('async', component, options);
805
-
- const content = await renderer.#collect_content_async();
806
-
- const hydratables = await renderer.#collect_hydratables();
807
-
- if (hydratables !== null) {
808
-
- content.head = hydratables + content.head;
809
-
- }
810
-
- return Renderer.#close_render(content, renderer);
811
-
- } finally {
812
-
- set_ssr_context(previous_context);
813
-
- abort();
814
-
- }
815
-
- }
816
-
-
817
-
- /**
818
-
- * Collect all of the code from the `out` array and return it as a string, or a promise resolving to a string.
819
-
- * @param {AccumulatedContent} content
820
-
- * @returns {AccumulatedContent}
821
-
- */
822
-
- #collect_content(content = { head: '', body: '' }) {
823
-
- for (const item of this.#out) {
824
-
- if (typeof item === 'string') {
825
-
- content[this.type] += item;
826
-
- } else if (item instanceof Renderer) {
827
-
- item.#collect_content(content);
828
-
- }
829
-
- }
830
-
-
831
-
- return content;
832
-
- }
833
-
-
834
-
- /**
835
-
- * Collect all of the code from the `out` array and return it as a string.
836
-
- * @param {AccumulatedContent} content
837
-
- * @returns {Promise<AccumulatedContent>}
838
-
- */
839
-
- async #collect_content_async(content = { head: '', body: '' }) {
840
-
- await this.promise;
841
-
-
842
-
- // no danger to sequentially awaiting stuff in here; all of the work is already kicked off
843
-
- for (const item of this.#out) {
844
-
- if (typeof item === 'string') {
845
-
- content[this.type] += item;
846
-
- } else if (item instanceof Renderer) {
847
-
- await item.#collect_content_async(content);
848
-
- }
849
-
- }
850
-
-
851
-
- return content;
852
-
- }
853
-
-
854
-
- async #collect_hydratables() {
855
-
- const ctx = get_render_context().hydratable;
856
-
-
857
-
- for (const [_, key] of ctx.unresolved_promises) {
858
-
- // this is a problem -- it means we've finished the render but we're still waiting on a promise to resolve so we can
859
-
- // serialize it, so we're blocking the response on useless content.
860
-
- w.unresolved_hydratable(key, ctx.lookup.get(key)?.stack ?? '<missing stack trace>');
861
-
- }
862
-
-
863
-
- for (const comparison of ctx.comparisons) {
864
-
- // these reject if there's a mismatch
865
-
- await comparison;
866
-
- }
867
-
-
868
-
- return await Renderer.#hydratable_block(ctx);
869
-
- }
870
-
-
871
-
- /**
872
-
- * @template {Record<string, any>} Props
873
-
- * @param {'sync' | 'async'} mode
874
-
- * @param {import('svelte').Component<Props>} component
875
-
- * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string }} options
876
-
- * @returns {Renderer}
877
-
- */
878
-
- static #open_render(mode, component, options) {
879
-
- const renderer = new Renderer(
880
-
- new SSRState(mode, options.idPrefix ? options.idPrefix + '-' : '')
881
-
- );
882
-
-
883
-
- renderer.push(BLOCK_OPEN);
884
-
-
885
-
- if (options.context) {
886
-
- push();
887
-
- /** @type {SSRContext} */ (ssr_context).c = options.context;
888
-
- /** @type {SSRContext} */ (ssr_context).r = renderer;
889
-
- }
890
-
-
891
-
- // @ts-expect-error
892
-
- component(renderer, options.props ?? {});
893
-
-
894
-
- if (options.context) {
895
-
- pop();
896
-
- }
897
-
-
898
-
- renderer.push(BLOCK_CLOSE);
899
-
-
900
-
- return renderer;
901
-
- }
902
-
-
903
-
- /**
904
-
- * @param {AccumulatedContent} content
905
-
- * @param {Renderer} renderer
906
-
- */
907
-
- static #close_render(content, renderer) {
908
-
- for (const cleanup of renderer.#collect_on_destroy()) {
909
-
- cleanup();
910
-
- }
911
-
-
912
-
- let head = content.head + renderer.global.get_title();
913
-
- let body = content.body;
914
-
-
915
-
- for (const { hash, code } of renderer.global.css) {
916
-
- head += `<style id="${hash}">${code}</style>`;
917
-
- }
918
-
-
919
-
- return {
920
-
- head,
921
-
- body
922
-
- };
923
-
- }
924
-
-
925
-
- /**
926
-
- * @param {HydratableContext} ctx
927
-
- */
928
-
- static async #hydratable_block(ctx) {
929
-
- if (ctx.lookup.size === 0) {
930
-
- return null;
931
-
- }
932
-
-
933
-
- let entries = [];
934
-
- let has_promises = false;
935
-
-
936
-
- for (const [k, v] of ctx.lookup) {
937
-
- if (v.promises) {
938
-
- has_promises = true;
939
-
- for (const p of v.promises) await p;
940
-
- }
941
-
-
942
-
- entries.push(`[${JSON.stringify(k)},${v.serialized}]`);
943
-
- }
944
-
-
945
-
- let prelude = `const h = (window.__svelte ??= {}).h ??= new Map();`;
946
-
-
947
-
- if (has_promises) {
948
-
- prelude = `const r = (v) => Promise.resolve(v);
949
-
- ${prelude}`;
950
-
- }
951
-
-
952
-
- // TODO csp -- have discussed but not implemented
953
-
- return `
954
-
- <script>
955
-
- {
956
-
- ${prelude}
957
-
-
958
-
- for (const [k, v] of [
959
-
- ${entries.join(',\n\t\t\t\t\t')}
960
-
- ]) {
961
-
- h.set(k, v);
962
-
- }
963
-
- }
964
-
- </script>`;
965
-
- }
966
-
+function render(component, options = {}) {
967
-
+ let out = '';
968
-
+ const renderer = { push(s) { out += s; } };
969
-
+ component(renderer, options.props ?? {});
970
-
+ return { body: out };
971
-
}
972
-
973
-
-export class SSRState {
974
-
- /** @readonly @type {'sync' | 'async'} */
975
-
- mode;
976
-
-
977
-
- /** @readonly @type {() => string} */
978
-
- uid;
979
-
-
980
-
- /** @readonly @type {Set<{ hash: string; code: string }>} */
981
-
- css = new Set();
982
-
-
983
-
- /** @type {{ path: number[], value: string }} */
984
-
- #title = { path: [], value: '' };
985
-
-
986
-
- /**
987
-
- * @param {'sync' | 'async'} mode
988
-
- * @param {string} [id_prefix]
989
-
- */
990
-
- constructor(mode, id_prefix = '') {
991
-
- this.mode = mode;
992
-
-
993
-
- let uid = 1;
994
-
- this.uid = () => `${id_prefix}s${uid++}`;
995
-
- }
996
-
-
997
-
- get_title() {
998
-
- return this.#title.value;
999
-
- }
1000
-
-
1001
-
- /**
1002
-
- * Performs a depth-first (lexicographic) comparison using the path. Rejects sets
1003
-
- * from earlier than or equal to the current value.
1004
-
- * @param {string} value
1005
-
- * @param {number[]} path
1006
-
- */
1007
-
- set_title(value, path) {
1008
-
- const current = this.#title.path;
1009
-
-
1010
-
- let i = 0;
1011
-
- let l = Math.min(path.length, current.length);
1012
-
-
1013
-
- // skip identical prefixes - [1, 2, 3, ...] === [1, 2, 3, ...]
1014
-
- while (i < l && path[i] === current[i]) i += 1;
1015
-
-
1016
-
- if (path[i] === undefined) return;
1017
-
-
1018
-
- // replace title if
1019
-
- // - incoming path is longer - [7, 8, 9] > [7, 8]
1020
-
- // - incoming path is later - [7, 8, 9] > [7, 8, 8]
1021
-
- if (current[i] === undefined || path[i] > current[i]) {
1022
-
- this.#title.path = path;
1023
-
- this.#title.value = value;
1024
-
- }
1025
-
- }
1026
-
-}
1027
-
+export { render };
1028
-
+export const Renderer = { render };
1029
-
diff --git a/src/internal/shared/attributes.js b/src/internal/shared/attributes.js
1030
-
index 4ad550e8d612e42d1e719dcbfcbce383bbbbb27f..a12fe17a0efd135bd9fd4f1b1594c059a6d12e54 100644
1031
-
--- a/src/internal/shared/attributes.js
1032
-
+++ b/src/internal/shared/attributes.js
1033
-
@@ -27,7 +27,7 @@ export function attr(name, value, is_boolean = false) {
1034
-
is_boolean = true;
1035
-
}
1036
-
if (value == null || (!value && is_boolean)) return '';
1037
-
- const normalized = (name in replacements && replacements[name].get(value)) || value;
1038
-
+ const normalized = value;
1039
-
const assignment = is_boolean ? '' : `="${escape_html(normalized, true)}"`;
1040
-
return ` ${name}${assignment}`;
1041
-
}
-3169
pnpm-lock.yaml
-3169
pnpm-lock.yaml
···
1
-
lockfileVersion: '9.0'
2
-
3
-
settings:
4
-
autoInstallPeers: true
5
-
excludeLinksFromLockfile: false
6
-
7
-
catalogs:
8
-
default:
9
-
svelte:
10
-
specifier: ^5.45.5
11
-
version: 5.45.5
12
-
13
-
patchedDependencies:
14
-
svelte:
15
-
hash: 0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd
16
-
path: patches/svelte.patch
17
-
18
-
importers:
19
-
20
-
.:
21
-
devDependencies:
22
-
'@changesets/cli':
23
-
specifier: ^2.29.8
24
-
version: 2.29.8(@types/node@24.10.1)
25
-
prettier:
26
-
specifier: ^3.7.4
27
-
version: 3.7.4
28
-
prettier-plugin-css-order:
29
-
specifier: ^2.1.2
30
-
version: 2.1.2(postcss@8.5.6)(prettier@3.7.4)
31
-
prettier-plugin-svelte:
32
-
specifier: ^3.4.0
33
-
version: 3.4.0(prettier@3.7.4)(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))
34
-
typescript:
35
-
specifier: ~5.8.3
36
-
version: 5.8.3
37
-
38
-
packages/bluesky-post-embed:
39
-
dependencies:
40
-
'@atcute/bluesky':
41
-
specifier: ^2.1.1
42
-
version: 2.1.1(@atcute/client@3.1.0)
43
-
'@atcute/bluesky-richtext-segmenter':
44
-
specifier: ^2.0.4
45
-
version: 2.0.4
46
-
'@atcute/client':
47
-
specifier: ^3.1.0
48
-
version: 3.1.0
49
-
devDependencies:
50
-
'@preact/preset-vite':
51
-
specifier: ^2.10.2
52
-
version: 2.10.2(@babel/core@7.28.5)(preact@10.28.0)(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))
53
-
'@tsconfig/svelte':
54
-
specifier: ^5.0.6
55
-
version: 5.0.6
56
-
'@types/node':
57
-
specifier: ^24.10.1
58
-
version: 24.10.1
59
-
internal:
60
-
specifier: workspace:^
61
-
version: link:../internal
62
-
preact:
63
-
specifier: ^10.28.0
64
-
version: 10.28.0
65
-
svelte:
66
-
specifier: 'catalog:'
67
-
version: 5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd)
68
-
svelte-check:
69
-
specifier: ^4.3.4
70
-
version: 4.3.4(picomatch@4.0.3)(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))(typescript@5.8.3)
71
-
vite:
72
-
specifier: ^7.2.6
73
-
version: 7.2.6(@types/node@24.10.1)(terser@5.44.1)
74
-
vite-plugin-dts:
75
-
specifier: ^4.5.4
76
-
version: 4.5.4(@types/node@24.10.1)(rollup@4.53.3)(typescript@5.8.3)(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))
77
-
78
-
packages/bluesky-profile-card-embed:
79
-
dependencies:
80
-
'@atcute/bluesky':
81
-
specifier: ^2.1.1
82
-
version: 2.1.1(@atcute/client@3.1.0)
83
-
'@atcute/bluesky-richtext-parser':
84
-
specifier: ^1.0.7
85
-
version: 1.0.7
86
-
'@atcute/client':
87
-
specifier: ^3.1.0
88
-
version: 3.1.0
89
-
devDependencies:
90
-
'@preact/preset-vite':
91
-
specifier: ^2.10.2
92
-
version: 2.10.2(@babel/core@7.28.5)(preact@10.28.0)(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))
93
-
'@tsconfig/svelte':
94
-
specifier: ^5.0.6
95
-
version: 5.0.6
96
-
'@types/node':
97
-
specifier: ^24.10.1
98
-
version: 24.10.1
99
-
internal:
100
-
specifier: workspace:^
101
-
version: link:../internal
102
-
preact:
103
-
specifier: ^10.28.0
104
-
version: 10.28.0
105
-
svelte:
106
-
specifier: 'catalog:'
107
-
version: 5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd)
108
-
svelte-check:
109
-
specifier: ^4.3.4
110
-
version: 4.3.4(picomatch@4.0.3)(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))(typescript@5.8.3)
111
-
vite:
112
-
specifier: ^7.2.6
113
-
version: 7.2.6(@types/node@24.10.1)(terser@5.44.1)
114
-
vite-plugin-dts:
115
-
specifier: ^4.5.4
116
-
version: 4.5.4(@types/node@24.10.1)(rollup@4.53.3)(typescript@5.8.3)(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))
117
-
118
-
packages/bluesky-profile-feed-embed:
119
-
dependencies:
120
-
'@atcute/bluesky':
121
-
specifier: ^2.1.1
122
-
version: 2.1.1(@atcute/client@3.1.0)
123
-
'@atcute/bluesky-richtext-segmenter':
124
-
specifier: ^2.0.4
125
-
version: 2.0.4
126
-
'@atcute/client':
127
-
specifier: ^3.1.0
128
-
version: 3.1.0
129
-
devDependencies:
130
-
'@tsconfig/svelte':
131
-
specifier: ^5.0.6
132
-
version: 5.0.6
133
-
'@types/node':
134
-
specifier: ^24.10.1
135
-
version: 24.10.1
136
-
internal:
137
-
specifier: workspace:^
138
-
version: link:../internal
139
-
svelte:
140
-
specifier: 'catalog:'
141
-
version: 5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd)
142
-
svelte-check:
143
-
specifier: ^4.3.4
144
-
version: 4.3.4(picomatch@4.0.3)(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))(typescript@5.8.3)
145
-
vite:
146
-
specifier: ^7.2.6
147
-
version: 7.2.6(@types/node@24.10.1)(terser@5.44.1)
148
-
vite-plugin-dts:
149
-
specifier: ^4.5.4
150
-
version: 4.5.4(@types/node@24.10.1)(rollup@4.53.3)(typescript@5.8.3)(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))
151
-
152
-
packages/internal:
153
-
devDependencies:
154
-
'@atcute/bluesky':
155
-
specifier: ^2.1.1
156
-
version: 2.1.1(@atcute/client@3.1.0)
157
-
'@atcute/bluesky-richtext-parser':
158
-
specifier: ^1.0.7
159
-
version: 1.0.7
160
-
'@atcute/bluesky-richtext-segmenter':
161
-
specifier: ^2.0.4
162
-
version: 2.0.4
163
-
'@atcute/client':
164
-
specifier: ^3.1.0
165
-
version: 3.1.0
166
-
'@tsconfig/svelte':
167
-
specifier: ^5.0.6
168
-
version: 5.0.6
169
-
svelte:
170
-
specifier: 'catalog:'
171
-
version: 5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd)
172
-
173
-
packages/svelte-site:
174
-
dependencies:
175
-
'@atcute/bluesky':
176
-
specifier: ^2.1.1
177
-
version: 2.1.1(@atcute/client@3.1.0)
178
-
'@atcute/client':
179
-
specifier: ^3.1.0
180
-
version: 3.1.0
181
-
bluesky-post-embed:
182
-
specifier: workspace:^
183
-
version: link:../bluesky-post-embed
184
-
bluesky-profile-card-embed:
185
-
specifier: workspace:^
186
-
version: link:../bluesky-profile-card-embed
187
-
bluesky-profile-feed-embed:
188
-
specifier: workspace:^
189
-
version: link:../bluesky-profile-feed-embed
190
-
internal:
191
-
specifier: workspace:^
192
-
version: link:../internal
193
-
devDependencies:
194
-
'@sveltejs/vite-plugin-svelte':
195
-
specifier: ^6.2.1
196
-
version: 6.2.1(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))
197
-
'@tsconfig/svelte':
198
-
specifier: ^5.0.6
199
-
version: 5.0.6
200
-
svelte:
201
-
specifier: ^5.45.5
202
-
version: 5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd)
203
-
svelte-check:
204
-
specifier: ^4.3.4
205
-
version: 4.3.4(picomatch@4.0.3)(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))(typescript@5.8.3)
206
-
terser:
207
-
specifier: ^5.44.1
208
-
version: 5.44.1
209
-
tslib:
210
-
specifier: ^2.8.1
211
-
version: 2.8.1
212
-
vite:
213
-
specifier: ^7.2.6
214
-
version: 7.2.6(@types/node@24.10.1)(terser@5.44.1)
215
-
216
-
packages:
217
-
218
-
'@atcute/atproto@3.1.9':
219
-
resolution: {integrity: sha512-DyWwHCTdR4hY2BPNbLXgVmm7lI+fceOwWbE4LXbGvbvVtSn+ejSVFaAv01Ra3kWDha0whsOmbJL8JP0QPpf1+w==}
220
-
221
-
'@atcute/bluesky-richtext-parser@1.0.7':
222
-
resolution: {integrity: sha512-nOvU699OXiGMbyswao7JJnY0C9WkwE7PVC/m5WWt0UN9fsXSOor9IZWw+v9SATp+94BTJoG38XyUomUaJnoQRA==}
223
-
224
-
'@atcute/bluesky-richtext-segmenter@2.0.4':
225
-
resolution: {integrity: sha512-6m5QEAv4lU3qTy5MeJXJRRG33acipYJnMW1T7W/KrMyThGhQ7jSTTh8Z48quElgivgX7MDj6o/ow1oLUsjsCKw==}
226
-
227
-
'@atcute/bluesky@2.1.1':
228
-
resolution: {integrity: sha512-wEZfFW58J6yC1SqHcVJOn4qbHENTTzjeCEWthRT5HvKovADLqk54HSMSAuXDMBUbintSTBr0khQNZQ3ZdgzDdQ==}
229
-
peerDependencies:
230
-
'@atcute/client': ^3.0.0
231
-
232
-
'@atcute/bluesky@3.2.11':
233
-
resolution: {integrity: sha512-AboS6y4t+zaxIq7E4noue10csSpIuk/Uwo30/l6GgGBDPXrd7STw8Yb5nGZQP+TdG/uC8/c2mm7UnY65SDOh6A==}
234
-
235
-
'@atcute/client@3.1.0':
236
-
resolution: {integrity: sha512-+rQPsHXSf0DUm8XoHoaH7Y2E8tIpbsW84djyPj7dqAyrFIjvGuJ1X1DvMufwbTIcmLerdy+dzl34iZcz/h3Vhg==}
237
-
238
-
'@atcute/lexicons@1.2.5':
239
-
resolution: {integrity: sha512-9yO9WdgxW8jZ7SbzUycH710z+JmsQ9W9n5S6i6eghYju32kkluFmgBeS47r8e8p2+Dv4DemS7o/3SUGsX9FR5Q==}
240
-
241
-
'@babel/code-frame@7.27.1':
242
-
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
243
-
engines: {node: '>=6.9.0'}
244
-
245
-
'@babel/compat-data@7.28.5':
246
-
resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==}
247
-
engines: {node: '>=6.9.0'}
248
-
249
-
'@babel/core@7.28.5':
250
-
resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==}
251
-
engines: {node: '>=6.9.0'}
252
-
253
-
'@babel/generator@7.28.5':
254
-
resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==}
255
-
engines: {node: '>=6.9.0'}
256
-
257
-
'@babel/helper-annotate-as-pure@7.27.3':
258
-
resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==}
259
-
engines: {node: '>=6.9.0'}
260
-
261
-
'@babel/helper-compilation-targets@7.27.2':
262
-
resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==}
263
-
engines: {node: '>=6.9.0'}
264
-
265
-
'@babel/helper-globals@7.28.0':
266
-
resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
267
-
engines: {node: '>=6.9.0'}
268
-
269
-
'@babel/helper-module-imports@7.27.1':
270
-
resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==}
271
-
engines: {node: '>=6.9.0'}
272
-
273
-
'@babel/helper-module-transforms@7.28.3':
274
-
resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==}
275
-
engines: {node: '>=6.9.0'}
276
-
peerDependencies:
277
-
'@babel/core': ^7.0.0
278
-
279
-
'@babel/helper-plugin-utils@7.27.1':
280
-
resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==}
281
-
engines: {node: '>=6.9.0'}
282
-
283
-
'@babel/helper-string-parser@7.27.1':
284
-
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
285
-
engines: {node: '>=6.9.0'}
286
-
287
-
'@babel/helper-validator-identifier@7.28.5':
288
-
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
289
-
engines: {node: '>=6.9.0'}
290
-
291
-
'@babel/helper-validator-option@7.27.1':
292
-
resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
293
-
engines: {node: '>=6.9.0'}
294
-
295
-
'@babel/helpers@7.28.4':
296
-
resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==}
297
-
engines: {node: '>=6.9.0'}
298
-
299
-
'@babel/parser@7.28.5':
300
-
resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==}
301
-
engines: {node: '>=6.0.0'}
302
-
hasBin: true
303
-
304
-
'@babel/plugin-syntax-jsx@7.27.1':
305
-
resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==}
306
-
engines: {node: '>=6.9.0'}
307
-
peerDependencies:
308
-
'@babel/core': ^7.0.0-0
309
-
310
-
'@babel/plugin-transform-react-jsx-development@7.27.1':
311
-
resolution: {integrity: sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==}
312
-
engines: {node: '>=6.9.0'}
313
-
peerDependencies:
314
-
'@babel/core': ^7.0.0-0
315
-
316
-
'@babel/plugin-transform-react-jsx@7.27.1':
317
-
resolution: {integrity: sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==}
318
-
engines: {node: '>=6.9.0'}
319
-
peerDependencies:
320
-
'@babel/core': ^7.0.0-0
321
-
322
-
'@babel/runtime@7.28.4':
323
-
resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
324
-
engines: {node: '>=6.9.0'}
325
-
326
-
'@babel/template@7.27.2':
327
-
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
328
-
engines: {node: '>=6.9.0'}
329
-
330
-
'@babel/traverse@7.28.5':
331
-
resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==}
332
-
engines: {node: '>=6.9.0'}
333
-
334
-
'@babel/types@7.28.5':
335
-
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
336
-
engines: {node: '>=6.9.0'}
337
-
338
-
'@changesets/apply-release-plan@7.0.14':
339
-
resolution: {integrity: sha512-ddBvf9PHdy2YY0OUiEl3TV78mH9sckndJR14QAt87KLEbIov81XO0q0QAmvooBxXlqRRP8I9B7XOzZwQG7JkWA==}
340
-
341
-
'@changesets/assemble-release-plan@6.0.9':
342
-
resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==}
343
-
344
-
'@changesets/changelog-git@0.2.1':
345
-
resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==}
346
-
347
-
'@changesets/cli@2.29.8':
348
-
resolution: {integrity: sha512-1weuGZpP63YWUYjay/E84qqwcnt5yJMM0tep10Up7Q5cS/DGe2IZ0Uj3HNMxGhCINZuR7aO9WBMdKnPit5ZDPA==}
349
-
hasBin: true
350
-
351
-
'@changesets/config@3.1.2':
352
-
resolution: {integrity: sha512-CYiRhA4bWKemdYi/uwImjPxqWNpqGPNbEBdX1BdONALFIDK7MCUj6FPkzD+z9gJcvDFUQJn9aDVf4UG7OT6Kog==}
353
-
354
-
'@changesets/errors@0.2.0':
355
-
resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==}
356
-
357
-
'@changesets/get-dependents-graph@2.1.3':
358
-
resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==}
359
-
360
-
'@changesets/get-release-plan@4.0.14':
361
-
resolution: {integrity: sha512-yjZMHpUHgl4Xl5gRlolVuxDkm4HgSJqT93Ri1Uz8kGrQb+5iJ8dkXJ20M2j/Y4iV5QzS2c5SeTxVSKX+2eMI0g==}
362
-
363
-
'@changesets/get-version-range-type@0.4.0':
364
-
resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==}
365
-
366
-
'@changesets/git@3.0.4':
367
-
resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==}
368
-
369
-
'@changesets/logger@0.1.1':
370
-
resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==}
371
-
372
-
'@changesets/parse@0.4.2':
373
-
resolution: {integrity: sha512-Uo5MC5mfg4OM0jU3up66fmSn6/NE9INK+8/Vn/7sMVcdWg46zfbvvUSjD9EMonVqPi9fbrJH9SXHn48Tr1f2yA==}
374
-
375
-
'@changesets/pre@2.0.2':
376
-
resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==}
377
-
378
-
'@changesets/read@0.6.6':
379
-
resolution: {integrity: sha512-P5QaN9hJSQQKJShzzpBT13FzOSPyHbqdoIBUd2DJdgvnECCyO6LmAOWSV+O8se2TaZJVwSXjL+v9yhb+a9JeJg==}
380
-
381
-
'@changesets/should-skip-package@0.1.2':
382
-
resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==}
383
-
384
-
'@changesets/types@4.1.0':
385
-
resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==}
386
-
387
-
'@changesets/types@6.1.0':
388
-
resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==}
389
-
390
-
'@changesets/write@0.4.0':
391
-
resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==}
392
-
393
-
'@esbuild/aix-ppc64@0.25.12':
394
-
resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
395
-
engines: {node: '>=18'}
396
-
cpu: [ppc64]
397
-
os: [aix]
398
-
399
-
'@esbuild/android-arm64@0.25.12':
400
-
resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
401
-
engines: {node: '>=18'}
402
-
cpu: [arm64]
403
-
os: [android]
404
-
405
-
'@esbuild/android-arm@0.25.12':
406
-
resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
407
-
engines: {node: '>=18'}
408
-
cpu: [arm]
409
-
os: [android]
410
-
411
-
'@esbuild/android-x64@0.25.12':
412
-
resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
413
-
engines: {node: '>=18'}
414
-
cpu: [x64]
415
-
os: [android]
416
-
417
-
'@esbuild/darwin-arm64@0.25.12':
418
-
resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
419
-
engines: {node: '>=18'}
420
-
cpu: [arm64]
421
-
os: [darwin]
422
-
423
-
'@esbuild/darwin-x64@0.25.12':
424
-
resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
425
-
engines: {node: '>=18'}
426
-
cpu: [x64]
427
-
os: [darwin]
428
-
429
-
'@esbuild/freebsd-arm64@0.25.12':
430
-
resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
431
-
engines: {node: '>=18'}
432
-
cpu: [arm64]
433
-
os: [freebsd]
434
-
435
-
'@esbuild/freebsd-x64@0.25.12':
436
-
resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
437
-
engines: {node: '>=18'}
438
-
cpu: [x64]
439
-
os: [freebsd]
440
-
441
-
'@esbuild/linux-arm64@0.25.12':
442
-
resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
443
-
engines: {node: '>=18'}
444
-
cpu: [arm64]
445
-
os: [linux]
446
-
447
-
'@esbuild/linux-arm@0.25.12':
448
-
resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
449
-
engines: {node: '>=18'}
450
-
cpu: [arm]
451
-
os: [linux]
452
-
453
-
'@esbuild/linux-ia32@0.25.12':
454
-
resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
455
-
engines: {node: '>=18'}
456
-
cpu: [ia32]
457
-
os: [linux]
458
-
459
-
'@esbuild/linux-loong64@0.25.12':
460
-
resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
461
-
engines: {node: '>=18'}
462
-
cpu: [loong64]
463
-
os: [linux]
464
-
465
-
'@esbuild/linux-mips64el@0.25.12':
466
-
resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
467
-
engines: {node: '>=18'}
468
-
cpu: [mips64el]
469
-
os: [linux]
470
-
471
-
'@esbuild/linux-ppc64@0.25.12':
472
-
resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
473
-
engines: {node: '>=18'}
474
-
cpu: [ppc64]
475
-
os: [linux]
476
-
477
-
'@esbuild/linux-riscv64@0.25.12':
478
-
resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
479
-
engines: {node: '>=18'}
480
-
cpu: [riscv64]
481
-
os: [linux]
482
-
483
-
'@esbuild/linux-s390x@0.25.12':
484
-
resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
485
-
engines: {node: '>=18'}
486
-
cpu: [s390x]
487
-
os: [linux]
488
-
489
-
'@esbuild/linux-x64@0.25.12':
490
-
resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
491
-
engines: {node: '>=18'}
492
-
cpu: [x64]
493
-
os: [linux]
494
-
495
-
'@esbuild/netbsd-arm64@0.25.12':
496
-
resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
497
-
engines: {node: '>=18'}
498
-
cpu: [arm64]
499
-
os: [netbsd]
500
-
501
-
'@esbuild/netbsd-x64@0.25.12':
502
-
resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
503
-
engines: {node: '>=18'}
504
-
cpu: [x64]
505
-
os: [netbsd]
506
-
507
-
'@esbuild/openbsd-arm64@0.25.12':
508
-
resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
509
-
engines: {node: '>=18'}
510
-
cpu: [arm64]
511
-
os: [openbsd]
512
-
513
-
'@esbuild/openbsd-x64@0.25.12':
514
-
resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
515
-
engines: {node: '>=18'}
516
-
cpu: [x64]
517
-
os: [openbsd]
518
-
519
-
'@esbuild/openharmony-arm64@0.25.12':
520
-
resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
521
-
engines: {node: '>=18'}
522
-
cpu: [arm64]
523
-
os: [openharmony]
524
-
525
-
'@esbuild/sunos-x64@0.25.12':
526
-
resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
527
-
engines: {node: '>=18'}
528
-
cpu: [x64]
529
-
os: [sunos]
530
-
531
-
'@esbuild/win32-arm64@0.25.12':
532
-
resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
533
-
engines: {node: '>=18'}
534
-
cpu: [arm64]
535
-
os: [win32]
536
-
537
-
'@esbuild/win32-ia32@0.25.12':
538
-
resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
539
-
engines: {node: '>=18'}
540
-
cpu: [ia32]
541
-
os: [win32]
542
-
543
-
'@esbuild/win32-x64@0.25.12':
544
-
resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
545
-
engines: {node: '>=18'}
546
-
cpu: [x64]
547
-
os: [win32]
548
-
549
-
'@inquirer/external-editor@1.0.3':
550
-
resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==}
551
-
engines: {node: '>=18'}
552
-
peerDependencies:
553
-
'@types/node': '>=18'
554
-
peerDependenciesMeta:
555
-
'@types/node':
556
-
optional: true
557
-
558
-
'@isaacs/balanced-match@4.0.1':
559
-
resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==}
560
-
engines: {node: 20 || >=22}
561
-
562
-
'@isaacs/brace-expansion@5.0.0':
563
-
resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==}
564
-
engines: {node: 20 || >=22}
565
-
566
-
'@jridgewell/gen-mapping@0.3.13':
567
-
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
568
-
569
-
'@jridgewell/remapping@2.3.5':
570
-
resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
571
-
572
-
'@jridgewell/resolve-uri@3.1.2':
573
-
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
574
-
engines: {node: '>=6.0.0'}
575
-
576
-
'@jridgewell/source-map@0.3.11':
577
-
resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==}
578
-
579
-
'@jridgewell/sourcemap-codec@1.5.5':
580
-
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
581
-
582
-
'@jridgewell/trace-mapping@0.3.31':
583
-
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
584
-
585
-
'@manypkg/find-root@1.1.0':
586
-
resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==}
587
-
588
-
'@manypkg/get-packages@1.1.3':
589
-
resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==}
590
-
591
-
'@microsoft/api-extractor-model@7.32.1':
592
-
resolution: {integrity: sha512-u4yJytMYiUAnhcNQcZDTh/tVtlrzKlyKrQnLOV+4Qr/5gV+cpufWzCYAB1Q23URFqD6z2RoL2UYncM9xJVGNKA==}
593
-
594
-
'@microsoft/api-extractor@7.55.1':
595
-
resolution: {integrity: sha512-l8Z+8qrLkZFM3HM95Dbpqs6G39fpCa7O5p8A7AkA6hSevxkgwsOlLrEuPv0ADOyj5dI1Af5WVDiwpKG/ya5G3w==}
596
-
hasBin: true
597
-
598
-
'@microsoft/tsdoc-config@0.18.0':
599
-
resolution: {integrity: sha512-8N/vClYyfOH+l4fLkkr9+myAoR6M7akc8ntBJ4DJdWH2b09uVfr71+LTMpNyG19fNqWDg8KEDZhx5wxuqHyGjw==}
600
-
601
-
'@microsoft/tsdoc@0.16.0':
602
-
resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==}
603
-
604
-
'@nodelib/fs.scandir@2.1.5':
605
-
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
606
-
engines: {node: '>= 8'}
607
-
608
-
'@nodelib/fs.stat@2.0.5':
609
-
resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
610
-
engines: {node: '>= 8'}
611
-
612
-
'@nodelib/fs.walk@1.2.8':
613
-
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
614
-
engines: {node: '>= 8'}
615
-
616
-
'@preact/preset-vite@2.10.2':
617
-
resolution: {integrity: sha512-K9wHlJOtkE+cGqlyQ5v9kL3Ge0Ql4LlIZjkUTL+1zf3nNdF88F9UZN6VTV8jdzBX9Fl7WSzeNMSDG7qECPmSmg==}
618
-
peerDependencies:
619
-
'@babel/core': 7.x
620
-
vite: 2.x || 3.x || 4.x || 5.x || 6.x || 7.x
621
-
622
-
'@prefresh/babel-plugin@0.5.2':
623
-
resolution: {integrity: sha512-AOl4HG6dAxWkJ5ndPHBgBa49oo/9bOiJuRDKHLSTyH+Fd9x00shTXpdiTj1W41l6oQIwUOAgJeHMn4QwIDpHkA==}
624
-
625
-
'@prefresh/core@1.5.9':
626
-
resolution: {integrity: sha512-IKBKCPaz34OFVC+adiQ2qaTF5qdztO2/4ZPf4KsRTgjKosWqxVXmEbxCiUydYZRY8GVie+DQlKzQr9gt6HQ+EQ==}
627
-
peerDependencies:
628
-
preact: ^10.0.0 || ^11.0.0-0
629
-
630
-
'@prefresh/utils@1.2.1':
631
-
resolution: {integrity: sha512-vq/sIuN5nYfYzvyayXI4C2QkprfNaHUQ9ZX+3xLD8nL3rWyzpxOm1+K7RtMbhd+66QcaISViK7amjnheQ/4WZw==}
632
-
633
-
'@prefresh/vite@2.4.11':
634
-
resolution: {integrity: sha512-/XjURQqdRiCG3NpMmWqE9kJwrg9IchIOWHzulCfqg2sRe/8oQ1g5De7xrk9lbqPIQLn7ntBkKdqWXIj4E9YXyg==}
635
-
peerDependencies:
636
-
preact: ^10.4.0 || ^11.0.0-0
637
-
vite: '>=2.0.0'
638
-
639
-
'@rollup/pluginutils@4.2.1':
640
-
resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
641
-
engines: {node: '>= 8.0.0'}
642
-
643
-
'@rollup/pluginutils@5.3.0':
644
-
resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
645
-
engines: {node: '>=14.0.0'}
646
-
peerDependencies:
647
-
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
648
-
peerDependenciesMeta:
649
-
rollup:
650
-
optional: true
651
-
652
-
'@rollup/rollup-android-arm-eabi@4.53.3':
653
-
resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==}
654
-
cpu: [arm]
655
-
os: [android]
656
-
657
-
'@rollup/rollup-android-arm64@4.53.3':
658
-
resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==}
659
-
cpu: [arm64]
660
-
os: [android]
661
-
662
-
'@rollup/rollup-darwin-arm64@4.53.3':
663
-
resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==}
664
-
cpu: [arm64]
665
-
os: [darwin]
666
-
667
-
'@rollup/rollup-darwin-x64@4.53.3':
668
-
resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==}
669
-
cpu: [x64]
670
-
os: [darwin]
671
-
672
-
'@rollup/rollup-freebsd-arm64@4.53.3':
673
-
resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==}
674
-
cpu: [arm64]
675
-
os: [freebsd]
676
-
677
-
'@rollup/rollup-freebsd-x64@4.53.3':
678
-
resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==}
679
-
cpu: [x64]
680
-
os: [freebsd]
681
-
682
-
'@rollup/rollup-linux-arm-gnueabihf@4.53.3':
683
-
resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==}
684
-
cpu: [arm]
685
-
os: [linux]
686
-
687
-
'@rollup/rollup-linux-arm-musleabihf@4.53.3':
688
-
resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==}
689
-
cpu: [arm]
690
-
os: [linux]
691
-
692
-
'@rollup/rollup-linux-arm64-gnu@4.53.3':
693
-
resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==}
694
-
cpu: [arm64]
695
-
os: [linux]
696
-
697
-
'@rollup/rollup-linux-arm64-musl@4.53.3':
698
-
resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==}
699
-
cpu: [arm64]
700
-
os: [linux]
701
-
702
-
'@rollup/rollup-linux-loong64-gnu@4.53.3':
703
-
resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==}
704
-
cpu: [loong64]
705
-
os: [linux]
706
-
707
-
'@rollup/rollup-linux-ppc64-gnu@4.53.3':
708
-
resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==}
709
-
cpu: [ppc64]
710
-
os: [linux]
711
-
712
-
'@rollup/rollup-linux-riscv64-gnu@4.53.3':
713
-
resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==}
714
-
cpu: [riscv64]
715
-
os: [linux]
716
-
717
-
'@rollup/rollup-linux-riscv64-musl@4.53.3':
718
-
resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==}
719
-
cpu: [riscv64]
720
-
os: [linux]
721
-
722
-
'@rollup/rollup-linux-s390x-gnu@4.53.3':
723
-
resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==}
724
-
cpu: [s390x]
725
-
os: [linux]
726
-
727
-
'@rollup/rollup-linux-x64-gnu@4.53.3':
728
-
resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==}
729
-
cpu: [x64]
730
-
os: [linux]
731
-
732
-
'@rollup/rollup-linux-x64-musl@4.53.3':
733
-
resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==}
734
-
cpu: [x64]
735
-
os: [linux]
736
-
737
-
'@rollup/rollup-openharmony-arm64@4.53.3':
738
-
resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==}
739
-
cpu: [arm64]
740
-
os: [openharmony]
741
-
742
-
'@rollup/rollup-win32-arm64-msvc@4.53.3':
743
-
resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==}
744
-
cpu: [arm64]
745
-
os: [win32]
746
-
747
-
'@rollup/rollup-win32-ia32-msvc@4.53.3':
748
-
resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==}
749
-
cpu: [ia32]
750
-
os: [win32]
751
-
752
-
'@rollup/rollup-win32-x64-gnu@4.53.3':
753
-
resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==}
754
-
cpu: [x64]
755
-
os: [win32]
756
-
757
-
'@rollup/rollup-win32-x64-msvc@4.53.3':
758
-
resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==}
759
-
cpu: [x64]
760
-
os: [win32]
761
-
762
-
'@rushstack/node-core-library@5.19.0':
763
-
resolution: {integrity: sha512-BxAopbeWBvNJ6VGiUL+5lbJXywTdsnMeOS8j57Cn/xY10r6sV/gbsTlfYKjzVCUBZATX2eRzJHSMCchsMTGN6A==}
764
-
peerDependencies:
765
-
'@types/node': '*'
766
-
peerDependenciesMeta:
767
-
'@types/node':
768
-
optional: true
769
-
770
-
'@rushstack/problem-matcher@0.1.1':
771
-
resolution: {integrity: sha512-Fm5XtS7+G8HLcJHCWpES5VmeMyjAKaWeyZU5qPzZC+22mPlJzAsOxymHiWIfuirtPckX3aptWws+K2d0BzniJA==}
772
-
peerDependencies:
773
-
'@types/node': '*'
774
-
peerDependenciesMeta:
775
-
'@types/node':
776
-
optional: true
777
-
778
-
'@rushstack/rig-package@0.6.0':
779
-
resolution: {integrity: sha512-ZQmfzsLE2+Y91GF15c65L/slMRVhF6Hycq04D4TwtdGaUAbIXXg9c5pKA5KFU7M4QMaihoobp9JJYpYcaY3zOw==}
780
-
781
-
'@rushstack/terminal@0.19.4':
782
-
resolution: {integrity: sha512-f4XQk02CrKfrMgyOfhYd3qWI944dLC21S4I/LUhrlAP23GTMDNG6EK5effQtFkISwUKCgD9vMBrJZaPSUquxWQ==}
783
-
peerDependencies:
784
-
'@types/node': '*'
785
-
peerDependenciesMeta:
786
-
'@types/node':
787
-
optional: true
788
-
789
-
'@rushstack/ts-command-line@5.1.4':
790
-
resolution: {integrity: sha512-H0I6VdJ6sOUbktDFpP2VW5N29w8v4hRoNZOQz02vtEi6ZTYL1Ju8u+TcFiFawUDrUsx/5MQTUhd79uwZZVwVlA==}
791
-
792
-
'@standard-schema/spec@1.0.0':
793
-
resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
794
-
795
-
'@sveltejs/acorn-typescript@1.0.8':
796
-
resolution: {integrity: sha512-esgN+54+q0NjB0Y/4BomT9samII7jGwNy/2a3wNZbT2A2RpmXsXwUt24LvLhx6jUq2gVk4cWEvcRO6MFQbOfNA==}
797
-
peerDependencies:
798
-
acorn: ^8.9.0
799
-
800
-
'@sveltejs/vite-plugin-svelte-inspector@5.0.1':
801
-
resolution: {integrity: sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==}
802
-
engines: {node: ^20.19 || ^22.12 || >=24}
803
-
peerDependencies:
804
-
'@sveltejs/vite-plugin-svelte': ^6.0.0-next.0
805
-
svelte: ^5.0.0
806
-
vite: ^6.3.0 || ^7.0.0
807
-
808
-
'@sveltejs/vite-plugin-svelte@6.2.1':
809
-
resolution: {integrity: sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==}
810
-
engines: {node: ^20.19 || ^22.12 || >=24}
811
-
peerDependencies:
812
-
svelte: ^5.0.0
813
-
vite: ^6.3.0 || ^7.0.0
814
-
815
-
'@tsconfig/svelte@5.0.6':
816
-
resolution: {integrity: sha512-yGxYL0I9eETH1/DR9qVJey4DAsCdeau4a9wYPKuXfEhm8lFO8wg+LLYJjIpAm6Fw7HSlhepPhYPDop75485yWQ==}
817
-
818
-
'@types/argparse@1.0.38':
819
-
resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==}
820
-
821
-
'@types/estree@1.0.8':
822
-
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
823
-
824
-
'@types/node@12.20.55':
825
-
resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
826
-
827
-
'@types/node@24.10.1':
828
-
resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==}
829
-
830
-
'@volar/language-core@2.4.26':
831
-
resolution: {integrity: sha512-hH0SMitMxnB43OZpyF1IFPS9bgb2I3bpCh76m2WEK7BE0A0EzpYsRp0CCH2xNKshr7kacU5TQBLYn4zj7CG60A==}
832
-
833
-
'@volar/source-map@2.4.26':
834
-
resolution: {integrity: sha512-JJw0Tt/kSFsIRmgTQF4JSt81AUSI1aEye5Zl65EeZ8H35JHnTvFGmpDOBn5iOxd48fyGE+ZvZBp5FcgAy/1Qhw==}
835
-
836
-
'@volar/typescript@2.4.26':
837
-
resolution: {integrity: sha512-N87ecLD48Sp6zV9zID/5yuS1+5foj0DfuYGdQ6KHj/IbKvyKv1zNX6VCmnKYwtmHadEO6mFc2EKISiu3RDPAvA==}
838
-
839
-
'@vue/compiler-core@3.5.25':
840
-
resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==}
841
-
842
-
'@vue/compiler-dom@3.5.25':
843
-
resolution: {integrity: sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==}
844
-
845
-
'@vue/compiler-vue2@2.7.16':
846
-
resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==}
847
-
848
-
'@vue/language-core@2.2.0':
849
-
resolution: {integrity: sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==}
850
-
peerDependencies:
851
-
typescript: '*'
852
-
peerDependenciesMeta:
853
-
typescript:
854
-
optional: true
855
-
856
-
'@vue/shared@3.5.25':
857
-
resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==}
858
-
859
-
acorn@8.15.0:
860
-
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
861
-
engines: {node: '>=0.4.0'}
862
-
hasBin: true
863
-
864
-
ajv-draft-04@1.0.0:
865
-
resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
866
-
peerDependencies:
867
-
ajv: ^8.5.0
868
-
peerDependenciesMeta:
869
-
ajv:
870
-
optional: true
871
-
872
-
ajv-formats@3.0.1:
873
-
resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
874
-
peerDependencies:
875
-
ajv: ^8.0.0
876
-
peerDependenciesMeta:
877
-
ajv:
878
-
optional: true
879
-
880
-
ajv@8.12.0:
881
-
resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==}
882
-
883
-
ajv@8.13.0:
884
-
resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==}
885
-
886
-
alien-signals@0.4.14:
887
-
resolution: {integrity: sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==}
888
-
889
-
ansi-colors@4.1.3:
890
-
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
891
-
engines: {node: '>=6'}
892
-
893
-
ansi-regex@5.0.1:
894
-
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
895
-
engines: {node: '>=8'}
896
-
897
-
argparse@1.0.10:
898
-
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
899
-
900
-
argparse@2.0.1:
901
-
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
902
-
903
-
aria-query@5.3.2:
904
-
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
905
-
engines: {node: '>= 0.4'}
906
-
907
-
array-union@2.1.0:
908
-
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
909
-
engines: {node: '>=8'}
910
-
911
-
axobject-query@4.1.0:
912
-
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
913
-
engines: {node: '>= 0.4'}
914
-
915
-
babel-plugin-transform-hook-names@1.0.2:
916
-
resolution: {integrity: sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==}
917
-
peerDependencies:
918
-
'@babel/core': ^7.12.10
919
-
920
-
balanced-match@1.0.2:
921
-
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
922
-
923
-
baseline-browser-mapping@2.9.0:
924
-
resolution: {integrity: sha512-Mh++g+2LPfzZToywfE1BUzvZbfOY52Nil0rn9H1CPC5DJ7fX+Vir7nToBeoiSbB1zTNeGYbELEvJESujgGrzXw==}
925
-
hasBin: true
926
-
927
-
better-path-resolve@1.0.0:
928
-
resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==}
929
-
engines: {node: '>=4'}
930
-
931
-
boolbase@1.0.0:
932
-
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
933
-
934
-
brace-expansion@2.0.2:
935
-
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
936
-
937
-
braces@3.0.3:
938
-
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
939
-
engines: {node: '>=8'}
940
-
941
-
browserslist@4.28.1:
942
-
resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==}
943
-
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
944
-
hasBin: true
945
-
946
-
buffer-from@1.1.2:
947
-
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
948
-
949
-
caniuse-lite@1.0.30001759:
950
-
resolution: {integrity: sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==}
951
-
952
-
chardet@2.1.1:
953
-
resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==}
954
-
955
-
chokidar@4.0.3:
956
-
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
957
-
engines: {node: '>= 14.16.0'}
958
-
959
-
ci-info@3.9.0:
960
-
resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
961
-
engines: {node: '>=8'}
962
-
963
-
clsx@2.1.1:
964
-
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
965
-
engines: {node: '>=6'}
966
-
967
-
commander@2.20.3:
968
-
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
969
-
970
-
compare-versions@6.1.1:
971
-
resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==}
972
-
973
-
confbox@0.1.8:
974
-
resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
975
-
976
-
confbox@0.2.2:
977
-
resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==}
978
-
979
-
convert-source-map@2.0.0:
980
-
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
981
-
982
-
cross-spawn@7.0.6:
983
-
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
984
-
engines: {node: '>= 8'}
985
-
986
-
css-declaration-sorter@7.3.0:
987
-
resolution: {integrity: sha512-LQF6N/3vkAMYF4xoHLJfG718HRJh34Z8BnNhd6bosOMIVjMlhuZK5++oZa3uYAgrI5+7x2o27gUqTR2U/KjUOQ==}
988
-
engines: {node: ^14 || ^16 || >=18}
989
-
peerDependencies:
990
-
postcss: ^8.0.9
991
-
992
-
css-select@5.2.2:
993
-
resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
994
-
995
-
css-what@6.2.2:
996
-
resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==}
997
-
engines: {node: '>= 6'}
998
-
999
-
de-indent@1.0.2:
1000
-
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
1001
-
1002
-
debug@4.4.3:
1003
-
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
1004
-
engines: {node: '>=6.0'}
1005
-
peerDependencies:
1006
-
supports-color: '*'
1007
-
peerDependenciesMeta:
1008
-
supports-color:
1009
-
optional: true
1010
-
1011
-
deepmerge@4.3.1:
1012
-
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
1013
-
engines: {node: '>=0.10.0'}
1014
-
1015
-
detect-indent@6.1.0:
1016
-
resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==}
1017
-
engines: {node: '>=8'}
1018
-
1019
-
devalue@5.5.0:
1020
-
resolution: {integrity: sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==}
1021
-
1022
-
diff@8.0.2:
1023
-
resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==}
1024
-
engines: {node: '>=0.3.1'}
1025
-
1026
-
dir-glob@3.0.1:
1027
-
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
1028
-
engines: {node: '>=8'}
1029
-
1030
-
dom-serializer@2.0.0:
1031
-
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
1032
-
1033
-
domelementtype@2.3.0:
1034
-
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
1035
-
1036
-
domhandler@5.0.3:
1037
-
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
1038
-
engines: {node: '>= 4'}
1039
-
1040
-
domutils@3.2.2:
1041
-
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
1042
-
1043
-
electron-to-chromium@1.5.264:
1044
-
resolution: {integrity: sha512-1tEf0nLgltC3iy9wtlYDlQDc5Rg9lEKVjEmIHJ21rI9OcqkvD45K1oyNIRA4rR1z3LgJ7KeGzEBojVcV6m4qjA==}
1045
-
1046
-
enquirer@2.4.1:
1047
-
resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==}
1048
-
engines: {node: '>=8.6'}
1049
-
1050
-
entities@4.5.0:
1051
-
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
1052
-
engines: {node: '>=0.12'}
1053
-
1054
-
esbuild@0.25.12:
1055
-
resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
1056
-
engines: {node: '>=18'}
1057
-
hasBin: true
1058
-
1059
-
escalade@3.2.0:
1060
-
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
1061
-
engines: {node: '>=6'}
1062
-
1063
-
esm-env@1.2.2:
1064
-
resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==}
1065
-
1066
-
esprima@4.0.1:
1067
-
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
1068
-
engines: {node: '>=4'}
1069
-
hasBin: true
1070
-
1071
-
esrap@2.2.1:
1072
-
resolution: {integrity: sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==}
1073
-
1074
-
estree-walker@2.0.2:
1075
-
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
1076
-
1077
-
exsolve@1.0.8:
1078
-
resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==}
1079
-
1080
-
extendable-error@0.1.7:
1081
-
resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==}
1082
-
1083
-
fast-deep-equal@3.1.3:
1084
-
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
1085
-
1086
-
fast-glob@3.3.3:
1087
-
resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
1088
-
engines: {node: '>=8.6.0'}
1089
-
1090
-
fastq@1.19.1:
1091
-
resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
1092
-
1093
-
fdir@6.5.0:
1094
-
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
1095
-
engines: {node: '>=12.0.0'}
1096
-
peerDependencies:
1097
-
picomatch: ^3 || ^4
1098
-
peerDependenciesMeta:
1099
-
picomatch:
1100
-
optional: true
1101
-
1102
-
fill-range@7.1.1:
1103
-
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
1104
-
engines: {node: '>=8'}
1105
-
1106
-
find-up@4.1.0:
1107
-
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
1108
-
engines: {node: '>=8'}
1109
-
1110
-
fs-extra@11.3.2:
1111
-
resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==}
1112
-
engines: {node: '>=14.14'}
1113
-
1114
-
fs-extra@7.0.1:
1115
-
resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
1116
-
engines: {node: '>=6 <7 || >=8'}
1117
-
1118
-
fs-extra@8.1.0:
1119
-
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
1120
-
engines: {node: '>=6 <7 || >=8'}
1121
-
1122
-
fsevents@2.3.3:
1123
-
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
1124
-
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
1125
-
os: [darwin]
1126
-
1127
-
function-bind@1.1.2:
1128
-
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
1129
-
1130
-
gensync@1.0.0-beta.2:
1131
-
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
1132
-
engines: {node: '>=6.9.0'}
1133
-
1134
-
glob-parent@5.1.2:
1135
-
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
1136
-
engines: {node: '>= 6'}
1137
-
1138
-
globby@11.1.0:
1139
-
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
1140
-
engines: {node: '>=10'}
1141
-
1142
-
graceful-fs@4.2.11:
1143
-
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
1144
-
1145
-
has-flag@4.0.0:
1146
-
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
1147
-
engines: {node: '>=8'}
1148
-
1149
-
hasown@2.0.2:
1150
-
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
1151
-
engines: {node: '>= 0.4'}
1152
-
1153
-
he@1.2.0:
1154
-
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
1155
-
hasBin: true
1156
-
1157
-
human-id@4.1.3:
1158
-
resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==}
1159
-
hasBin: true
1160
-
1161
-
iconv-lite@0.7.0:
1162
-
resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==}
1163
-
engines: {node: '>=0.10.0'}
1164
-
1165
-
ignore@5.3.2:
1166
-
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
1167
-
engines: {node: '>= 4'}
1168
-
1169
-
import-lazy@4.0.0:
1170
-
resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==}
1171
-
engines: {node: '>=8'}
1172
-
1173
-
is-core-module@2.16.1:
1174
-
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
1175
-
engines: {node: '>= 0.4'}
1176
-
1177
-
is-extglob@2.1.1:
1178
-
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
1179
-
engines: {node: '>=0.10.0'}
1180
-
1181
-
is-glob@4.0.3:
1182
-
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
1183
-
engines: {node: '>=0.10.0'}
1184
-
1185
-
is-number@7.0.0:
1186
-
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
1187
-
engines: {node: '>=0.12.0'}
1188
-
1189
-
is-reference@3.0.3:
1190
-
resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==}
1191
-
1192
-
is-subdir@1.2.0:
1193
-
resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==}
1194
-
engines: {node: '>=4'}
1195
-
1196
-
is-windows@1.0.2:
1197
-
resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
1198
-
engines: {node: '>=0.10.0'}
1199
-
1200
-
isexe@2.0.0:
1201
-
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
1202
-
1203
-
jju@1.4.0:
1204
-
resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
1205
-
1206
-
js-tokens@4.0.0:
1207
-
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
1208
-
1209
-
js-yaml@3.14.2:
1210
-
resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==}
1211
-
hasBin: true
1212
-
1213
-
js-yaml@4.1.1:
1214
-
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
1215
-
hasBin: true
1216
-
1217
-
jsesc@3.1.0:
1218
-
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
1219
-
engines: {node: '>=6'}
1220
-
hasBin: true
1221
-
1222
-
json-schema-traverse@1.0.0:
1223
-
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
1224
-
1225
-
json5@2.2.3:
1226
-
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
1227
-
engines: {node: '>=6'}
1228
-
hasBin: true
1229
-
1230
-
jsonfile@4.0.0:
1231
-
resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
1232
-
1233
-
jsonfile@6.2.0:
1234
-
resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==}
1235
-
1236
-
kolorist@1.8.0:
1237
-
resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
1238
-
1239
-
local-pkg@1.1.2:
1240
-
resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==}
1241
-
engines: {node: '>=14'}
1242
-
1243
-
locate-character@3.0.0:
1244
-
resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
1245
-
1246
-
locate-path@5.0.0:
1247
-
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
1248
-
engines: {node: '>=8'}
1249
-
1250
-
lodash.startcase@4.4.0:
1251
-
resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==}
1252
-
1253
-
lodash@4.17.21:
1254
-
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
1255
-
1256
-
lru-cache@5.1.1:
1257
-
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
1258
-
1259
-
lru-cache@6.0.0:
1260
-
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
1261
-
engines: {node: '>=10'}
1262
-
1263
-
magic-string@0.30.21:
1264
-
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
1265
-
1266
-
merge2@1.4.1:
1267
-
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
1268
-
engines: {node: '>= 8'}
1269
-
1270
-
micromatch@4.0.8:
1271
-
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
1272
-
engines: {node: '>=8.6'}
1273
-
1274
-
minimatch@10.0.3:
1275
-
resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==}
1276
-
engines: {node: 20 || >=22}
1277
-
1278
-
minimatch@9.0.5:
1279
-
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
1280
-
engines: {node: '>=16 || 14 >=14.17'}
1281
-
1282
-
mlly@1.8.0:
1283
-
resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==}
1284
-
1285
-
mri@1.2.0:
1286
-
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
1287
-
engines: {node: '>=4'}
1288
-
1289
-
ms@2.1.3:
1290
-
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
1291
-
1292
-
muggle-string@0.4.1:
1293
-
resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
1294
-
1295
-
nanoid@3.3.11:
1296
-
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
1297
-
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
1298
-
hasBin: true
1299
-
1300
-
node-html-parser@6.1.13:
1301
-
resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==}
1302
-
1303
-
node-releases@2.0.27:
1304
-
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
1305
-
1306
-
nth-check@2.1.1:
1307
-
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
1308
-
1309
-
outdent@0.5.0:
1310
-
resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==}
1311
-
1312
-
p-filter@2.1.0:
1313
-
resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==}
1314
-
engines: {node: '>=8'}
1315
-
1316
-
p-limit@2.3.0:
1317
-
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
1318
-
engines: {node: '>=6'}
1319
-
1320
-
p-locate@4.1.0:
1321
-
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
1322
-
engines: {node: '>=8'}
1323
-
1324
-
p-map@2.1.0:
1325
-
resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==}
1326
-
engines: {node: '>=6'}
1327
-
1328
-
p-try@2.2.0:
1329
-
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
1330
-
engines: {node: '>=6'}
1331
-
1332
-
package-manager-detector@0.2.11:
1333
-
resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==}
1334
-
1335
-
path-browserify@1.0.1:
1336
-
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
1337
-
1338
-
path-exists@4.0.0:
1339
-
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
1340
-
engines: {node: '>=8'}
1341
-
1342
-
path-key@3.1.1:
1343
-
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
1344
-
engines: {node: '>=8'}
1345
-
1346
-
path-parse@1.0.7:
1347
-
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
1348
-
1349
-
path-type@4.0.0:
1350
-
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
1351
-
engines: {node: '>=8'}
1352
-
1353
-
pathe@2.0.3:
1354
-
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
1355
-
1356
-
picocolors@1.1.1:
1357
-
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
1358
-
1359
-
picomatch@2.3.1:
1360
-
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1361
-
engines: {node: '>=8.6'}
1362
-
1363
-
picomatch@4.0.3:
1364
-
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
1365
-
engines: {node: '>=12'}
1366
-
1367
-
pify@4.0.1:
1368
-
resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
1369
-
engines: {node: '>=6'}
1370
-
1371
-
pkg-types@1.3.1:
1372
-
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
1373
-
1374
-
pkg-types@2.3.0:
1375
-
resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==}
1376
-
1377
-
postcss-less@6.0.0:
1378
-
resolution: {integrity: sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==}
1379
-
engines: {node: '>=12'}
1380
-
peerDependencies:
1381
-
postcss: ^8.3.5
1382
-
1383
-
postcss-scss@4.0.9:
1384
-
resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==}
1385
-
engines: {node: '>=12.0'}
1386
-
peerDependencies:
1387
-
postcss: ^8.4.29
1388
-
1389
-
postcss@8.5.6:
1390
-
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
1391
-
engines: {node: ^10 || ^12 || >=14}
1392
-
1393
-
preact@10.28.0:
1394
-
resolution: {integrity: sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA==}
1395
-
1396
-
prettier-plugin-css-order@2.1.2:
1397
-
resolution: {integrity: sha512-vomxPjHI6pOMYcBuouSJHxxQClJXaUpU9rsV9IAO2wrSTZILRRlrxAAR8t9UF6wtczLkLfNRFUwM+ZbGXOONUA==}
1398
-
engines: {node: '>=16'}
1399
-
peerDependencies:
1400
-
prettier: 3.x
1401
-
1402
-
prettier-plugin-svelte@3.4.0:
1403
-
resolution: {integrity: sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==}
1404
-
peerDependencies:
1405
-
prettier: ^3.0.0
1406
-
svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0
1407
-
1408
-
prettier@2.8.8:
1409
-
resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
1410
-
engines: {node: '>=10.13.0'}
1411
-
hasBin: true
1412
-
1413
-
prettier@3.7.4:
1414
-
resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==}
1415
-
engines: {node: '>=14'}
1416
-
hasBin: true
1417
-
1418
-
punycode@2.3.1:
1419
-
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
1420
-
engines: {node: '>=6'}
1421
-
1422
-
quansync@0.2.11:
1423
-
resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
1424
-
1425
-
queue-microtask@1.2.3:
1426
-
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
1427
-
1428
-
read-yaml-file@1.1.0:
1429
-
resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==}
1430
-
engines: {node: '>=6'}
1431
-
1432
-
readdirp@4.1.2:
1433
-
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
1434
-
engines: {node: '>= 14.18.0'}
1435
-
1436
-
require-from-string@2.0.2:
1437
-
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
1438
-
engines: {node: '>=0.10.0'}
1439
-
1440
-
resolve-from@5.0.0:
1441
-
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
1442
-
engines: {node: '>=8'}
1443
-
1444
-
resolve@1.22.11:
1445
-
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
1446
-
engines: {node: '>= 0.4'}
1447
-
hasBin: true
1448
-
1449
-
reusify@1.1.0:
1450
-
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
1451
-
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
1452
-
1453
-
rollup@4.53.3:
1454
-
resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==}
1455
-
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
1456
-
hasBin: true
1457
-
1458
-
run-parallel@1.2.0:
1459
-
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
1460
-
1461
-
sade@1.8.1:
1462
-
resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
1463
-
engines: {node: '>=6'}
1464
-
1465
-
safer-buffer@2.1.2:
1466
-
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
1467
-
1468
-
semver@6.3.1:
1469
-
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
1470
-
hasBin: true
1471
-
1472
-
semver@7.5.4:
1473
-
resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
1474
-
engines: {node: '>=10'}
1475
-
hasBin: true
1476
-
1477
-
semver@7.7.3:
1478
-
resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==}
1479
-
engines: {node: '>=10'}
1480
-
hasBin: true
1481
-
1482
-
shebang-command@2.0.0:
1483
-
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
1484
-
engines: {node: '>=8'}
1485
-
1486
-
shebang-regex@3.0.0:
1487
-
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
1488
-
engines: {node: '>=8'}
1489
-
1490
-
signal-exit@4.1.0:
1491
-
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
1492
-
engines: {node: '>=14'}
1493
-
1494
-
simple-code-frame@1.3.0:
1495
-
resolution: {integrity: sha512-MB4pQmETUBlNs62BBeRjIFGeuy/x6gGKh7+eRUemn1rCFhqo7K+4slPqsyizCbcbYLnaYqaoZ2FWsZ/jN06D8w==}
1496
-
1497
-
slash@3.0.0:
1498
-
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
1499
-
engines: {node: '>=8'}
1500
-
1501
-
source-map-js@1.2.1:
1502
-
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
1503
-
engines: {node: '>=0.10.0'}
1504
-
1505
-
source-map-support@0.5.21:
1506
-
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
1507
-
1508
-
source-map@0.6.1:
1509
-
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
1510
-
engines: {node: '>=0.10.0'}
1511
-
1512
-
source-map@0.7.6:
1513
-
resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==}
1514
-
engines: {node: '>= 12'}
1515
-
1516
-
spawndamnit@3.0.1:
1517
-
resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==}
1518
-
1519
-
sprintf-js@1.0.3:
1520
-
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
1521
-
1522
-
stack-trace@1.0.0-pre2:
1523
-
resolution: {integrity: sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==}
1524
-
engines: {node: '>=16'}
1525
-
1526
-
string-argv@0.3.2:
1527
-
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
1528
-
engines: {node: '>=0.6.19'}
1529
-
1530
-
strip-ansi@6.0.1:
1531
-
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
1532
-
engines: {node: '>=8'}
1533
-
1534
-
strip-bom@3.0.0:
1535
-
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
1536
-
engines: {node: '>=4'}
1537
-
1538
-
strip-json-comments@3.1.1:
1539
-
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
1540
-
engines: {node: '>=8'}
1541
-
1542
-
supports-color@8.1.1:
1543
-
resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
1544
-
engines: {node: '>=10'}
1545
-
1546
-
supports-preserve-symlinks-flag@1.0.0:
1547
-
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
1548
-
engines: {node: '>= 0.4'}
1549
-
1550
-
svelte-check@4.3.4:
1551
-
resolution: {integrity: sha512-DVWvxhBrDsd+0hHWKfjP99lsSXASeOhHJYyuKOFYJcP7ThfSCKgjVarE8XfuMWpS5JV3AlDf+iK1YGGo2TACdw==}
1552
-
engines: {node: '>= 18.0.0'}
1553
-
hasBin: true
1554
-
peerDependencies:
1555
-
svelte: ^4.0.0 || ^5.0.0-next.0
1556
-
typescript: '>=5.0.0'
1557
-
1558
-
svelte@5.45.5:
1559
-
resolution: {integrity: sha512-2074U+vObO5Zs8/qhxtBwdi6ZXNIhEBTzNmUFjiZexLxTdt9vq96D/0pnQELl6YcpLMD7pZ2dhXKByfGS8SAdg==}
1560
-
engines: {node: '>=18'}
1561
-
1562
-
term-size@2.2.1:
1563
-
resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==}
1564
-
engines: {node: '>=8'}
1565
-
1566
-
terser@5.44.1:
1567
-
resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==}
1568
-
engines: {node: '>=10'}
1569
-
hasBin: true
1570
-
1571
-
tinyglobby@0.2.15:
1572
-
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
1573
-
engines: {node: '>=12.0.0'}
1574
-
1575
-
to-regex-range@5.0.1:
1576
-
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
1577
-
engines: {node: '>=8.0'}
1578
-
1579
-
tslib@2.8.1:
1580
-
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
1581
-
1582
-
typescript@5.8.2:
1583
-
resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==}
1584
-
engines: {node: '>=14.17'}
1585
-
hasBin: true
1586
-
1587
-
typescript@5.8.3:
1588
-
resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
1589
-
engines: {node: '>=14.17'}
1590
-
hasBin: true
1591
-
1592
-
ufo@1.6.1:
1593
-
resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
1594
-
1595
-
undici-types@7.16.0:
1596
-
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
1597
-
1598
-
universalify@0.1.2:
1599
-
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
1600
-
engines: {node: '>= 4.0.0'}
1601
-
1602
-
universalify@2.0.1:
1603
-
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
1604
-
engines: {node: '>= 10.0.0'}
1605
-
1606
-
update-browserslist-db@1.2.1:
1607
-
resolution: {integrity: sha512-R9NcHbbZ45RoWfTdhn1J9SS7zxNvlddv4YRrHTUaFdtjbmfncfedB45EC9IaqJQ97iAR1GZgOfyRQO+ExIF6EQ==}
1608
-
hasBin: true
1609
-
peerDependencies:
1610
-
browserslist: '>= 4.21.0'
1611
-
1612
-
uri-js@4.4.1:
1613
-
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
1614
-
1615
-
vite-plugin-dts@4.5.4:
1616
-
resolution: {integrity: sha512-d4sOM8M/8z7vRXHHq/ebbblfaxENjogAAekcfcDCCwAyvGqnPrc7f4NZbvItS+g4WTgerW0xDwSz5qz11JT3vg==}
1617
-
peerDependencies:
1618
-
typescript: '*'
1619
-
vite: '*'
1620
-
peerDependenciesMeta:
1621
-
vite:
1622
-
optional: true
1623
-
1624
-
vite-prerender-plugin@0.5.12:
1625
-
resolution: {integrity: sha512-EiwhbMn+flg14EysbLTmZSzq8NGTxhytgK3bf4aGRF1evWLGwZiHiUJ1KZDvbxgKbMf2pG6fJWGEa3UZXOnR1g==}
1626
-
peerDependencies:
1627
-
vite: 5.x || 6.x || 7.x
1628
-
1629
-
vite@7.2.6:
1630
-
resolution: {integrity: sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==}
1631
-
engines: {node: ^20.19.0 || >=22.12.0}
1632
-
hasBin: true
1633
-
peerDependencies:
1634
-
'@types/node': ^20.19.0 || >=22.12.0
1635
-
jiti: '>=1.21.0'
1636
-
less: ^4.0.0
1637
-
lightningcss: ^1.21.0
1638
-
sass: ^1.70.0
1639
-
sass-embedded: ^1.70.0
1640
-
stylus: '>=0.54.8'
1641
-
sugarss: ^5.0.0
1642
-
terser: ^5.16.0
1643
-
tsx: ^4.8.1
1644
-
yaml: ^2.4.2
1645
-
peerDependenciesMeta:
1646
-
'@types/node':
1647
-
optional: true
1648
-
jiti:
1649
-
optional: true
1650
-
less:
1651
-
optional: true
1652
-
lightningcss:
1653
-
optional: true
1654
-
sass:
1655
-
optional: true
1656
-
sass-embedded:
1657
-
optional: true
1658
-
stylus:
1659
-
optional: true
1660
-
sugarss:
1661
-
optional: true
1662
-
terser:
1663
-
optional: true
1664
-
tsx:
1665
-
optional: true
1666
-
yaml:
1667
-
optional: true
1668
-
1669
-
vitefu@1.1.1:
1670
-
resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==}
1671
-
peerDependencies:
1672
-
vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0
1673
-
peerDependenciesMeta:
1674
-
vite:
1675
-
optional: true
1676
-
1677
-
vscode-uri@3.1.0:
1678
-
resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
1679
-
1680
-
which@2.0.2:
1681
-
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
1682
-
engines: {node: '>= 8'}
1683
-
hasBin: true
1684
-
1685
-
yallist@3.1.1:
1686
-
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
1687
-
1688
-
yallist@4.0.0:
1689
-
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
1690
-
1691
-
zimmerframe@1.1.4:
1692
-
resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==}
1693
-
1694
-
snapshots:
1695
-
1696
-
'@atcute/atproto@3.1.9':
1697
-
dependencies:
1698
-
'@atcute/lexicons': 1.2.5
1699
-
1700
-
'@atcute/bluesky-richtext-parser@1.0.7': {}
1701
-
1702
-
'@atcute/bluesky-richtext-segmenter@2.0.4':
1703
-
dependencies:
1704
-
'@atcute/bluesky': 3.2.11
1705
-
'@atcute/lexicons': 1.2.5
1706
-
1707
-
'@atcute/bluesky@2.1.1(@atcute/client@3.1.0)':
1708
-
dependencies:
1709
-
'@atcute/client': 3.1.0
1710
-
1711
-
'@atcute/bluesky@3.2.11':
1712
-
dependencies:
1713
-
'@atcute/atproto': 3.1.9
1714
-
'@atcute/lexicons': 1.2.5
1715
-
1716
-
'@atcute/client@3.1.0': {}
1717
-
1718
-
'@atcute/lexicons@1.2.5':
1719
-
dependencies:
1720
-
'@standard-schema/spec': 1.0.0
1721
-
esm-env: 1.2.2
1722
-
1723
-
'@babel/code-frame@7.27.1':
1724
-
dependencies:
1725
-
'@babel/helper-validator-identifier': 7.28.5
1726
-
js-tokens: 4.0.0
1727
-
picocolors: 1.1.1
1728
-
1729
-
'@babel/compat-data@7.28.5': {}
1730
-
1731
-
'@babel/core@7.28.5':
1732
-
dependencies:
1733
-
'@babel/code-frame': 7.27.1
1734
-
'@babel/generator': 7.28.5
1735
-
'@babel/helper-compilation-targets': 7.27.2
1736
-
'@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5)
1737
-
'@babel/helpers': 7.28.4
1738
-
'@babel/parser': 7.28.5
1739
-
'@babel/template': 7.27.2
1740
-
'@babel/traverse': 7.28.5
1741
-
'@babel/types': 7.28.5
1742
-
'@jridgewell/remapping': 2.3.5
1743
-
convert-source-map: 2.0.0
1744
-
debug: 4.4.3
1745
-
gensync: 1.0.0-beta.2
1746
-
json5: 2.2.3
1747
-
semver: 6.3.1
1748
-
transitivePeerDependencies:
1749
-
- supports-color
1750
-
1751
-
'@babel/generator@7.28.5':
1752
-
dependencies:
1753
-
'@babel/parser': 7.28.5
1754
-
'@babel/types': 7.28.5
1755
-
'@jridgewell/gen-mapping': 0.3.13
1756
-
'@jridgewell/trace-mapping': 0.3.31
1757
-
jsesc: 3.1.0
1758
-
1759
-
'@babel/helper-annotate-as-pure@7.27.3':
1760
-
dependencies:
1761
-
'@babel/types': 7.28.5
1762
-
1763
-
'@babel/helper-compilation-targets@7.27.2':
1764
-
dependencies:
1765
-
'@babel/compat-data': 7.28.5
1766
-
'@babel/helper-validator-option': 7.27.1
1767
-
browserslist: 4.28.1
1768
-
lru-cache: 5.1.1
1769
-
semver: 6.3.1
1770
-
1771
-
'@babel/helper-globals@7.28.0': {}
1772
-
1773
-
'@babel/helper-module-imports@7.27.1':
1774
-
dependencies:
1775
-
'@babel/traverse': 7.28.5
1776
-
'@babel/types': 7.28.5
1777
-
transitivePeerDependencies:
1778
-
- supports-color
1779
-
1780
-
'@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)':
1781
-
dependencies:
1782
-
'@babel/core': 7.28.5
1783
-
'@babel/helper-module-imports': 7.27.1
1784
-
'@babel/helper-validator-identifier': 7.28.5
1785
-
'@babel/traverse': 7.28.5
1786
-
transitivePeerDependencies:
1787
-
- supports-color
1788
-
1789
-
'@babel/helper-plugin-utils@7.27.1': {}
1790
-
1791
-
'@babel/helper-string-parser@7.27.1': {}
1792
-
1793
-
'@babel/helper-validator-identifier@7.28.5': {}
1794
-
1795
-
'@babel/helper-validator-option@7.27.1': {}
1796
-
1797
-
'@babel/helpers@7.28.4':
1798
-
dependencies:
1799
-
'@babel/template': 7.27.2
1800
-
'@babel/types': 7.28.5
1801
-
1802
-
'@babel/parser@7.28.5':
1803
-
dependencies:
1804
-
'@babel/types': 7.28.5
1805
-
1806
-
'@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)':
1807
-
dependencies:
1808
-
'@babel/core': 7.28.5
1809
-
'@babel/helper-plugin-utils': 7.27.1
1810
-
1811
-
'@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.5)':
1812
-
dependencies:
1813
-
'@babel/core': 7.28.5
1814
-
'@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5)
1815
-
transitivePeerDependencies:
1816
-
- supports-color
1817
-
1818
-
'@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.5)':
1819
-
dependencies:
1820
-
'@babel/core': 7.28.5
1821
-
'@babel/helper-annotate-as-pure': 7.27.3
1822
-
'@babel/helper-module-imports': 7.27.1
1823
-
'@babel/helper-plugin-utils': 7.27.1
1824
-
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5)
1825
-
'@babel/types': 7.28.5
1826
-
transitivePeerDependencies:
1827
-
- supports-color
1828
-
1829
-
'@babel/runtime@7.28.4': {}
1830
-
1831
-
'@babel/template@7.27.2':
1832
-
dependencies:
1833
-
'@babel/code-frame': 7.27.1
1834
-
'@babel/parser': 7.28.5
1835
-
'@babel/types': 7.28.5
1836
-
1837
-
'@babel/traverse@7.28.5':
1838
-
dependencies:
1839
-
'@babel/code-frame': 7.27.1
1840
-
'@babel/generator': 7.28.5
1841
-
'@babel/helper-globals': 7.28.0
1842
-
'@babel/parser': 7.28.5
1843
-
'@babel/template': 7.27.2
1844
-
'@babel/types': 7.28.5
1845
-
debug: 4.4.3
1846
-
transitivePeerDependencies:
1847
-
- supports-color
1848
-
1849
-
'@babel/types@7.28.5':
1850
-
dependencies:
1851
-
'@babel/helper-string-parser': 7.27.1
1852
-
'@babel/helper-validator-identifier': 7.28.5
1853
-
1854
-
'@changesets/apply-release-plan@7.0.14':
1855
-
dependencies:
1856
-
'@changesets/config': 3.1.2
1857
-
'@changesets/get-version-range-type': 0.4.0
1858
-
'@changesets/git': 3.0.4
1859
-
'@changesets/should-skip-package': 0.1.2
1860
-
'@changesets/types': 6.1.0
1861
-
'@manypkg/get-packages': 1.1.3
1862
-
detect-indent: 6.1.0
1863
-
fs-extra: 7.0.1
1864
-
lodash.startcase: 4.4.0
1865
-
outdent: 0.5.0
1866
-
prettier: 2.8.8
1867
-
resolve-from: 5.0.0
1868
-
semver: 7.7.3
1869
-
1870
-
'@changesets/assemble-release-plan@6.0.9':
1871
-
dependencies:
1872
-
'@changesets/errors': 0.2.0
1873
-
'@changesets/get-dependents-graph': 2.1.3
1874
-
'@changesets/should-skip-package': 0.1.2
1875
-
'@changesets/types': 6.1.0
1876
-
'@manypkg/get-packages': 1.1.3
1877
-
semver: 7.7.3
1878
-
1879
-
'@changesets/changelog-git@0.2.1':
1880
-
dependencies:
1881
-
'@changesets/types': 6.1.0
1882
-
1883
-
'@changesets/cli@2.29.8(@types/node@24.10.1)':
1884
-
dependencies:
1885
-
'@changesets/apply-release-plan': 7.0.14
1886
-
'@changesets/assemble-release-plan': 6.0.9
1887
-
'@changesets/changelog-git': 0.2.1
1888
-
'@changesets/config': 3.1.2
1889
-
'@changesets/errors': 0.2.0
1890
-
'@changesets/get-dependents-graph': 2.1.3
1891
-
'@changesets/get-release-plan': 4.0.14
1892
-
'@changesets/git': 3.0.4
1893
-
'@changesets/logger': 0.1.1
1894
-
'@changesets/pre': 2.0.2
1895
-
'@changesets/read': 0.6.6
1896
-
'@changesets/should-skip-package': 0.1.2
1897
-
'@changesets/types': 6.1.0
1898
-
'@changesets/write': 0.4.0
1899
-
'@inquirer/external-editor': 1.0.3(@types/node@24.10.1)
1900
-
'@manypkg/get-packages': 1.1.3
1901
-
ansi-colors: 4.1.3
1902
-
ci-info: 3.9.0
1903
-
enquirer: 2.4.1
1904
-
fs-extra: 7.0.1
1905
-
mri: 1.2.0
1906
-
p-limit: 2.3.0
1907
-
package-manager-detector: 0.2.11
1908
-
picocolors: 1.1.1
1909
-
resolve-from: 5.0.0
1910
-
semver: 7.7.3
1911
-
spawndamnit: 3.0.1
1912
-
term-size: 2.2.1
1913
-
transitivePeerDependencies:
1914
-
- '@types/node'
1915
-
1916
-
'@changesets/config@3.1.2':
1917
-
dependencies:
1918
-
'@changesets/errors': 0.2.0
1919
-
'@changesets/get-dependents-graph': 2.1.3
1920
-
'@changesets/logger': 0.1.1
1921
-
'@changesets/types': 6.1.0
1922
-
'@manypkg/get-packages': 1.1.3
1923
-
fs-extra: 7.0.1
1924
-
micromatch: 4.0.8
1925
-
1926
-
'@changesets/errors@0.2.0':
1927
-
dependencies:
1928
-
extendable-error: 0.1.7
1929
-
1930
-
'@changesets/get-dependents-graph@2.1.3':
1931
-
dependencies:
1932
-
'@changesets/types': 6.1.0
1933
-
'@manypkg/get-packages': 1.1.3
1934
-
picocolors: 1.1.1
1935
-
semver: 7.7.3
1936
-
1937
-
'@changesets/get-release-plan@4.0.14':
1938
-
dependencies:
1939
-
'@changesets/assemble-release-plan': 6.0.9
1940
-
'@changesets/config': 3.1.2
1941
-
'@changesets/pre': 2.0.2
1942
-
'@changesets/read': 0.6.6
1943
-
'@changesets/types': 6.1.0
1944
-
'@manypkg/get-packages': 1.1.3
1945
-
1946
-
'@changesets/get-version-range-type@0.4.0': {}
1947
-
1948
-
'@changesets/git@3.0.4':
1949
-
dependencies:
1950
-
'@changesets/errors': 0.2.0
1951
-
'@manypkg/get-packages': 1.1.3
1952
-
is-subdir: 1.2.0
1953
-
micromatch: 4.0.8
1954
-
spawndamnit: 3.0.1
1955
-
1956
-
'@changesets/logger@0.1.1':
1957
-
dependencies:
1958
-
picocolors: 1.1.1
1959
-
1960
-
'@changesets/parse@0.4.2':
1961
-
dependencies:
1962
-
'@changesets/types': 6.1.0
1963
-
js-yaml: 4.1.1
1964
-
1965
-
'@changesets/pre@2.0.2':
1966
-
dependencies:
1967
-
'@changesets/errors': 0.2.0
1968
-
'@changesets/types': 6.1.0
1969
-
'@manypkg/get-packages': 1.1.3
1970
-
fs-extra: 7.0.1
1971
-
1972
-
'@changesets/read@0.6.6':
1973
-
dependencies:
1974
-
'@changesets/git': 3.0.4
1975
-
'@changesets/logger': 0.1.1
1976
-
'@changesets/parse': 0.4.2
1977
-
'@changesets/types': 6.1.0
1978
-
fs-extra: 7.0.1
1979
-
p-filter: 2.1.0
1980
-
picocolors: 1.1.1
1981
-
1982
-
'@changesets/should-skip-package@0.1.2':
1983
-
dependencies:
1984
-
'@changesets/types': 6.1.0
1985
-
'@manypkg/get-packages': 1.1.3
1986
-
1987
-
'@changesets/types@4.1.0': {}
1988
-
1989
-
'@changesets/types@6.1.0': {}
1990
-
1991
-
'@changesets/write@0.4.0':
1992
-
dependencies:
1993
-
'@changesets/types': 6.1.0
1994
-
fs-extra: 7.0.1
1995
-
human-id: 4.1.3
1996
-
prettier: 2.8.8
1997
-
1998
-
'@esbuild/aix-ppc64@0.25.12':
1999
-
optional: true
2000
-
2001
-
'@esbuild/android-arm64@0.25.12':
2002
-
optional: true
2003
-
2004
-
'@esbuild/android-arm@0.25.12':
2005
-
optional: true
2006
-
2007
-
'@esbuild/android-x64@0.25.12':
2008
-
optional: true
2009
-
2010
-
'@esbuild/darwin-arm64@0.25.12':
2011
-
optional: true
2012
-
2013
-
'@esbuild/darwin-x64@0.25.12':
2014
-
optional: true
2015
-
2016
-
'@esbuild/freebsd-arm64@0.25.12':
2017
-
optional: true
2018
-
2019
-
'@esbuild/freebsd-x64@0.25.12':
2020
-
optional: true
2021
-
2022
-
'@esbuild/linux-arm64@0.25.12':
2023
-
optional: true
2024
-
2025
-
'@esbuild/linux-arm@0.25.12':
2026
-
optional: true
2027
-
2028
-
'@esbuild/linux-ia32@0.25.12':
2029
-
optional: true
2030
-
2031
-
'@esbuild/linux-loong64@0.25.12':
2032
-
optional: true
2033
-
2034
-
'@esbuild/linux-mips64el@0.25.12':
2035
-
optional: true
2036
-
2037
-
'@esbuild/linux-ppc64@0.25.12':
2038
-
optional: true
2039
-
2040
-
'@esbuild/linux-riscv64@0.25.12':
2041
-
optional: true
2042
-
2043
-
'@esbuild/linux-s390x@0.25.12':
2044
-
optional: true
2045
-
2046
-
'@esbuild/linux-x64@0.25.12':
2047
-
optional: true
2048
-
2049
-
'@esbuild/netbsd-arm64@0.25.12':
2050
-
optional: true
2051
-
2052
-
'@esbuild/netbsd-x64@0.25.12':
2053
-
optional: true
2054
-
2055
-
'@esbuild/openbsd-arm64@0.25.12':
2056
-
optional: true
2057
-
2058
-
'@esbuild/openbsd-x64@0.25.12':
2059
-
optional: true
2060
-
2061
-
'@esbuild/openharmony-arm64@0.25.12':
2062
-
optional: true
2063
-
2064
-
'@esbuild/sunos-x64@0.25.12':
2065
-
optional: true
2066
-
2067
-
'@esbuild/win32-arm64@0.25.12':
2068
-
optional: true
2069
-
2070
-
'@esbuild/win32-ia32@0.25.12':
2071
-
optional: true
2072
-
2073
-
'@esbuild/win32-x64@0.25.12':
2074
-
optional: true
2075
-
2076
-
'@inquirer/external-editor@1.0.3(@types/node@24.10.1)':
2077
-
dependencies:
2078
-
chardet: 2.1.1
2079
-
iconv-lite: 0.7.0
2080
-
optionalDependencies:
2081
-
'@types/node': 24.10.1
2082
-
2083
-
'@isaacs/balanced-match@4.0.1': {}
2084
-
2085
-
'@isaacs/brace-expansion@5.0.0':
2086
-
dependencies:
2087
-
'@isaacs/balanced-match': 4.0.1
2088
-
2089
-
'@jridgewell/gen-mapping@0.3.13':
2090
-
dependencies:
2091
-
'@jridgewell/sourcemap-codec': 1.5.5
2092
-
'@jridgewell/trace-mapping': 0.3.31
2093
-
2094
-
'@jridgewell/remapping@2.3.5':
2095
-
dependencies:
2096
-
'@jridgewell/gen-mapping': 0.3.13
2097
-
'@jridgewell/trace-mapping': 0.3.31
2098
-
2099
-
'@jridgewell/resolve-uri@3.1.2': {}
2100
-
2101
-
'@jridgewell/source-map@0.3.11':
2102
-
dependencies:
2103
-
'@jridgewell/gen-mapping': 0.3.13
2104
-
'@jridgewell/trace-mapping': 0.3.31
2105
-
2106
-
'@jridgewell/sourcemap-codec@1.5.5': {}
2107
-
2108
-
'@jridgewell/trace-mapping@0.3.31':
2109
-
dependencies:
2110
-
'@jridgewell/resolve-uri': 3.1.2
2111
-
'@jridgewell/sourcemap-codec': 1.5.5
2112
-
2113
-
'@manypkg/find-root@1.1.0':
2114
-
dependencies:
2115
-
'@babel/runtime': 7.28.4
2116
-
'@types/node': 12.20.55
2117
-
find-up: 4.1.0
2118
-
fs-extra: 8.1.0
2119
-
2120
-
'@manypkg/get-packages@1.1.3':
2121
-
dependencies:
2122
-
'@babel/runtime': 7.28.4
2123
-
'@changesets/types': 4.1.0
2124
-
'@manypkg/find-root': 1.1.0
2125
-
fs-extra: 8.1.0
2126
-
globby: 11.1.0
2127
-
read-yaml-file: 1.1.0
2128
-
2129
-
'@microsoft/api-extractor-model@7.32.1(@types/node@24.10.1)':
2130
-
dependencies:
2131
-
'@microsoft/tsdoc': 0.16.0
2132
-
'@microsoft/tsdoc-config': 0.18.0
2133
-
'@rushstack/node-core-library': 5.19.0(@types/node@24.10.1)
2134
-
transitivePeerDependencies:
2135
-
- '@types/node'
2136
-
2137
-
'@microsoft/api-extractor@7.55.1(@types/node@24.10.1)':
2138
-
dependencies:
2139
-
'@microsoft/api-extractor-model': 7.32.1(@types/node@24.10.1)
2140
-
'@microsoft/tsdoc': 0.16.0
2141
-
'@microsoft/tsdoc-config': 0.18.0
2142
-
'@rushstack/node-core-library': 5.19.0(@types/node@24.10.1)
2143
-
'@rushstack/rig-package': 0.6.0
2144
-
'@rushstack/terminal': 0.19.4(@types/node@24.10.1)
2145
-
'@rushstack/ts-command-line': 5.1.4(@types/node@24.10.1)
2146
-
diff: 8.0.2
2147
-
lodash: 4.17.21
2148
-
minimatch: 10.0.3
2149
-
resolve: 1.22.11
2150
-
semver: 7.5.4
2151
-
source-map: 0.6.1
2152
-
typescript: 5.8.2
2153
-
transitivePeerDependencies:
2154
-
- '@types/node'
2155
-
2156
-
'@microsoft/tsdoc-config@0.18.0':
2157
-
dependencies:
2158
-
'@microsoft/tsdoc': 0.16.0
2159
-
ajv: 8.12.0
2160
-
jju: 1.4.0
2161
-
resolve: 1.22.11
2162
-
2163
-
'@microsoft/tsdoc@0.16.0': {}
2164
-
2165
-
'@nodelib/fs.scandir@2.1.5':
2166
-
dependencies:
2167
-
'@nodelib/fs.stat': 2.0.5
2168
-
run-parallel: 1.2.0
2169
-
2170
-
'@nodelib/fs.stat@2.0.5': {}
2171
-
2172
-
'@nodelib/fs.walk@1.2.8':
2173
-
dependencies:
2174
-
'@nodelib/fs.scandir': 2.1.5
2175
-
fastq: 1.19.1
2176
-
2177
-
'@preact/preset-vite@2.10.2(@babel/core@7.28.5)(preact@10.28.0)(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))':
2178
-
dependencies:
2179
-
'@babel/core': 7.28.5
2180
-
'@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5)
2181
-
'@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.5)
2182
-
'@prefresh/vite': 2.4.11(preact@10.28.0)(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))
2183
-
'@rollup/pluginutils': 4.2.1
2184
-
babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.5)
2185
-
debug: 4.4.3
2186
-
picocolors: 1.1.1
2187
-
vite: 7.2.6(@types/node@24.10.1)(terser@5.44.1)
2188
-
vite-prerender-plugin: 0.5.12(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))
2189
-
transitivePeerDependencies:
2190
-
- preact
2191
-
- supports-color
2192
-
2193
-
'@prefresh/babel-plugin@0.5.2': {}
2194
-
2195
-
'@prefresh/core@1.5.9(preact@10.28.0)':
2196
-
dependencies:
2197
-
preact: 10.28.0
2198
-
2199
-
'@prefresh/utils@1.2.1': {}
2200
-
2201
-
'@prefresh/vite@2.4.11(preact@10.28.0)(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))':
2202
-
dependencies:
2203
-
'@babel/core': 7.28.5
2204
-
'@prefresh/babel-plugin': 0.5.2
2205
-
'@prefresh/core': 1.5.9(preact@10.28.0)
2206
-
'@prefresh/utils': 1.2.1
2207
-
'@rollup/pluginutils': 4.2.1
2208
-
preact: 10.28.0
2209
-
vite: 7.2.6(@types/node@24.10.1)(terser@5.44.1)
2210
-
transitivePeerDependencies:
2211
-
- supports-color
2212
-
2213
-
'@rollup/pluginutils@4.2.1':
2214
-
dependencies:
2215
-
estree-walker: 2.0.2
2216
-
picomatch: 2.3.1
2217
-
2218
-
'@rollup/pluginutils@5.3.0(rollup@4.53.3)':
2219
-
dependencies:
2220
-
'@types/estree': 1.0.8
2221
-
estree-walker: 2.0.2
2222
-
picomatch: 4.0.3
2223
-
optionalDependencies:
2224
-
rollup: 4.53.3
2225
-
2226
-
'@rollup/rollup-android-arm-eabi@4.53.3':
2227
-
optional: true
2228
-
2229
-
'@rollup/rollup-android-arm64@4.53.3':
2230
-
optional: true
2231
-
2232
-
'@rollup/rollup-darwin-arm64@4.53.3':
2233
-
optional: true
2234
-
2235
-
'@rollup/rollup-darwin-x64@4.53.3':
2236
-
optional: true
2237
-
2238
-
'@rollup/rollup-freebsd-arm64@4.53.3':
2239
-
optional: true
2240
-
2241
-
'@rollup/rollup-freebsd-x64@4.53.3':
2242
-
optional: true
2243
-
2244
-
'@rollup/rollup-linux-arm-gnueabihf@4.53.3':
2245
-
optional: true
2246
-
2247
-
'@rollup/rollup-linux-arm-musleabihf@4.53.3':
2248
-
optional: true
2249
-
2250
-
'@rollup/rollup-linux-arm64-gnu@4.53.3':
2251
-
optional: true
2252
-
2253
-
'@rollup/rollup-linux-arm64-musl@4.53.3':
2254
-
optional: true
2255
-
2256
-
'@rollup/rollup-linux-loong64-gnu@4.53.3':
2257
-
optional: true
2258
-
2259
-
'@rollup/rollup-linux-ppc64-gnu@4.53.3':
2260
-
optional: true
2261
-
2262
-
'@rollup/rollup-linux-riscv64-gnu@4.53.3':
2263
-
optional: true
2264
-
2265
-
'@rollup/rollup-linux-riscv64-musl@4.53.3':
2266
-
optional: true
2267
-
2268
-
'@rollup/rollup-linux-s390x-gnu@4.53.3':
2269
-
optional: true
2270
-
2271
-
'@rollup/rollup-linux-x64-gnu@4.53.3':
2272
-
optional: true
2273
-
2274
-
'@rollup/rollup-linux-x64-musl@4.53.3':
2275
-
optional: true
2276
-
2277
-
'@rollup/rollup-openharmony-arm64@4.53.3':
2278
-
optional: true
2279
-
2280
-
'@rollup/rollup-win32-arm64-msvc@4.53.3':
2281
-
optional: true
2282
-
2283
-
'@rollup/rollup-win32-ia32-msvc@4.53.3':
2284
-
optional: true
2285
-
2286
-
'@rollup/rollup-win32-x64-gnu@4.53.3':
2287
-
optional: true
2288
-
2289
-
'@rollup/rollup-win32-x64-msvc@4.53.3':
2290
-
optional: true
2291
-
2292
-
'@rushstack/node-core-library@5.19.0(@types/node@24.10.1)':
2293
-
dependencies:
2294
-
ajv: 8.13.0
2295
-
ajv-draft-04: 1.0.0(ajv@8.13.0)
2296
-
ajv-formats: 3.0.1(ajv@8.13.0)
2297
-
fs-extra: 11.3.2
2298
-
import-lazy: 4.0.0
2299
-
jju: 1.4.0
2300
-
resolve: 1.22.11
2301
-
semver: 7.5.4
2302
-
optionalDependencies:
2303
-
'@types/node': 24.10.1
2304
-
2305
-
'@rushstack/problem-matcher@0.1.1(@types/node@24.10.1)':
2306
-
optionalDependencies:
2307
-
'@types/node': 24.10.1
2308
-
2309
-
'@rushstack/rig-package@0.6.0':
2310
-
dependencies:
2311
-
resolve: 1.22.11
2312
-
strip-json-comments: 3.1.1
2313
-
2314
-
'@rushstack/terminal@0.19.4(@types/node@24.10.1)':
2315
-
dependencies:
2316
-
'@rushstack/node-core-library': 5.19.0(@types/node@24.10.1)
2317
-
'@rushstack/problem-matcher': 0.1.1(@types/node@24.10.1)
2318
-
supports-color: 8.1.1
2319
-
optionalDependencies:
2320
-
'@types/node': 24.10.1
2321
-
2322
-
'@rushstack/ts-command-line@5.1.4(@types/node@24.10.1)':
2323
-
dependencies:
2324
-
'@rushstack/terminal': 0.19.4(@types/node@24.10.1)
2325
-
'@types/argparse': 1.0.38
2326
-
argparse: 1.0.10
2327
-
string-argv: 0.3.2
2328
-
transitivePeerDependencies:
2329
-
- '@types/node'
2330
-
2331
-
'@standard-schema/spec@1.0.0': {}
2332
-
2333
-
'@sveltejs/acorn-typescript@1.0.8(acorn@8.15.0)':
2334
-
dependencies:
2335
-
acorn: 8.15.0
2336
-
2337
-
'@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1)))(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))':
2338
-
dependencies:
2339
-
'@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))
2340
-
debug: 4.4.3
2341
-
svelte: 5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd)
2342
-
vite: 7.2.6(@types/node@24.10.1)(terser@5.44.1)
2343
-
transitivePeerDependencies:
2344
-
- supports-color
2345
-
2346
-
'@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))':
2347
-
dependencies:
2348
-
'@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1)))(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))
2349
-
debug: 4.4.3
2350
-
deepmerge: 4.3.1
2351
-
magic-string: 0.30.21
2352
-
svelte: 5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd)
2353
-
vite: 7.2.6(@types/node@24.10.1)(terser@5.44.1)
2354
-
vitefu: 1.1.1(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1))
2355
-
transitivePeerDependencies:
2356
-
- supports-color
2357
-
2358
-
'@tsconfig/svelte@5.0.6': {}
2359
-
2360
-
'@types/argparse@1.0.38': {}
2361
-
2362
-
'@types/estree@1.0.8': {}
2363
-
2364
-
'@types/node@12.20.55': {}
2365
-
2366
-
'@types/node@24.10.1':
2367
-
dependencies:
2368
-
undici-types: 7.16.0
2369
-
2370
-
'@volar/language-core@2.4.26':
2371
-
dependencies:
2372
-
'@volar/source-map': 2.4.26
2373
-
2374
-
'@volar/source-map@2.4.26': {}
2375
-
2376
-
'@volar/typescript@2.4.26':
2377
-
dependencies:
2378
-
'@volar/language-core': 2.4.26
2379
-
path-browserify: 1.0.1
2380
-
vscode-uri: 3.1.0
2381
-
2382
-
'@vue/compiler-core@3.5.25':
2383
-
dependencies:
2384
-
'@babel/parser': 7.28.5
2385
-
'@vue/shared': 3.5.25
2386
-
entities: 4.5.0
2387
-
estree-walker: 2.0.2
2388
-
source-map-js: 1.2.1
2389
-
2390
-
'@vue/compiler-dom@3.5.25':
2391
-
dependencies:
2392
-
'@vue/compiler-core': 3.5.25
2393
-
'@vue/shared': 3.5.25
2394
-
2395
-
'@vue/compiler-vue2@2.7.16':
2396
-
dependencies:
2397
-
de-indent: 1.0.2
2398
-
he: 1.2.0
2399
-
2400
-
'@vue/language-core@2.2.0(typescript@5.8.3)':
2401
-
dependencies:
2402
-
'@volar/language-core': 2.4.26
2403
-
'@vue/compiler-dom': 3.5.25
2404
-
'@vue/compiler-vue2': 2.7.16
2405
-
'@vue/shared': 3.5.25
2406
-
alien-signals: 0.4.14
2407
-
minimatch: 9.0.5
2408
-
muggle-string: 0.4.1
2409
-
path-browserify: 1.0.1
2410
-
optionalDependencies:
2411
-
typescript: 5.8.3
2412
-
2413
-
'@vue/shared@3.5.25': {}
2414
-
2415
-
acorn@8.15.0: {}
2416
-
2417
-
ajv-draft-04@1.0.0(ajv@8.13.0):
2418
-
optionalDependencies:
2419
-
ajv: 8.13.0
2420
-
2421
-
ajv-formats@3.0.1(ajv@8.13.0):
2422
-
optionalDependencies:
2423
-
ajv: 8.13.0
2424
-
2425
-
ajv@8.12.0:
2426
-
dependencies:
2427
-
fast-deep-equal: 3.1.3
2428
-
json-schema-traverse: 1.0.0
2429
-
require-from-string: 2.0.2
2430
-
uri-js: 4.4.1
2431
-
2432
-
ajv@8.13.0:
2433
-
dependencies:
2434
-
fast-deep-equal: 3.1.3
2435
-
json-schema-traverse: 1.0.0
2436
-
require-from-string: 2.0.2
2437
-
uri-js: 4.4.1
2438
-
2439
-
alien-signals@0.4.14: {}
2440
-
2441
-
ansi-colors@4.1.3: {}
2442
-
2443
-
ansi-regex@5.0.1: {}
2444
-
2445
-
argparse@1.0.10:
2446
-
dependencies:
2447
-
sprintf-js: 1.0.3
2448
-
2449
-
argparse@2.0.1: {}
2450
-
2451
-
aria-query@5.3.2: {}
2452
-
2453
-
array-union@2.1.0: {}
2454
-
2455
-
axobject-query@4.1.0: {}
2456
-
2457
-
babel-plugin-transform-hook-names@1.0.2(@babel/core@7.28.5):
2458
-
dependencies:
2459
-
'@babel/core': 7.28.5
2460
-
2461
-
balanced-match@1.0.2: {}
2462
-
2463
-
baseline-browser-mapping@2.9.0: {}
2464
-
2465
-
better-path-resolve@1.0.0:
2466
-
dependencies:
2467
-
is-windows: 1.0.2
2468
-
2469
-
boolbase@1.0.0: {}
2470
-
2471
-
brace-expansion@2.0.2:
2472
-
dependencies:
2473
-
balanced-match: 1.0.2
2474
-
2475
-
braces@3.0.3:
2476
-
dependencies:
2477
-
fill-range: 7.1.1
2478
-
2479
-
browserslist@4.28.1:
2480
-
dependencies:
2481
-
baseline-browser-mapping: 2.9.0
2482
-
caniuse-lite: 1.0.30001759
2483
-
electron-to-chromium: 1.5.264
2484
-
node-releases: 2.0.27
2485
-
update-browserslist-db: 1.2.1(browserslist@4.28.1)
2486
-
2487
-
buffer-from@1.1.2: {}
2488
-
2489
-
caniuse-lite@1.0.30001759: {}
2490
-
2491
-
chardet@2.1.1: {}
2492
-
2493
-
chokidar@4.0.3:
2494
-
dependencies:
2495
-
readdirp: 4.1.2
2496
-
2497
-
ci-info@3.9.0: {}
2498
-
2499
-
clsx@2.1.1: {}
2500
-
2501
-
commander@2.20.3: {}
2502
-
2503
-
compare-versions@6.1.1: {}
2504
-
2505
-
confbox@0.1.8: {}
2506
-
2507
-
confbox@0.2.2: {}
2508
-
2509
-
convert-source-map@2.0.0: {}
2510
-
2511
-
cross-spawn@7.0.6:
2512
-
dependencies:
2513
-
path-key: 3.1.1
2514
-
shebang-command: 2.0.0
2515
-
which: 2.0.2
2516
-
2517
-
css-declaration-sorter@7.3.0(postcss@8.5.6):
2518
-
dependencies:
2519
-
postcss: 8.5.6
2520
-
2521
-
css-select@5.2.2:
2522
-
dependencies:
2523
-
boolbase: 1.0.0
2524
-
css-what: 6.2.2
2525
-
domhandler: 5.0.3
2526
-
domutils: 3.2.2
2527
-
nth-check: 2.1.1
2528
-
2529
-
css-what@6.2.2: {}
2530
-
2531
-
de-indent@1.0.2: {}
2532
-
2533
-
debug@4.4.3:
2534
-
dependencies:
2535
-
ms: 2.1.3
2536
-
2537
-
deepmerge@4.3.1: {}
2538
-
2539
-
detect-indent@6.1.0: {}
2540
-
2541
-
devalue@5.5.0: {}
2542
-
2543
-
diff@8.0.2: {}
2544
-
2545
-
dir-glob@3.0.1:
2546
-
dependencies:
2547
-
path-type: 4.0.0
2548
-
2549
-
dom-serializer@2.0.0:
2550
-
dependencies:
2551
-
domelementtype: 2.3.0
2552
-
domhandler: 5.0.3
2553
-
entities: 4.5.0
2554
-
2555
-
domelementtype@2.3.0: {}
2556
-
2557
-
domhandler@5.0.3:
2558
-
dependencies:
2559
-
domelementtype: 2.3.0
2560
-
2561
-
domutils@3.2.2:
2562
-
dependencies:
2563
-
dom-serializer: 2.0.0
2564
-
domelementtype: 2.3.0
2565
-
domhandler: 5.0.3
2566
-
2567
-
electron-to-chromium@1.5.264: {}
2568
-
2569
-
enquirer@2.4.1:
2570
-
dependencies:
2571
-
ansi-colors: 4.1.3
2572
-
strip-ansi: 6.0.1
2573
-
2574
-
entities@4.5.0: {}
2575
-
2576
-
esbuild@0.25.12:
2577
-
optionalDependencies:
2578
-
'@esbuild/aix-ppc64': 0.25.12
2579
-
'@esbuild/android-arm': 0.25.12
2580
-
'@esbuild/android-arm64': 0.25.12
2581
-
'@esbuild/android-x64': 0.25.12
2582
-
'@esbuild/darwin-arm64': 0.25.12
2583
-
'@esbuild/darwin-x64': 0.25.12
2584
-
'@esbuild/freebsd-arm64': 0.25.12
2585
-
'@esbuild/freebsd-x64': 0.25.12
2586
-
'@esbuild/linux-arm': 0.25.12
2587
-
'@esbuild/linux-arm64': 0.25.12
2588
-
'@esbuild/linux-ia32': 0.25.12
2589
-
'@esbuild/linux-loong64': 0.25.12
2590
-
'@esbuild/linux-mips64el': 0.25.12
2591
-
'@esbuild/linux-ppc64': 0.25.12
2592
-
'@esbuild/linux-riscv64': 0.25.12
2593
-
'@esbuild/linux-s390x': 0.25.12
2594
-
'@esbuild/linux-x64': 0.25.12
2595
-
'@esbuild/netbsd-arm64': 0.25.12
2596
-
'@esbuild/netbsd-x64': 0.25.12
2597
-
'@esbuild/openbsd-arm64': 0.25.12
2598
-
'@esbuild/openbsd-x64': 0.25.12
2599
-
'@esbuild/openharmony-arm64': 0.25.12
2600
-
'@esbuild/sunos-x64': 0.25.12
2601
-
'@esbuild/win32-arm64': 0.25.12
2602
-
'@esbuild/win32-ia32': 0.25.12
2603
-
'@esbuild/win32-x64': 0.25.12
2604
-
2605
-
escalade@3.2.0: {}
2606
-
2607
-
esm-env@1.2.2: {}
2608
-
2609
-
esprima@4.0.1: {}
2610
-
2611
-
esrap@2.2.1:
2612
-
dependencies:
2613
-
'@jridgewell/sourcemap-codec': 1.5.5
2614
-
2615
-
estree-walker@2.0.2: {}
2616
-
2617
-
exsolve@1.0.8: {}
2618
-
2619
-
extendable-error@0.1.7: {}
2620
-
2621
-
fast-deep-equal@3.1.3: {}
2622
-
2623
-
fast-glob@3.3.3:
2624
-
dependencies:
2625
-
'@nodelib/fs.stat': 2.0.5
2626
-
'@nodelib/fs.walk': 1.2.8
2627
-
glob-parent: 5.1.2
2628
-
merge2: 1.4.1
2629
-
micromatch: 4.0.8
2630
-
2631
-
fastq@1.19.1:
2632
-
dependencies:
2633
-
reusify: 1.1.0
2634
-
2635
-
fdir@6.5.0(picomatch@4.0.3):
2636
-
optionalDependencies:
2637
-
picomatch: 4.0.3
2638
-
2639
-
fill-range@7.1.1:
2640
-
dependencies:
2641
-
to-regex-range: 5.0.1
2642
-
2643
-
find-up@4.1.0:
2644
-
dependencies:
2645
-
locate-path: 5.0.0
2646
-
path-exists: 4.0.0
2647
-
2648
-
fs-extra@11.3.2:
2649
-
dependencies:
2650
-
graceful-fs: 4.2.11
2651
-
jsonfile: 6.2.0
2652
-
universalify: 2.0.1
2653
-
2654
-
fs-extra@7.0.1:
2655
-
dependencies:
2656
-
graceful-fs: 4.2.11
2657
-
jsonfile: 4.0.0
2658
-
universalify: 0.1.2
2659
-
2660
-
fs-extra@8.1.0:
2661
-
dependencies:
2662
-
graceful-fs: 4.2.11
2663
-
jsonfile: 4.0.0
2664
-
universalify: 0.1.2
2665
-
2666
-
fsevents@2.3.3:
2667
-
optional: true
2668
-
2669
-
function-bind@1.1.2: {}
2670
-
2671
-
gensync@1.0.0-beta.2: {}
2672
-
2673
-
glob-parent@5.1.2:
2674
-
dependencies:
2675
-
is-glob: 4.0.3
2676
-
2677
-
globby@11.1.0:
2678
-
dependencies:
2679
-
array-union: 2.1.0
2680
-
dir-glob: 3.0.1
2681
-
fast-glob: 3.3.3
2682
-
ignore: 5.3.2
2683
-
merge2: 1.4.1
2684
-
slash: 3.0.0
2685
-
2686
-
graceful-fs@4.2.11: {}
2687
-
2688
-
has-flag@4.0.0: {}
2689
-
2690
-
hasown@2.0.2:
2691
-
dependencies:
2692
-
function-bind: 1.1.2
2693
-
2694
-
he@1.2.0: {}
2695
-
2696
-
human-id@4.1.3: {}
2697
-
2698
-
iconv-lite@0.7.0:
2699
-
dependencies:
2700
-
safer-buffer: 2.1.2
2701
-
2702
-
ignore@5.3.2: {}
2703
-
2704
-
import-lazy@4.0.0: {}
2705
-
2706
-
is-core-module@2.16.1:
2707
-
dependencies:
2708
-
hasown: 2.0.2
2709
-
2710
-
is-extglob@2.1.1: {}
2711
-
2712
-
is-glob@4.0.3:
2713
-
dependencies:
2714
-
is-extglob: 2.1.1
2715
-
2716
-
is-number@7.0.0: {}
2717
-
2718
-
is-reference@3.0.3:
2719
-
dependencies:
2720
-
'@types/estree': 1.0.8
2721
-
2722
-
is-subdir@1.2.0:
2723
-
dependencies:
2724
-
better-path-resolve: 1.0.0
2725
-
2726
-
is-windows@1.0.2: {}
2727
-
2728
-
isexe@2.0.0: {}
2729
-
2730
-
jju@1.4.0: {}
2731
-
2732
-
js-tokens@4.0.0: {}
2733
-
2734
-
js-yaml@3.14.2:
2735
-
dependencies:
2736
-
argparse: 1.0.10
2737
-
esprima: 4.0.1
2738
-
2739
-
js-yaml@4.1.1:
2740
-
dependencies:
2741
-
argparse: 2.0.1
2742
-
2743
-
jsesc@3.1.0: {}
2744
-
2745
-
json-schema-traverse@1.0.0: {}
2746
-
2747
-
json5@2.2.3: {}
2748
-
2749
-
jsonfile@4.0.0:
2750
-
optionalDependencies:
2751
-
graceful-fs: 4.2.11
2752
-
2753
-
jsonfile@6.2.0:
2754
-
dependencies:
2755
-
universalify: 2.0.1
2756
-
optionalDependencies:
2757
-
graceful-fs: 4.2.11
2758
-
2759
-
kolorist@1.8.0: {}
2760
-
2761
-
local-pkg@1.1.2:
2762
-
dependencies:
2763
-
mlly: 1.8.0
2764
-
pkg-types: 2.3.0
2765
-
quansync: 0.2.11
2766
-
2767
-
locate-character@3.0.0: {}
2768
-
2769
-
locate-path@5.0.0:
2770
-
dependencies:
2771
-
p-locate: 4.1.0
2772
-
2773
-
lodash.startcase@4.4.0: {}
2774
-
2775
-
lodash@4.17.21: {}
2776
-
2777
-
lru-cache@5.1.1:
2778
-
dependencies:
2779
-
yallist: 3.1.1
2780
-
2781
-
lru-cache@6.0.0:
2782
-
dependencies:
2783
-
yallist: 4.0.0
2784
-
2785
-
magic-string@0.30.21:
2786
-
dependencies:
2787
-
'@jridgewell/sourcemap-codec': 1.5.5
2788
-
2789
-
merge2@1.4.1: {}
2790
-
2791
-
micromatch@4.0.8:
2792
-
dependencies:
2793
-
braces: 3.0.3
2794
-
picomatch: 2.3.1
2795
-
2796
-
minimatch@10.0.3:
2797
-
dependencies:
2798
-
'@isaacs/brace-expansion': 5.0.0
2799
-
2800
-
minimatch@9.0.5:
2801
-
dependencies:
2802
-
brace-expansion: 2.0.2
2803
-
2804
-
mlly@1.8.0:
2805
-
dependencies:
2806
-
acorn: 8.15.0
2807
-
pathe: 2.0.3
2808
-
pkg-types: 1.3.1
2809
-
ufo: 1.6.1
2810
-
2811
-
mri@1.2.0: {}
2812
-
2813
-
ms@2.1.3: {}
2814
-
2815
-
muggle-string@0.4.1: {}
2816
-
2817
-
nanoid@3.3.11: {}
2818
-
2819
-
node-html-parser@6.1.13:
2820
-
dependencies:
2821
-
css-select: 5.2.2
2822
-
he: 1.2.0
2823
-
2824
-
node-releases@2.0.27: {}
2825
-
2826
-
nth-check@2.1.1:
2827
-
dependencies:
2828
-
boolbase: 1.0.0
2829
-
2830
-
outdent@0.5.0: {}
2831
-
2832
-
p-filter@2.1.0:
2833
-
dependencies:
2834
-
p-map: 2.1.0
2835
-
2836
-
p-limit@2.3.0:
2837
-
dependencies:
2838
-
p-try: 2.2.0
2839
-
2840
-
p-locate@4.1.0:
2841
-
dependencies:
2842
-
p-limit: 2.3.0
2843
-
2844
-
p-map@2.1.0: {}
2845
-
2846
-
p-try@2.2.0: {}
2847
-
2848
-
package-manager-detector@0.2.11:
2849
-
dependencies:
2850
-
quansync: 0.2.11
2851
-
2852
-
path-browserify@1.0.1: {}
2853
-
2854
-
path-exists@4.0.0: {}
2855
-
2856
-
path-key@3.1.1: {}
2857
-
2858
-
path-parse@1.0.7: {}
2859
-
2860
-
path-type@4.0.0: {}
2861
-
2862
-
pathe@2.0.3: {}
2863
-
2864
-
picocolors@1.1.1: {}
2865
-
2866
-
picomatch@2.3.1: {}
2867
-
2868
-
picomatch@4.0.3: {}
2869
-
2870
-
pify@4.0.1: {}
2871
-
2872
-
pkg-types@1.3.1:
2873
-
dependencies:
2874
-
confbox: 0.1.8
2875
-
mlly: 1.8.0
2876
-
pathe: 2.0.3
2877
-
2878
-
pkg-types@2.3.0:
2879
-
dependencies:
2880
-
confbox: 0.2.2
2881
-
exsolve: 1.0.8
2882
-
pathe: 2.0.3
2883
-
2884
-
postcss-less@6.0.0(postcss@8.5.6):
2885
-
dependencies:
2886
-
postcss: 8.5.6
2887
-
2888
-
postcss-scss@4.0.9(postcss@8.5.6):
2889
-
dependencies:
2890
-
postcss: 8.5.6
2891
-
2892
-
postcss@8.5.6:
2893
-
dependencies:
2894
-
nanoid: 3.3.11
2895
-
picocolors: 1.1.1
2896
-
source-map-js: 1.2.1
2897
-
2898
-
preact@10.28.0: {}
2899
-
2900
-
prettier-plugin-css-order@2.1.2(postcss@8.5.6)(prettier@3.7.4):
2901
-
dependencies:
2902
-
css-declaration-sorter: 7.3.0(postcss@8.5.6)
2903
-
postcss-less: 6.0.0(postcss@8.5.6)
2904
-
postcss-scss: 4.0.9(postcss@8.5.6)
2905
-
prettier: 3.7.4
2906
-
transitivePeerDependencies:
2907
-
- postcss
2908
-
2909
-
prettier-plugin-svelte@3.4.0(prettier@3.7.4)(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd)):
2910
-
dependencies:
2911
-
prettier: 3.7.4
2912
-
svelte: 5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd)
2913
-
2914
-
prettier@2.8.8: {}
2915
-
2916
-
prettier@3.7.4: {}
2917
-
2918
-
punycode@2.3.1: {}
2919
-
2920
-
quansync@0.2.11: {}
2921
-
2922
-
queue-microtask@1.2.3: {}
2923
-
2924
-
read-yaml-file@1.1.0:
2925
-
dependencies:
2926
-
graceful-fs: 4.2.11
2927
-
js-yaml: 3.14.2
2928
-
pify: 4.0.1
2929
-
strip-bom: 3.0.0
2930
-
2931
-
readdirp@4.1.2: {}
2932
-
2933
-
require-from-string@2.0.2: {}
2934
-
2935
-
resolve-from@5.0.0: {}
2936
-
2937
-
resolve@1.22.11:
2938
-
dependencies:
2939
-
is-core-module: 2.16.1
2940
-
path-parse: 1.0.7
2941
-
supports-preserve-symlinks-flag: 1.0.0
2942
-
2943
-
reusify@1.1.0: {}
2944
-
2945
-
rollup@4.53.3:
2946
-
dependencies:
2947
-
'@types/estree': 1.0.8
2948
-
optionalDependencies:
2949
-
'@rollup/rollup-android-arm-eabi': 4.53.3
2950
-
'@rollup/rollup-android-arm64': 4.53.3
2951
-
'@rollup/rollup-darwin-arm64': 4.53.3
2952
-
'@rollup/rollup-darwin-x64': 4.53.3
2953
-
'@rollup/rollup-freebsd-arm64': 4.53.3
2954
-
'@rollup/rollup-freebsd-x64': 4.53.3
2955
-
'@rollup/rollup-linux-arm-gnueabihf': 4.53.3
2956
-
'@rollup/rollup-linux-arm-musleabihf': 4.53.3
2957
-
'@rollup/rollup-linux-arm64-gnu': 4.53.3
2958
-
'@rollup/rollup-linux-arm64-musl': 4.53.3
2959
-
'@rollup/rollup-linux-loong64-gnu': 4.53.3
2960
-
'@rollup/rollup-linux-ppc64-gnu': 4.53.3
2961
-
'@rollup/rollup-linux-riscv64-gnu': 4.53.3
2962
-
'@rollup/rollup-linux-riscv64-musl': 4.53.3
2963
-
'@rollup/rollup-linux-s390x-gnu': 4.53.3
2964
-
'@rollup/rollup-linux-x64-gnu': 4.53.3
2965
-
'@rollup/rollup-linux-x64-musl': 4.53.3
2966
-
'@rollup/rollup-openharmony-arm64': 4.53.3
2967
-
'@rollup/rollup-win32-arm64-msvc': 4.53.3
2968
-
'@rollup/rollup-win32-ia32-msvc': 4.53.3
2969
-
'@rollup/rollup-win32-x64-gnu': 4.53.3
2970
-
'@rollup/rollup-win32-x64-msvc': 4.53.3
2971
-
fsevents: 2.3.3
2972
-
2973
-
run-parallel@1.2.0:
2974
-
dependencies:
2975
-
queue-microtask: 1.2.3
2976
-
2977
-
sade@1.8.1:
2978
-
dependencies:
2979
-
mri: 1.2.0
2980
-
2981
-
safer-buffer@2.1.2: {}
2982
-
2983
-
semver@6.3.1: {}
2984
-
2985
-
semver@7.5.4:
2986
-
dependencies:
2987
-
lru-cache: 6.0.0
2988
-
2989
-
semver@7.7.3: {}
2990
-
2991
-
shebang-command@2.0.0:
2992
-
dependencies:
2993
-
shebang-regex: 3.0.0
2994
-
2995
-
shebang-regex@3.0.0: {}
2996
-
2997
-
signal-exit@4.1.0: {}
2998
-
2999
-
simple-code-frame@1.3.0:
3000
-
dependencies:
3001
-
kolorist: 1.8.0
3002
-
3003
-
slash@3.0.0: {}
3004
-
3005
-
source-map-js@1.2.1: {}
3006
-
3007
-
source-map-support@0.5.21:
3008
-
dependencies:
3009
-
buffer-from: 1.1.2
3010
-
source-map: 0.6.1
3011
-
3012
-
source-map@0.6.1: {}
3013
-
3014
-
source-map@0.7.6: {}
3015
-
3016
-
spawndamnit@3.0.1:
3017
-
dependencies:
3018
-
cross-spawn: 7.0.6
3019
-
signal-exit: 4.1.0
3020
-
3021
-
sprintf-js@1.0.3: {}
3022
-
3023
-
stack-trace@1.0.0-pre2: {}
3024
-
3025
-
string-argv@0.3.2: {}
3026
-
3027
-
strip-ansi@6.0.1:
3028
-
dependencies:
3029
-
ansi-regex: 5.0.1
3030
-
3031
-
strip-bom@3.0.0: {}
3032
-
3033
-
strip-json-comments@3.1.1: {}
3034
-
3035
-
supports-color@8.1.1:
3036
-
dependencies:
3037
-
has-flag: 4.0.0
3038
-
3039
-
supports-preserve-symlinks-flag@1.0.0: {}
3040
-
3041
-
svelte-check@4.3.4(picomatch@4.0.3)(svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd))(typescript@5.8.3):
3042
-
dependencies:
3043
-
'@jridgewell/trace-mapping': 0.3.31
3044
-
chokidar: 4.0.3
3045
-
fdir: 6.5.0(picomatch@4.0.3)
3046
-
picocolors: 1.1.1
3047
-
sade: 1.8.1
3048
-
svelte: 5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd)
3049
-
typescript: 5.8.3
3050
-
transitivePeerDependencies:
3051
-
- picomatch
3052
-
3053
-
svelte@5.45.5(patch_hash=0f942ae2231640ac09d0a1e9913071000fffa9bdfe69630d767130d415a78ecd):
3054
-
dependencies:
3055
-
'@jridgewell/remapping': 2.3.5
3056
-
'@jridgewell/sourcemap-codec': 1.5.5
3057
-
'@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0)
3058
-
'@types/estree': 1.0.8
3059
-
acorn: 8.15.0
3060
-
aria-query: 5.3.2
3061
-
axobject-query: 4.1.0
3062
-
clsx: 2.1.1
3063
-
devalue: 5.5.0
3064
-
esm-env: 1.2.2
3065
-
esrap: 2.2.1
3066
-
is-reference: 3.0.3
3067
-
locate-character: 3.0.0
3068
-
magic-string: 0.30.21
3069
-
zimmerframe: 1.1.4
3070
-
3071
-
term-size@2.2.1: {}
3072
-
3073
-
terser@5.44.1:
3074
-
dependencies:
3075
-
'@jridgewell/source-map': 0.3.11
3076
-
acorn: 8.15.0
3077
-
commander: 2.20.3
3078
-
source-map-support: 0.5.21
3079
-
3080
-
tinyglobby@0.2.15:
3081
-
dependencies:
3082
-
fdir: 6.5.0(picomatch@4.0.3)
3083
-
picomatch: 4.0.3
3084
-
3085
-
to-regex-range@5.0.1:
3086
-
dependencies:
3087
-
is-number: 7.0.0
3088
-
3089
-
tslib@2.8.1: {}
3090
-
3091
-
typescript@5.8.2: {}
3092
-
3093
-
typescript@5.8.3: {}
3094
-
3095
-
ufo@1.6.1: {}
3096
-
3097
-
undici-types@7.16.0: {}
3098
-
3099
-
universalify@0.1.2: {}
3100
-
3101
-
universalify@2.0.1: {}
3102
-
3103
-
update-browserslist-db@1.2.1(browserslist@4.28.1):
3104
-
dependencies:
3105
-
browserslist: 4.28.1
3106
-
escalade: 3.2.0
3107
-
picocolors: 1.1.1
3108
-
3109
-
uri-js@4.4.1:
3110
-
dependencies:
3111
-
punycode: 2.3.1
3112
-
3113
-
vite-plugin-dts@4.5.4(@types/node@24.10.1)(rollup@4.53.3)(typescript@5.8.3)(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1)):
3114
-
dependencies:
3115
-
'@microsoft/api-extractor': 7.55.1(@types/node@24.10.1)
3116
-
'@rollup/pluginutils': 5.3.0(rollup@4.53.3)
3117
-
'@volar/typescript': 2.4.26
3118
-
'@vue/language-core': 2.2.0(typescript@5.8.3)
3119
-
compare-versions: 6.1.1
3120
-
debug: 4.4.3
3121
-
kolorist: 1.8.0
3122
-
local-pkg: 1.1.2
3123
-
magic-string: 0.30.21
3124
-
typescript: 5.8.3
3125
-
optionalDependencies:
3126
-
vite: 7.2.6(@types/node@24.10.1)(terser@5.44.1)
3127
-
transitivePeerDependencies:
3128
-
- '@types/node'
3129
-
- rollup
3130
-
- supports-color
3131
-
3132
-
vite-prerender-plugin@0.5.12(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1)):
3133
-
dependencies:
3134
-
kolorist: 1.8.0
3135
-
magic-string: 0.30.21
3136
-
node-html-parser: 6.1.13
3137
-
simple-code-frame: 1.3.0
3138
-
source-map: 0.7.6
3139
-
stack-trace: 1.0.0-pre2
3140
-
vite: 7.2.6(@types/node@24.10.1)(terser@5.44.1)
3141
-
3142
-
vite@7.2.6(@types/node@24.10.1)(terser@5.44.1):
3143
-
dependencies:
3144
-
esbuild: 0.25.12
3145
-
fdir: 6.5.0(picomatch@4.0.3)
3146
-
picomatch: 4.0.3
3147
-
postcss: 8.5.6
3148
-
rollup: 4.53.3
3149
-
tinyglobby: 0.2.15
3150
-
optionalDependencies:
3151
-
'@types/node': 24.10.1
3152
-
fsevents: 2.3.3
3153
-
terser: 5.44.1
3154
-
3155
-
vitefu@1.1.1(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1)):
3156
-
optionalDependencies:
3157
-
vite: 7.2.6(@types/node@24.10.1)(terser@5.44.1)
3158
-
3159
-
vscode-uri@3.1.0: {}
3160
-
3161
-
which@2.0.2:
3162
-
dependencies:
3163
-
isexe: 2.0.0
3164
-
3165
-
yallist@3.1.1: {}
3166
-
3167
-
yallist@4.0.0: {}
3168
-
3169
-
zimmerframe@1.1.4: {}
-9
pnpm-workspace.yaml
-9
pnpm-workspace.yaml
-19
themes/dark.css
-19
themes/dark.css
···
1
-
.bluesky-embed {
2
-
--font-size: 16px;
3
-
--font-family:
4
-
system-ui, 'Segoe UI', 'Roboto', 'Helvetica', 'Arial', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
5
-
--max-feed-height: 600px;
6
-
}
7
-
8
-
.bluesky-embed {
9
-
--text-primary: #f1f3f5;
10
-
--text-secondary: #8c9eb2;
11
-
--text-link: #1083fe;
12
-
--background-primary: #000000;
13
-
--background-secondary: #212d3b;
14
-
--divider: rgb(37, 51, 66);
15
-
--divider-hover: rgb(66, 87, 108);
16
-
--button: #208bfe;
17
-
--button-text: #ffffff;
18
-
--button-hover: #4ca2fe;
19
-
}
-19
themes/dim.css
-19
themes/dim.css
···
1
-
.bluesky-embed {
2
-
--font-size: 16px;
3
-
--font-family:
4
-
system-ui, 'Segoe UI', 'Roboto', 'Helvetica', 'Arial', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
5
-
--max-feed-height: 600px;
6
-
}
7
-
8
-
.bluesky-embed {
9
-
--text-primary: #f1f3f5;
10
-
--text-secondary: #aebbc9;
11
-
--text-link: #1083fe;
12
-
--background-primary: #161e27;
13
-
--background-secondary: #212d3b;
14
-
--divider: #2e4052;
15
-
--divider-hover: #4a6179;
16
-
--button: #208bfe;
17
-
--button-text: #ffffff;
18
-
--button-hover: #4ca2fe;
19
-
}
-19
themes/light.css
-19
themes/light.css
···
1
-
.bluesky-embed {
2
-
--font-size: 16px;
3
-
--font-family:
4
-
system-ui, 'Segoe UI', 'Roboto', 'Helvetica', 'Arial', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
5
-
--max-feed-height: 600px;
6
-
}
7
-
8
-
.bluesky-embed {
9
-
--text-primary: #000000;
10
-
--text-secondary: #455668;
11
-
--text-link: #1083fe;
12
-
--background-primary: #ffffff;
13
-
--background-secondary: #455668;
14
-
--divider-hover: #a9b7c5;
15
-
--divider: #d4dbe2;
16
-
--button: #1083fe;
17
-
--button-text: #ffffff;
18
-
--button-hover: #0168d5;
19
-
}