@jant/core 0.3.49 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{app-C8bKBHtv.js → app-B9XQDSoB.js} +113 -71
- package/dist/{app-DxnM9H8F.js → app-CHW6VVQt.js} +1 -1
- package/dist/client/.vite/manifest.json +1 -1
- package/dist/client/_assets/{client-auth-Ce5WEAVS.js → client-auth-DFDajqqT.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/node.js +2 -2
- package/package.json +1 -1
- package/src/client/compose-bridge.ts +5 -0
- package/src/client/palette-search-trigger.ts +35 -0
- package/src/client-auth.ts +1 -0
- package/src/lib/__tests__/hosted-domain.test.ts +1 -1
- package/src/lib/hosted-domain-check.ts +21 -80
- package/src/lib/hosted-domain.ts +1 -1
- package/src/routes/api/internal/__tests__/sites.test.ts +168 -0
- package/src/routes/api/internal/sites.ts +63 -10
- package/src/routes/hosted/__tests__/domain-check.test.ts +30 -19
- package/src/routes/hosted/domain-check.ts +9 -14
- package/src/services/site-admin.ts +62 -1
- package/src/ui/shared/MediaGallery.tsx +1 -1
- package/src/ui/shared/__tests__/media-gallery.test.ts +3 -1
|
@@ -3418,9 +3418,9 @@ function normalizeThemeColorForMeta(color) {
|
|
|
3418
3418
|
* internal paths (e.g. `/_assets/client-HASH.js`) embedded by the Worker build
|
|
3419
3419
|
* from the Vite client manifest. Used only in production (IS_VITE_DEV=false).
|
|
3420
3420
|
*/ var IS_VITE_DEV = typeof __JANT_DEV__ !== "undefined" && __JANT_DEV__ === true;
|
|
3421
|
-
var CORE_VERSION = "0.
|
|
3421
|
+
var CORE_VERSION = "0.4.0-aa2a43928b7884a5";
|
|
3422
3422
|
var CLIENT_JS_FILE = "/_assets/client-dSfWfMe9.js";
|
|
3423
|
-
var CLIENT_AUTH_JS_FILE = "/_assets/client-auth-
|
|
3423
|
+
var CLIENT_AUTH_JS_FILE = "/_assets/client-auth-DFDajqqT.js";
|
|
3424
3424
|
var CLIENT_CSS_FILE = "/_assets/client-BoUn7xBo.css";
|
|
3425
3425
|
var CLIENT_CJK_CSS_FILE = "/_assets/client-cjk-B7Z0snDu.css";
|
|
3426
3426
|
var CLIENT_CJK_TC_CSS_FILE = "/_assets/client-cjk-tc-BesJYrb2.css";
|
|
@@ -3739,7 +3739,7 @@ var IconSprite = () => {
|
|
|
3739
3739
|
const cjkSerifFont = appConfig?.cjkSerifFont ?? "off";
|
|
3740
3740
|
const cjkStylesheetPath = cjkSerifFont === "zh-Hans" ? IS_VITE_DEV ? assetPath("/src/style-cjk.css") : toPublicAssetPath(CLIENT_CJK_CSS_FILE, assetBasePath) : cjkSerifFont === "zh-Hant" ? IS_VITE_DEV ? assetPath("/src/style-cjk-tc.css") : toPublicAssetPath(CLIENT_CJK_TC_CSS_FILE, assetBasePath) : cjkSerifFont === "ja" ? IS_VITE_DEV ? assetPath("/src/style-cjk-jp.css") : toPublicAssetPath(CLIENT_CJK_JP_CSS_FILE, assetBasePath) : cjkSerifFont === "ko" ? IS_VITE_DEV ? assetPath("/src/style-cjk-kr.css") : toPublicAssetPath(CLIENT_CJK_KR_CSS_FILE, assetBasePath) : null;
|
|
3741
3741
|
const clientScriptPath = IS_VITE_DEV ? resolvedClientBundle === "full" ? assetPath("/src/client-auth.ts") : assetPath("/src/client.ts") : toPublicAssetPath(resolvedClientBundle === "full" ? CLIENT_AUTH_JS_FILE : CLIENT_JS_FILE, assetBasePath);
|
|
3742
|
-
const faviconAssetVersion = resolvedFaviconVersion || "0.
|
|
3742
|
+
const faviconAssetVersion = resolvedFaviconVersion || "0.4.0-aa2a43928b7884a5";
|
|
3743
3743
|
const resolvedFaviconHref = faviconHref ?? (faviconAssetVersion ? toPublicPath(`/favicon.ico?v=${faviconAssetVersion}`, sitePathPrefix) : toPublicPath("/favicon.ico", sitePathPrefix));
|
|
3744
3744
|
const resolvedAppleTouchHref = appleTouchHref ?? (faviconAssetVersion ? toPublicPath(`/apple-touch-icon.png?v=${faviconAssetVersion}`, sitePathPrefix) : toPublicPath("/apple-touch-icon.png", sitePathPrefix));
|
|
3745
3745
|
const socialImageHref = resolvedSocialImagePath && (isFullUrl(resolvedSocialImagePath) || resolvedSocialImagePath.startsWith("//") ? resolvedSocialImagePath : toAbsoluteSiteUrl(resolvedSocialImagePath, appConfig?.siteUrl || "", sitePathPrefix));
|
|
@@ -6397,83 +6397,44 @@ hostedSsoRoutes.get("/__sso", async (c) => {
|
|
|
6397
6397
|
}
|
|
6398
6398
|
});
|
|
6399
6399
|
//#endregion
|
|
6400
|
-
//#region src/lib/crypto.ts
|
|
6401
|
-
/**
|
|
6402
|
-
* Compare two byte arrays using a constant-time loop.
|
|
6403
|
-
*
|
|
6404
|
-
* This avoids relying on runtime-specific crypto helpers so the same behavior
|
|
6405
|
-
* works in Node.js and Workers.
|
|
6406
|
-
*
|
|
6407
|
-
* @param a - First byte array
|
|
6408
|
-
* @param b - Second byte array
|
|
6409
|
-
* @returns `true` when the inputs are byte-for-byte identical
|
|
6410
|
-
*
|
|
6411
|
-
* @example
|
|
6412
|
-
* ```ts
|
|
6413
|
-
* const isEqual = timingSafeEqualBytes(
|
|
6414
|
-
* new TextEncoder().encode("abc"),
|
|
6415
|
-
* new TextEncoder().encode("abc"),
|
|
6416
|
-
* );
|
|
6417
|
-
* ```
|
|
6418
|
-
*/ function timingSafeEqualBytes(a, b) {
|
|
6419
|
-
if (a.byteLength !== b.byteLength) return false;
|
|
6420
|
-
let mismatch = 0;
|
|
6421
|
-
for (let index = 0; index < a.byteLength; index += 1) mismatch |= (a[index] ?? 0) ^ (b[index] ?? 0);
|
|
6422
|
-
return mismatch === 0;
|
|
6423
|
-
}
|
|
6424
|
-
/**
|
|
6425
|
-
* Compare two strings using a constant-time byte comparison.
|
|
6426
|
-
*
|
|
6427
|
-
* @param a - First string
|
|
6428
|
-
* @param b - Second string
|
|
6429
|
-
* @returns `true` when the UTF-8 byte sequences are identical
|
|
6430
|
-
*
|
|
6431
|
-
* @example
|
|
6432
|
-
* ```ts
|
|
6433
|
-
* const isEqual = timingSafeEqualText("token-a", "token-b");
|
|
6434
|
-
* ```
|
|
6435
|
-
*/ function timingSafeEqualText(a, b) {
|
|
6436
|
-
const encoder = new TextEncoder();
|
|
6437
|
-
return timingSafeEqualBytes(encoder.encode(a), encoder.encode(b));
|
|
6438
|
-
}
|
|
6439
|
-
//#endregion
|
|
6440
6400
|
//#region src/lib/hosted-domain-check.ts
|
|
6401
|
+
var VERIFICATION_HMAC_VERSION = "v1";
|
|
6441
6402
|
var textEncoder$3 = new TextEncoder();
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
6403
|
+
function bytesToHex$1(bytes) {
|
|
6404
|
+
let out = "";
|
|
6405
|
+
for (const byte of bytes) out += byte.toString(16).padStart(2, "0");
|
|
6406
|
+
return out;
|
|
6447
6407
|
}
|
|
6448
|
-
|
|
6408
|
+
/**
|
|
6409
|
+
* Compute the plaintext HMAC token returned from
|
|
6410
|
+
* `/.well-known/jant-verification`.
|
|
6411
|
+
*
|
|
6412
|
+
* The control plane sends a nonce in the query string; the site replies with
|
|
6413
|
+
* `jant-verification=<hex>` where `<hex>` is `HMAC-SHA256(secret, payload)`
|
|
6414
|
+
* over `payload = "v1:" + host + ":" + nonce`. The shared secret is
|
|
6415
|
+
* `HOSTED_CONTROL_PLANE_DOMAIN_CHECK_SECRET`.
|
|
6416
|
+
*/ async function computeHostedVerificationToken(secret, host, nonce) {
|
|
6449
6417
|
const key = await crypto.subtle.importKey("raw", textEncoder$3.encode(secret), {
|
|
6450
6418
|
name: "HMAC",
|
|
6451
6419
|
hash: "SHA-256"
|
|
6452
6420
|
}, false, ["sign"]);
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
async function signHostedDomainCheckToken(secret, claims) {
|
|
6456
|
-
const payload = toBase64Url$1(textEncoder$3.encode(JSON.stringify(claims)));
|
|
6457
|
-
return `${payload}.${toBase64Url$1(await createHmacSignature$1(secret, payload))}`;
|
|
6421
|
+
const payload = `${VERIFICATION_HMAC_VERSION}:${host.trim().toLowerCase()}:${nonce}`;
|
|
6422
|
+
return bytesToHex$1(new Uint8Array(await crypto.subtle.sign("HMAC", key, textEncoder$3.encode(payload))));
|
|
6458
6423
|
}
|
|
6459
6424
|
//#endregion
|
|
6460
6425
|
//#region src/routes/hosted/domain-check.ts
|
|
6461
6426
|
var hostedDomainCheckRoutes = new Hono();
|
|
6462
|
-
hostedDomainCheckRoutes.get("/.well-known/jant-
|
|
6427
|
+
hostedDomainCheckRoutes.get("/.well-known/jant-verification", async (c) => {
|
|
6463
6428
|
const secret = getHostedControlPlaneDomainCheckSecret(c.env);
|
|
6464
|
-
if (!secret) throw new NotFoundError("Hosted domain
|
|
6465
|
-
if (!c.var.currentSiteDomain) throw new NotFoundError("Hosted domain
|
|
6429
|
+
if (!secret) throw new NotFoundError("Hosted domain verification endpoint");
|
|
6430
|
+
if (!c.var.currentSiteDomain) throw new NotFoundError("Hosted domain verification endpoint");
|
|
6466
6431
|
const nonce = c.req.query("nonce")?.trim();
|
|
6467
|
-
if (!nonce) return c.
|
|
6468
|
-
const token = await
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
iss: "jant-core",
|
|
6474
|
-
nonce
|
|
6475
|
-
});
|
|
6476
|
-
return c.json({ token }, 200, { "Cache-Control": "no-store" });
|
|
6432
|
+
if (!nonce) return c.text("Missing nonce.", 400);
|
|
6433
|
+
const token = await computeHostedVerificationToken(secret, c.var.currentSiteDomain.host.trim().toLowerCase(), nonce);
|
|
6434
|
+
return c.text(`jant-verification=${token}\n`, 200, {
|
|
6435
|
+
"Cache-Control": "no-store",
|
|
6436
|
+
"Content-Type": "text/plain; charset=utf-8"
|
|
6437
|
+
});
|
|
6477
6438
|
});
|
|
6478
6439
|
//#endregion
|
|
6479
6440
|
//#region src/lib/collection-paths.ts
|
|
@@ -8811,7 +8772,7 @@ function getMediaPlaceholderDataUrl(blurhash, width, height) {
|
|
|
8811
8772
|
return blurhashToDataUrl(blurhash, decodeSize.width, decodeSize.height);
|
|
8812
8773
|
}
|
|
8813
8774
|
function getSingleVisualWidth(ratio) {
|
|
8814
|
-
return `min(100%, calc(24rem * ${ratio}))`;
|
|
8775
|
+
return `min(100%, calc(24rem * ${ratio}), var(--layout-content-width))`;
|
|
8815
8776
|
}
|
|
8816
8777
|
/**
|
|
8817
8778
|
* Format-specific file icon. Each MIME type gets a visually distinct icon
|
|
@@ -24752,8 +24713,10 @@ internalApiTokensRoutes.post("/purge", requireInternalAdminApi(), async (c) => {
|
|
|
24752
24713
|
});
|
|
24753
24714
|
//#endregion
|
|
24754
24715
|
//#region src/routes/api/internal/sites.ts
|
|
24716
|
+
var ManagedSiteKeySchema = z.string().trim().toLowerCase().min(3).max(40).regex(/^[a-z0-9](?:[a-z0-9-]{1,38}[a-z0-9])?$/, "Site key must use lowercase letters, numbers, or hyphens.");
|
|
24717
|
+
var SiteKeyAvailabilityQuerySchema = z.object({ key: ManagedSiteKeySchema });
|
|
24755
24718
|
var CreateManagedSiteSchema = z.object({
|
|
24756
|
-
key:
|
|
24719
|
+
key: ManagedSiteKeySchema,
|
|
24757
24720
|
primaryHost: z.string().trim().toLowerCase().min(1).max(255).regex(/^(?=.{1,255}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/, "Primary host must be a valid hostname."),
|
|
24758
24721
|
siteName: z.string().trim().min(1).max(120),
|
|
24759
24722
|
siteLanguage: z.string().trim().max(35).optional(),
|
|
@@ -24778,6 +24741,12 @@ internalSitesRoutes.post("/", requireInternalAdminApi(), async (c) => {
|
|
|
24778
24741
|
status: result.site.status
|
|
24779
24742
|
}, 201);
|
|
24780
24743
|
});
|
|
24744
|
+
internalSitesRoutes.get("/availability", requireInternalAdminApi(), async (c) => {
|
|
24745
|
+
assertHostBasedMode(c.env);
|
|
24746
|
+
const query = parseValidated(SiteKeyAvailabilityQuerySchema, { key: c.req.query("key") ?? "" });
|
|
24747
|
+
const result = await c.var.services.siteAdmin.isManagedSiteKeyAvailable(query.key);
|
|
24748
|
+
return c.json(result);
|
|
24749
|
+
});
|
|
24781
24750
|
internalSitesRoutes.delete("/:siteId", requireInternalAdminApi(), async (c) => {
|
|
24782
24751
|
assertHostBasedMode(c.env);
|
|
24783
24752
|
await c.var.services.siteAdmin.deleteManagedSite(c.req.param("siteId"), { storage: c.var.storage });
|
|
@@ -24847,6 +24816,18 @@ internalSitesRoutes.post("/:siteId/domains/:domainId/primary", requireInternalAd
|
|
|
24847
24816
|
redirectToPrimary: domain.redirectToPrimary
|
|
24848
24817
|
})) });
|
|
24849
24818
|
});
|
|
24819
|
+
var ManagedSiteDomainRedirectSchema = z.object({ redirectToPrimary: z.boolean() });
|
|
24820
|
+
internalSitesRoutes.post("/:siteId/domains/:domainId/redirect", requireInternalAdminApi(), async (c) => {
|
|
24821
|
+
assertHostBasedMode(c.env);
|
|
24822
|
+
const body = parseValidated(ManagedSiteDomainRedirectSchema, await c.req.json());
|
|
24823
|
+
const domains = await c.var.services.siteAdmin.setManagedSiteDomainRedirect(c.req.param("siteId"), c.req.param("domainId"), body.redirectToPrimary);
|
|
24824
|
+
return c.json({ domains: domains.map((domain) => ({
|
|
24825
|
+
host: domain.host,
|
|
24826
|
+
id: domain.id,
|
|
24827
|
+
kind: domain.kind,
|
|
24828
|
+
redirectToPrimary: domain.redirectToPrimary
|
|
24829
|
+
})) });
|
|
24830
|
+
});
|
|
24850
24831
|
internalSitesRoutes.delete("/:siteId/domains/:domainId", requireInternalAdminApi(), async (c) => {
|
|
24851
24832
|
assertHostBasedMode(c.env);
|
|
24852
24833
|
const domains = await c.var.services.siteAdmin.deleteManagedSiteDomain(c.req.param("siteId"), c.req.param("domainId"));
|
|
@@ -26616,7 +26597,7 @@ var cors = (options) => {
|
|
|
26616
26597
|
//#endregion
|
|
26617
26598
|
//#region src/lib/hosted-domain.ts
|
|
26618
26599
|
var CANONICAL_REDIRECT_BYPASS_PREFIXES = [
|
|
26619
|
-
"/.well-known/jant-
|
|
26600
|
+
"/.well-known/jant-verification",
|
|
26620
26601
|
"/__dev",
|
|
26621
26602
|
"/__sso",
|
|
26622
26603
|
"/api/",
|
|
@@ -26963,6 +26944,46 @@ function createD1RateLimiter(db, schema, now = () => Math.floor(Date.now() / 1e3
|
|
|
26963
26944
|
} };
|
|
26964
26945
|
}
|
|
26965
26946
|
//#endregion
|
|
26947
|
+
//#region src/lib/crypto.ts
|
|
26948
|
+
/**
|
|
26949
|
+
* Compare two byte arrays using a constant-time loop.
|
|
26950
|
+
*
|
|
26951
|
+
* This avoids relying on runtime-specific crypto helpers so the same behavior
|
|
26952
|
+
* works in Node.js and Workers.
|
|
26953
|
+
*
|
|
26954
|
+
* @param a - First byte array
|
|
26955
|
+
* @param b - Second byte array
|
|
26956
|
+
* @returns `true` when the inputs are byte-for-byte identical
|
|
26957
|
+
*
|
|
26958
|
+
* @example
|
|
26959
|
+
* ```ts
|
|
26960
|
+
* const isEqual = timingSafeEqualBytes(
|
|
26961
|
+
* new TextEncoder().encode("abc"),
|
|
26962
|
+
* new TextEncoder().encode("abc"),
|
|
26963
|
+
* );
|
|
26964
|
+
* ```
|
|
26965
|
+
*/ function timingSafeEqualBytes(a, b) {
|
|
26966
|
+
if (a.byteLength !== b.byteLength) return false;
|
|
26967
|
+
let mismatch = 0;
|
|
26968
|
+
for (let index = 0; index < a.byteLength; index += 1) mismatch |= (a[index] ?? 0) ^ (b[index] ?? 0);
|
|
26969
|
+
return mismatch === 0;
|
|
26970
|
+
}
|
|
26971
|
+
/**
|
|
26972
|
+
* Compare two strings using a constant-time byte comparison.
|
|
26973
|
+
*
|
|
26974
|
+
* @param a - First string
|
|
26975
|
+
* @param b - Second string
|
|
26976
|
+
* @returns `true` when the UTF-8 byte sequences are identical
|
|
26977
|
+
*
|
|
26978
|
+
* @example
|
|
26979
|
+
* ```ts
|
|
26980
|
+
* const isEqual = timingSafeEqualText("token-a", "token-b");
|
|
26981
|
+
* ```
|
|
26982
|
+
*/ function timingSafeEqualText(a, b) {
|
|
26983
|
+
const encoder = new TextEncoder();
|
|
26984
|
+
return timingSafeEqualBytes(encoder.encode(a), encoder.encode(b));
|
|
26985
|
+
}
|
|
26986
|
+
//#endregion
|
|
26966
26987
|
//#region src/lib/hosted-sso.ts
|
|
26967
26988
|
var textEncoder = new TextEncoder();
|
|
26968
26989
|
var textDecoder = new TextDecoder();
|
|
@@ -30755,6 +30776,14 @@ function createSiteAdminService(db, databaseSchema = sqliteSchemaBundle, databas
|
|
|
30755
30776
|
if (supportsDrizzleTransaction(db, databaseDialect)) return db.transaction(async (tx) => createWithDatabase(tx, input));
|
|
30756
30777
|
return createWithDatabase(db, input);
|
|
30757
30778
|
},
|
|
30779
|
+
async isManagedSiteKeyAvailable(key) {
|
|
30780
|
+
assertManagedSiteOperationsEnabled();
|
|
30781
|
+
const normalizedKey = key.trim();
|
|
30782
|
+
return {
|
|
30783
|
+
available: !(await db.select({ id: sites.id }).from(sites).where(eq(sites.key, normalizedKey)).limit(1))[0],
|
|
30784
|
+
key: normalizedKey
|
|
30785
|
+
};
|
|
30786
|
+
},
|
|
30758
30787
|
async getManagedSiteMediaUsage(siteId) {
|
|
30759
30788
|
assertManagedSiteOperationsEnabled();
|
|
30760
30789
|
return getManagedSiteMediaUsage(siteId);
|
|
@@ -30877,7 +30906,7 @@ function createSiteAdminService(db, databaseSchema = sqliteSchemaBundle, databas
|
|
|
30877
30906
|
const timestamp = now();
|
|
30878
30907
|
if (input.makePrimary) await targetDb.update(siteDomains).set({
|
|
30879
30908
|
kind: "alias",
|
|
30880
|
-
redirectToPrimary:
|
|
30909
|
+
redirectToPrimary: false,
|
|
30881
30910
|
updatedAt: timestamp
|
|
30882
30911
|
}).where(eq(siteDomains.siteId, normalizedSiteId));
|
|
30883
30912
|
await targetDb.insert(siteDomains).values({
|
|
@@ -30892,6 +30921,19 @@ function createSiteAdminService(db, databaseSchema = sqliteSchemaBundle, databas
|
|
|
30892
30921
|
});
|
|
30893
30922
|
});
|
|
30894
30923
|
},
|
|
30924
|
+
async setManagedSiteDomainRedirect(siteId, domainId, redirectToPrimary) {
|
|
30925
|
+
assertManagedSiteOperationsEnabled();
|
|
30926
|
+
return mutateSiteDomains(siteId, async (targetDb, normalizedSiteId) => {
|
|
30927
|
+
await requireSite(targetDb, normalizedSiteId);
|
|
30928
|
+
const normalizedDomainId = domainId.trim();
|
|
30929
|
+
if (!(await targetDb.select({ id: siteDomains.id }).from(siteDomains).where(sql`${siteDomains.id} = ${normalizedDomainId} AND ${siteDomains.siteId} = ${normalizedSiteId}`).limit(1))[0]) throw new NotFoundError("Site domain");
|
|
30930
|
+
const timestamp = now();
|
|
30931
|
+
await targetDb.update(siteDomains).set({
|
|
30932
|
+
redirectToPrimary,
|
|
30933
|
+
updatedAt: timestamp
|
|
30934
|
+
}).where(eq(siteDomains.id, normalizedDomainId));
|
|
30935
|
+
});
|
|
30936
|
+
},
|
|
30895
30937
|
async setManagedSitePrimaryDomain(siteId, domainId) {
|
|
30896
30938
|
assertManagedSiteOperationsEnabled();
|
|
30897
30939
|
return mutateSiteDomains(siteId, async (targetDb, normalizedSiteId) => {
|
|
@@ -2163,7 +2163,7 @@ The @mediabunny/aac-encoder extension package provides support for encoding AAC.
|
|
|
2163
2163
|
The @mediabunny/ac3 extension package provides support for encoding and decoding AC-3/E-AC-3.`),t.includes(`flac`)&&e.push(`
|
|
2164
2164
|
The @mediabunny/flac-encoder extension package provides support for encoding FLAC.`)}else e.push(`
|
|
2165
2165
|
Check the discardedTracks field for more info.`)}return e}async execute(){if(!this.isValid)throw Error(`Cannot execute this conversion because its output configuration is invalid. Make sure to always check the isValid field before executing a conversion.
|
|
2166
|
-
`+this._getInvalidityExplanation().join(``));if(this._executed)throw Error(`Conversion cannot be executed twice.`);if(this._executed=!0,this.onProgress){let e=this.utilizedTracks.map(e=>e.computeDuration()),t=Math.max(0,...await Promise.all(e));this._computeProgress=!0,this._totalDuration=Math.min(t-this._startTimestamp,this._endTimestamp-this._startTimestamp);for(let e of this.utilizedTracks)this._maxTimestamps.set(e.id,0);this.onProgress?.(0)}await this.output.start(),this._start();try{await Promise.all(this._trackPromises)}catch(e){throw this._canceled||this.cancel(),e}if(this._canceled)throw new VL;await this.output.finalize(),this._computeProgress&&this.onProgress?.(1)}async cancel(){if(!(this.output.state===`finalizing`||this.output.state===`finalized`)){if(this._canceled){console.warn(`Conversion already canceled.`);return}this._canceled=!0,await this.output.cancel()}}async _processVideoTrack(e,t){let n=e.codec;if(!n){this.discardedTracks.push({track:e,reason:`unknown_source_codec`});return}let r,i=LO(e.rotation+(t.rotate??0)),a=i,o=this.output.format.supportsVideoRotationMetadata&&(t.allowRotationMetadata??!0),[s,c]=i%180==0?[e.squarePixelWidth,e.squarePixelHeight]:[e.squarePixelHeight,e.squarePixelWidth],l=t.crop;l&&Zj(l,s,c);let[u,d]=l?[l.width,l.height]:[s,c],f=u,p=d,m=f/p,h=e=>Math.ceil(e/2)*2;t.width!==void 0&&t.height===void 0?(f=h(t.width),p=h(Math.round(f/m))):t.width===void 0&&t.height!==void 0?(p=h(t.height),f=h(Math.round(p*m))):t.width!==void 0&&t.height!==void 0&&(f=h(t.width),p=h(t.height));let g=await e.getFirstTimestamp(),_=this.output.format.getSupportedVideoCodecs(),v=!!t.forceTranscode||g<this._startTimestamp||!!t.frameRate||t.keyFrameInterval!==void 0||t.process!==void 0||t.bitrate!==void 0||!_.includes(n)||t.codec&&t.codec!==n||f!==u||p!==d||i!==0&&!o||!!l,y=t.alpha??`discard`;if(v){if(!await e.canDecode()){this.discardedTracks.push({track:e,reason:`undecodable_source_codec`});return}t.codec&&(_=_.filter(e=>e===t.codec));let n=t.bitrate??_L,s=await xL(_,{width:t.process&&t.processedWidth?t.processedWidth:f,height:t.process&&t.processedHeight?t.processedHeight:p,bitrate:n});if(!s){this.discardedTracks.push({track:e,reason:`no_encodable_target_codec`});return}let c={codec:s,bitrate:n,keyFrameInterval:t.keyFrameInterval,sizeChangeBehavior:t.fit??`passThrough`,alpha:y,hardwareAcceleration:t.hardwareAcceleration},m=new DL(c);r=m;let h=f!==u||p!==d||i!==0&&(!o||t.process!==void 0)||!!l||e.squarePixelWidth!==e.codedWidth||e.squarePixelHeight!==e.codedHeight;if(!h){let t=new FL({format:new cL,target:new eL}),n=new DL(c);t.addVideoTrack(n),await t.start();let r=await new yM(e).getSample(g);if(r)try{await n.add(r),r.close(),await t.finalize()}catch(e){console.info(`Error when probing encoder support. Falling back to rerender path.`,e),h=!0,t.cancel()}else await t.cancel()}h?this._trackPromises.push((async()=>{await this._started;let n=new bM(e,{width:f,height:p,fit:t.fit??`fill`,rotation:i,crop:t.crop,poolSize:1,alpha:y===`keep`}).canvases(this._startTimestamp,this._endTimestamp),r=t.frameRate;a=0;let o=null,s=null,c=null,l=async n=>{U(o),U(r!==void 0);let i=Math.round((n-s)*r);for(let n=1;n<i;n++){let i=new Jj(o,{timestamp:s+n/r,duration:1/r});await this._registerVideoSample(e,t,m,i),i.close()}};for await(let{canvas:i,timestamp:a,duration:u}of n){if(this._canceled)return;let n=Math.max(a-this._startTimestamp,0);if(c=n+u,r!==void 0){let e=Math.floor(n*r)/r;if(o!==null)if(e<=s){o=i,s=e;continue}else await l(e);n=e}let d=new Jj(i,{timestamp:n,duration:r===void 0?u:1/r});await this._registerVideoSample(e,t,m,d),d.close(),r!==void 0&&(o=i,s=n)}o&&(U(c!==null),U(r!==void 0),await l(Math.floor(c*r)/r)),m.close(),this._synchronizer.closeTrack(e.id)})()):this._trackPromises.push((async()=>{await this._started;let n=new yM(e),r=t.frameRate,i=null,a=null,o=null,s=async n=>{U(i),U(r!==void 0);let o=Math.round((n-a)*r);for(let n=1;n<o;n++)i.setTimestamp(a+n/r),i.setDuration(1/r),await this._registerVideoSample(e,t,m,i);i.close()};for await(let c of n.samples(this._startTimestamp,this._endTimestamp)){if(this._canceled){c.close(),i?.close();return}let n=Math.max(c.timestamp-this._startTimestamp,0);if(o=n+c.duration,r!==void 0){let e=Math.floor(n*r)/r;if(i!==null)if(e<=a){i.close(),i=c,a=e;continue}else await s(e);n=e,c.setDuration(1/r)}c.setTimestamp(n),await this._registerVideoSample(e,t,m,c),r===void 0?c.close():(i=c,a=n)}i&&(U(o!==null),U(r!==void 0),await s(Math.floor(o*r)/r)),m.close(),this._synchronizer.closeTrack(e.id)})())}else{let t=new wL(n);r=t,this._trackPromises.push((async()=>{await this._started;let n=new pM(e),r={decoderConfig:await e.getDecoderConfig()??void 0},i=Number.isFinite(this._endTimestamp)?await n.getPacket(this._endTimestamp,{metadataOnly:!0})??void 0:void 0;for await(let a of n.packets(void 0,i,{verifyKeyPackets:!0})){if(this._canceled)return;let n=a.clone({timestamp:a.timestamp-this._startTimestamp,sideData:y===`discard`?{}:a.sideData});U(n.timestamp>=0),this._reportProgress(e.id,n.timestamp),await t.add(n,r),this._synchronizer.shouldWait(e.id,n.timestamp)&&await this._synchronizer.wait(n.timestamp)}t.close(),this._synchronizer.closeTrack(e.id)})())}this.output.addVideoTrack(r,{frameRate:t.frameRate,languageCode:Ck(e.languageCode)?e.languageCode:void 0,name:e.name??void 0,disposition:e.disposition,rotation:a}),this._addedCounts.video++,this._totalTrackCount++,this.utilizedTracks.push(e)}async _registerVideoSample(e,t,n,r){if(this._canceled)return;this._reportProgress(e.id,r.timestamp);let i;if(!t.process)i=[r];else{let e=t.process(r);e instanceof Promise&&(e=await e),Array.isArray(e)||(e=e===null?[]:[e]),i=e.map(e=>e instanceof Jj?e:typeof VideoFrame<`u`&&e instanceof VideoFrame?new Jj(e):new Jj(e,{timestamp:r.timestamp,duration:r.duration}))}for(let t of i){if(this._canceled)break;await n.add(t),this._synchronizer.shouldWait(e.id,t.timestamp)&&await this._synchronizer.wait(t.timestamp)}for(let e of i)e!==r&&e.close()}async _processAudioTrack(e,t){let n=e.codec;if(!n){this.discardedTracks.push({track:e,reason:`unknown_source_codec`});return}let r,i=e.numberOfChannels,a=e.sampleRate,o=await e.getFirstTimestamp(),s=t.numberOfChannels??i,c=t.sampleRate??a,l=s!==i||c!==a||o<this._startTimestamp||o>this._startTimestamp&&!this.output.format.supportsTimestampedMediaData,u=this.output.format.getSupportedAudioCodecs();if(!t.forceTranscode&&!t.bitrate&&!l&&u.includes(n)&&(!t.codec||t.codec===n)&&!t.process){let t=new kL(n);r=t,this._trackPromises.push((async()=>{await this._started;let n=new pM(e),r={decoderConfig:await e.getDecoderConfig()??void 0},i=Number.isFinite(this._endTimestamp)?await n.getPacket(this._endTimestamp,{metadataOnly:!0})??void 0:void 0;for await(let a of n.packets(void 0,i)){if(this._canceled)return;let n=a.clone({timestamp:a.timestamp-this._startTimestamp});U(n.timestamp>=0),this._reportProgress(e.id,n.timestamp),await t.add(n,r),this._synchronizer.shouldWait(e.id,n.timestamp)&&await this._synchronizer.wait(n.timestamp)}t.close(),this._synchronizer.closeTrack(e.id)})())}else{if(!await e.canDecode()){this.discardedTracks.push({track:e,reason:`undecodable_source_codec`});return}let n=null;t.codec&&(u=u.filter(e=>e===t.codec));let i=t.bitrate??_L,a=await bL(u,{numberOfChannels:t.process&&t.processedNumberOfChannels?t.processedNumberOfChannels:s,sampleRate:t.process&&t.processedSampleRate?t.processedSampleRate:c,bitrate:i});if(!a.some(e=>tA.includes(e))&&u.some(e=>tA.includes(e))&&(s!==RL||c!==zL)){let e=(await bL(u,{numberOfChannels:RL,sampleRate:zL,bitrate:i})).find(e=>tA.includes(e));e&&(l=!0,n=e,s=RL,c=zL)}else n=a[0]??null;if(n===null){this.discardedTracks.push({track:e,reason:`no_encodable_target_codec`});return}if(l)r=this._resampleAudio(e,t,n,s,c,i);else{let a=new jL({codec:n,bitrate:i});r=a,this._trackPromises.push((async()=>{await this._started;let n=new CM(e);for await(let r of n.samples(void 0,this._endTimestamp)){if(this._canceled){r.close();return}r.setTimestamp(r.timestamp-this._startTimestamp),await this._registerAudioSample(e,t,a,r),r.close()}a.close(),this._synchronizer.closeTrack(e.id)})())}}this.output.addAudioTrack(r,{languageCode:Ck(e.languageCode)?e.languageCode:void 0,name:e.name??void 0,disposition:e.disposition}),this._addedCounts.audio++,this._totalTrackCount++,this.utilizedTracks.push(e)}async _registerAudioSample(e,t,n,r){if(this._canceled)return;this._reportProgress(e.id,r.timestamp);let i;if(!t.process)i=[r];else{let e=t.process(r);if(e instanceof Promise&&(e=await e),Array.isArray(e)||(e=e===null?[]:[e]),!e.every(e=>e instanceof rM))throw TypeError(`The audio process function must return an AudioSample, null, or an array of AudioSamples.`);i=e}for(let t of i){if(this._canceled)break;await n.add(t),this._synchronizer.shouldWait(e.id,t.timestamp)&&await this._synchronizer.wait(t.timestamp)}for(let e of i)e!==r&&e.close()}_resampleAudio(e,t,n,r,i,a){let o=new jL({codec:n,bitrate:a});return this._trackPromises.push((async()=>{await this._started;let n=new WL({targetNumberOfChannels:r,targetSampleRate:i,startTime:this._startTimestamp,endTime:this._endTimestamp,onSample:async n=>{await this._registerAudioSample(e,t,o,n),n.close()}}),a=new CM(e).samples(this._startTimestamp,this._endTimestamp);for await(let e of a){if(this._canceled){e.close();return}await n.add(e),e.close()}await n.finalize(),o.close(),this._synchronizer.closeTrack(e.id)})()),o}_reportProgress(e,t){if(!this._computeProgress)return;U(this._totalDuration!==null),this._maxTimestamps.set(e,Math.max(t,this._maxTimestamps.get(e)));let n=_k(Math.min(...this._maxTimestamps.values())/this._totalDuration,0,1);n!==this._lastProgress&&(this._lastProgress=n,this.onProgress?.(n))}},VL=class extends Error{constructor(e=`Conversion has been canceled.`){super(e),this.name=`ConversionCanceledError`}},HL=5,UL=class{constructor(){this.maxTimestamps=new Map,this.resolvers=[]}computeMinAndMaybeResolve(){let e=1/0;for(let[,t]of this.maxTimestamps)e=Math.min(e,t);for(let t=0;t<this.resolvers.length;t++){let n=this.resolvers[t];n.timestamp-e<HL&&(n.resolve(),this.resolvers.splice(t,1),t--)}return e}shouldWait(e,t){return this.maxTimestamps.set(e,Math.max(t,this.maxTimestamps.get(e)??-1/0)),t-this.computeMinAndMaybeResolve()>=HL}wait(e){let{promise:t,resolve:n}=ok();return this.resolvers.push({timestamp:e,resolve:n}),t}closeTrack(e){this.maxTimestamps.delete(e),this.computeMinAndMaybeResolve()}},WL=class{constructor(e){this.sourceSampleRate=null,this.sourceNumberOfChannels=null,this.targetSampleRate=e.targetSampleRate,this.targetNumberOfChannels=e.targetNumberOfChannels,this.startTime=e.startTime,this.endTime=e.endTime,this.onSample=e.onSample,this.bufferSizeInFrames=Math.floor(this.targetSampleRate*5),this.bufferSizeInSamples=this.bufferSizeInFrames*this.targetNumberOfChannels,this.outputBuffer=new Float32Array(this.bufferSizeInSamples),this.bufferStartFrame=0,this.maxWrittenFrame=-1}doChannelMixerSetup(){U(this.sourceNumberOfChannels!==null);let e=this.sourceNumberOfChannels,t=this.targetNumberOfChannels;e===1&&t===2?this.channelMixer=(t,n)=>t[n*e]:e===1&&t===4?this.channelMixer=(t,n,r)=>t[n*e]*+(r<2):e===1&&t===6?this.channelMixer=(t,n,r)=>t[n*e]*+(r===2):e===2&&t===1?this.channelMixer=(t,n)=>{let r=n*e;return .5*(t[r]+t[r+1])}:e===2&&t===4||e===2&&t===6?this.channelMixer=(t,n,r)=>t[n*e+r]*+(r<2):e===4&&t===1?this.channelMixer=(t,n)=>{let r=n*e;return .25*(t[r]+t[r+1]+t[r+2]+t[r+3])}:e===4&&t===2?this.channelMixer=(t,n,r)=>{let i=n*e;return .5*(t[i+r]+t[i+r+2])}:e===4&&t===6?this.channelMixer=(t,n,r)=>{let i=n*e;return r<2?t[i+r]:r===2||r===3?0:t[i+r-2]}:e===6&&t===1?this.channelMixer=(t,n)=>{let r=n*e;return Math.SQRT1_2*(t[r]+t[r+1])+t[r+2]+.5*(t[r+4]+t[r+5])}:e===6&&t===2?this.channelMixer=(t,n,r)=>{let i=n*e;return t[i+r]+Math.SQRT1_2*(t[i+2]+t[i+r+4])}:e===6&&t===4?this.channelMixer=(t,n,r)=>{let i=n*e;return r<2?t[i+r]+Math.SQRT1_2*t[i+2]:t[i+r+2]}:this.channelMixer=(t,n,r)=>r<e?t[n*e+r]:0}ensureTempBufferSize(e){let t=this.tempSourceBuffer.length;for(;t<e;)t*=2;if(t!==this.tempSourceBuffer.length){let e=new Float32Array(t);e.set(this.tempSourceBuffer),this.tempSourceBuffer=e}}async add(e){this.sourceSampleRate===null&&(this.sourceSampleRate=e.sampleRate,this.sourceNumberOfChannels=e.numberOfChannels,this.tempSourceBuffer=new Float32Array(this.sourceSampleRate*this.sourceNumberOfChannels),this.doChannelMixerSetup());let t=e.numberOfFrames*e.numberOfChannels;this.ensureTempBufferSize(t);let n=e.allocationSize({planeIndex:0,format:`f32`}),r=new Float32Array(this.tempSourceBuffer.buffer,0,n/4);e.copyTo(r,{planeIndex:0,format:`f32`});let i=e.timestamp-this.startTime,a=e.numberOfFrames/this.sourceSampleRate,o=Math.min(i+a,this.endTime-this.startTime),s=Math.floor(i*this.targetSampleRate),c=Math.ceil(o*this.targetSampleRate);for(let t=s;t<c;t++){if(t<this.bufferStartFrame)continue;for(;t>=this.bufferStartFrame+this.bufferSizeInFrames;)await this.finalizeCurrentBuffer(),this.bufferStartFrame+=this.bufferSizeInFrames;let n=t-this.bufferStartFrame;U(n<this.bufferSizeInFrames);let a=(t/this.targetSampleRate-i)*this.sourceSampleRate,o=Math.floor(a),s=Math.ceil(a),c=a-o;for(let t=0;t<this.targetNumberOfChannels;t++){let i=0,a=0;o>=0&&o<e.numberOfFrames&&(i=this.channelMixer(r,o,t)),s>=0&&s<e.numberOfFrames&&(a=this.channelMixer(r,s,t));let l=i+c*(a-i),u=n*this.targetNumberOfChannels+t;this.outputBuffer[u]+=l}this.maxWrittenFrame=Math.max(this.maxWrittenFrame,n)}}async finalizeCurrentBuffer(){if(this.maxWrittenFrame<0)return;let e=(this.maxWrittenFrame+1)*this.targetNumberOfChannels,t=new Float32Array(e);t.set(this.outputBuffer.subarray(0,e));let n=this.bufferStartFrame/this.targetSampleRate,r=new rM({format:`f32`,sampleRate:this.targetSampleRate,numberOfChannels:this.targetNumberOfChannels,timestamp:n,data:t});await this.onSample(r),this.outputBuffer.fill(0),this.maxWrittenFrame=-1}finalize(){return this.finalizeCurrentBuffer()}};function GL(){return typeof AudioEncoder<`u`}async function KL(e,t){let n=new MP({source:new OP(e),formats:EP}),r=new $I,i=new FL({format:new cL({fastStart:`in-memory`}),target:r});try{let a=await BL.init({input:n,output:i,video:{discard:!0},audio:{codec:`aac`,bitrate:_L}});t&&(a.onProgress=t),await a.execute();let o=r.buffer;if(!o)throw Error(`Audio processing produced no output`);let s=e.name.replace(/\.[^.]+$/,``);return{file:new File([o],`${s}.m4a`,{type:`audio/mp4`})}}finally{n.dispose()}}var qL={isSupported:GL,processToFile:KL},JL=1920,YL=1080,XL=640,ZL=32;function QL(){return typeof VideoEncoder<`u`}async function $L(e){let t=new MP({source:new OP(e),formats:EP});try{let e=await t.getPrimaryVideoTrack();if(!e)return{};let n=e.displayWidth,r=e.displayHeight,i=e.rotation,a=await t.computeDuration(),o=s(a),c=Math.min(a*.1,3),l=await new bM(e).getCanvas(c);if(!l)return{sourceWidth:n,sourceHeight:r,rotation:i,durationSeconds:o};let u=l.canvas,d=u.width,f=u.height,p=Math.min(XL/d,1),m=Math.round(d*p),h=Math.round(f*p),g=document.createElement(`canvas`);g.width=m,g.height=h;let _=g.getContext(`2d`);if(!_)return{sourceWidth:n,sourceHeight:r};_.drawImage(u,0,0,m,h);let v=await new Promise(e=>{g.toBlob(t=>e(t??void 0),`image/webp`,.8)}),y=Math.min(ZL/d,ZL/f,1),b=Math.max(Math.round(d*y),1),x=Math.max(Math.round(f*y),1),S=document.createElement(`canvas`);S.width=b,S.height=x;let C=S.getContext(`2d`);return C?(C.drawImage(u,0,0,b,x),{poster:v,blurhash:AC(C.getImageData(0,0,b,x).data,b,x,4,3),sourceWidth:n,sourceHeight:r,rotation:i,durationSeconds:o}):{poster:v,sourceWidth:n,sourceHeight:r}}catch{return{}}finally{t.dispose()}}async function eR(e,t){let{poster:n,blurhash:r,sourceWidth:i,sourceHeight:a,rotation:o,durationSeconds:s}=await $L(e),c=i||JL,l=a||YL;if(i&&a){let e=Math.max(i,a),t=Math.min(i,a),n=Math.min(JL/e,YL/t,1);c=Math.round(i*n),l=Math.round(a*n)}c+=c%2,l+=l%2;let u=new MP({source:new OP(e),formats:EP}),d=new $I,f=new FL({format:new cL({fastStart:`in-memory`}),target:d});try{let i=await BL.init({input:u,output:f,video:{codec:`avc`,width:c,height:l,fit:`contain`,bitrate:_L},audio:{codec:`aac`}});t&&(i.onProgress=t),await i.execute();let a=d.buffer;if(!a)throw Error(`Video processing produced no output`);let p=e.name.replace(/\.[^.]+$/,``),m=new File([a],`${p}.mp4`,{type:`video/mp4`}),h=await iR(m),g=Math.abs(h.width-c)<=2&&Math.abs(h.height-l)<=2;return o&&!g&&(rR(a),m=new File([a],`${p}.mp4`,{type:`video/mp4`}),h=await iR(m)),{file:m,width:h.width,height:h.height,durationSeconds:s,poster:n,blurhash:r}}finally{u.dispose()}}var tR=[65536,0,0,0,65536,0,0,0,1073741824];function nR(e,t,n,r){let i=t;for(;i+8<=n;){let t=e.getUint32(i),a=String.fromCharCode(e.getUint8(i+4),e.getUint8(i+5),e.getUint8(i+6),e.getUint8(i+7));if(t===0&&(t=n-i),t<8||i+t>n)break;r(i,t,a),(a===`moov`||a===`trak`||a===`mdia`||a===`edts`)&&nR(e,i+8,i+t,r),i+=t}}function rR(e){let t=new DataView(e);nR(t,0,e.byteLength,(n,r,i)=>{if(i!==`tkhd`)return;let a=n+8,o=a+(t.getUint8(a)===0?40:52);if(o+36>e.byteLength)return;let s=!0;for(let e=0;e<9;e++)if(t.getInt32(o+e*4)!==tR[e]){s=!1;break}if(!s)for(let e=0;e<9;e++)t.setInt32(o+e*4,tR[e])})}function iR(e){return new Promise((t,n)=>{let r=URL.createObjectURL(e),i=document.createElement(`video`);i.preload=`metadata`,i.onloadedmetadata=()=>{URL.revokeObjectURL(r),t({width:i.videoWidth,height:i.videoHeight})},i.onerror=()=>{URL.revokeObjectURL(r),n(Error(`Failed to probe transcoded video dimensions`))},i.src=r})}var aR={isSupported:QL,processToFile:eR};function oR(){return document.querySelector(`jant-compose-dialog`)}function sR(){return document.querySelector(`[data-page='collection'][data-collection-id]`)?.dataset.collectionId||void 0}function cR(e=document){if(e===document){let e=document.querySelector(`[data-page='post'] article[data-post]:hover`);if(e)return e}return e.querySelector(`[data-post-current] article[data-post]`)||e.querySelector(`[data-post-view] article[data-post]`)||(e===document?document.querySelector(`article[data-post]:hover`):null)}function lR(e){let t=e.closest(`[data-post-view]`)?.dataset.postViewId;if(t)return{kind:`post-view`,id:t};let n=e.closest(`[data-timeline-item]`),r=n?.dataset.threadRootId??e.dataset.threadRootId??e.dataset.postId;if(n&&r)return{kind:`timeline-item`,id:r};let i=e.dataset.postId;return i?{kind:`post-card`,id:i}:null}function uR(e){let t=e.cloneNode(!0);t.querySelector(`[data-post-meta]`)?.remove(),t.querySelector(`.post-status-badges`)?.remove();let n=e.querySelector(`time.dt-published`);return{contentHtml:t.innerHTML,dateText:n?.textContent?.trim()??``}}function dR(e){let t=e.dataset.format;if(t===`note`||t===`link`||t===`quote`)return t}async function fR(e){await oR()?.openNew(e)}async function pR(e){let t=e.dataset.postId;if(!t)return;let n=oR();if(!n)return;let r=e.dataset.threadRootId??t,i=dR(e);await n.openReply(t,uR(e),r,lR(e)??void 0,i?{initialFormat:i}:void 0)}function mR(e){return e instanceof globalThis.Element?e.closest(`jant-compose-editor`):null}function hR(e){return e instanceof globalThis.Element?e.closest(`jant-compose-dialog`):null}async function gR(e){let t=await fetch(e,{headers:{Accept:`text/html`}});return t.ok?t.text():null}async function _R(e){try{let t=document.querySelector(`[data-timeline-item][data-thread-root-id="${e}"]`)?.querySelector(`[data-timeline-item-content]`);if(!t)return!1;let n=await gR(`/_/timeline-item/${encodeURIComponent(e)}`);return n?(t.innerHTML=n,y(t),!0):!1}catch{return!1}}async function vR(e){try{let t=document.querySelector(`article[data-post-id="${e}"]`)?.closest(`[data-timeline-item]`),n=await gR(`/_/post-card/${encodeURIComponent(e)}`);if(!n)return!1;if(t){let e=t.querySelector(`[data-timeline-item-content]`);return e?(e.innerHTML=n,y(e),!0):!1}let r=document.querySelector(`article[data-post-id="${e}"]`);if(!r)return!1;r.outerHTML=n;let i=document.querySelector(`article[data-post-id="${e}"]`);return i&&y(i),!0}catch{return!1}}async function yR(e){try{let t=document.querySelector(`[data-post-view][data-post-view-id="${e}"]`);if(!t)return!1;let n=await gR(`/_/post-view/${encodeURIComponent(e)}`);if(!n)return!1;t.outerHTML=n;let r=document.querySelector(`[data-post-view][data-post-view-id="${e}"]`);return r&&y(r),!0}catch{return!1}}async function bR(e){return!e.replyRefreshKind||!e.replyRefreshId?!1:e.replyRefreshKind===`timeline-item`?_R(e.replyThreadRootId??e.replyRefreshId):e.replyRefreshKind===`post-view`?yR(e.replyRefreshId):vR(e.replyRefreshId)}var xR=new Map,SR=new Set,CR=new Map;function wR(e){return new Promise(t=>{let n=setTimeout(()=>{a(),t(null)},3e3),r=URL.createObjectURL(e),i=document.createElement(`video`);i.muted=!0,i.playsInline=!0,i.preload=`auto`;function a(){clearTimeout(n),i.removeAttribute(`src`),i.load(),URL.revokeObjectURL(r)}i.onloadeddata=()=>{try{let e=i.videoWidth,n=i.videoHeight;if(!e||!n){a(),t(null);return}let r=Math.min(640/e,1),o=Math.round(e*r),s=Math.round(n*r),c=document.createElement(`canvas`);c.width=o,c.height=s;let l=c.getContext(`2d`);if(!l){a(),t(null);return}l.drawImage(i,0,0,o,s),c.toBlob(e=>{a(),t(e)},`image/webp`,.6)}catch{a(),t(null)}},i.onerror=()=>{a(),t(null)},i.src=r})}async function TR(e,t,n){try{let r,i,o,s,c,l,u;if(e.type.startsWith(`video/`)){if(!aR.isSupported())return n?.updateAttachmentStatus(t,`error`,null,`Your browser doesn't support video processing. Use Chrome or Edge to upload videos.`),null;wR(e).then(e=>{e&&n?.updateAttachmentPoster(t,e)}),n?.updateAttachmentStatus(t,`processing`,null,null);let a=await aR.processToFile(e,e=>{n?.updateAttachmentProgress(t,e)});r=a.file,i=a.width,o=a.height,s=a.durationSeconds,c=a.blurhash,u=a.poster,u&&n?.updateAttachmentPoster(t,u)}else if(e.type.startsWith(`audio/`)){if(!qL.isSupported())return n?.updateAttachmentStatus(t,`error`,null,`Your browser doesn't support audio processing. Use Chrome or Edge to upload audio.`),null;try{l=await NC(e)}catch{}n?.updateAttachmentStatus(t,`processing`,null,null),r=(await qL.processToFile(e,e=>{n?.updateAttachmentProgress(t,e)})).file}else if(e.type.startsWith(`image/`)||/\.heic$/i.test(e.name)||/\.heif$/i.test(e.name)){let s=e;try{let{isHeic:a,heicTo:c}=await kO(async()=>{let{isHeic:e,heicTo:t}=await import(`./chunks/heic-to-DUUaO23q.js`);return{isHeic:e,heicTo:t}},[]);if(await a(e)){n?.updateAttachmentStatus(t,`processing`,null,null);let r=await c({blob:e,type:`image/jpeg`,quality:.92});s=new File([r],e.name.replace(/\.heic$/i,`.jpg`),{type:`image/jpeg`}),n?.updateAttachmentPreview(t,s)}let l=await re.processToFile(s);r=l.file,i=l.width,o=l.height}catch{return n?.removeAttachment(t),a(`Image format not supported.`,`error`),null}}else r=e;if(n?.updateAttachmentStatus(t,`uploading`,null,null),!e.type.startsWith(`video/`)){let e=await PC(r);i??=e.width,o??=e.height,c??=e.blurhash,l??=e.waveform,!u&&e.poster&&(u=e.poster,n?.updateAttachmentPoster(t,u))}let d,f;if(sS(e.type)===`text`)try{let e=await r.text(),t=e.replace(/\s+/g,` `).trim();f=e.length,d=t.length<=100?t:t.slice(0,100)+`…`}catch{}let p=await GC(r,{width:i,height:o,durationSeconds:s,blurhash:c,waveform:l,poster:u,summary:d,chars:f},e=>{n?.updateAttachmentProgress(t,e)});return n?.updateAttachmentStatus(t,`done`,p.id,null),CR.set(t,p.id),p.id}catch(e){let r=e instanceof Error?e.message:`Upload failed`;return n?.updateAttachmentStatus(t,`error`,null,r),n||a(r,`error`),null}}document.addEventListener(`jant:attachment-removed`,e=>{let{clientId:t,mediaId:n}=e.detail;CR.delete(t),n?fetch(`/api/upload/${n}`,{method:`DELETE`}).catch(()=>{}):SR.add(t)}),document.addEventListener(`jant:files-selected`,e=>{let t=e,n=mR(t.target);for(let{file:e,clientId:r}of t.detail.files){let t=TR(e,r,n).then(e=>SR.has(r)?(SR.delete(r),e&&fetch(`/api/upload/${e}`,{method:`DELETE`}).catch(()=>{}),null):e);xR.set(r,t),t.finally(()=>xR.delete(r))}}),document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-reply-trigger]`);if(!t)return;let n=t.closest(`article[data-post]`);n&&pR(n)});function ER(e,t){let n=e.format===`quote`,r=e.format===`link`,i=!!e.editPostId,a=e=>e||void 0,o=e=>e||null;return{format:e.format,title:n?void 0:i?o(e.title):a(e.title),body:i?o(e.body):a(e.body),url:r?i?o(e.url):a(e.url):i?null:void 0,sourceName:n?i?o(e.quoteAuthor):a(e.quoteAuthor):void 0,sourceUrl:n?i?o(e.url):a(e.url):void 0,quoteText:n?i?o(e.quoteText):a(e.quoteText):i?null:void 0,slug:e.slug||void 0,status:e.status,publishedAt:e.status===`published`?e.publishedAt:void 0,visibility:e.visibility||void 0,rating:i?e.rating>0?e.rating:null:e.rating||void 0,collectionIds:e.collectionIds,attachments:t.length>0?t:void 0,replyToId:e.replyToId||void 0,quietReply:e.quietReply||void 0}}function DR(e){return JSON.stringify(e.bodyJson)!==JSON.stringify(e.originalBodyJson??null)}function OR(e,t){let n=[];for(let r of e.attachments){if(r.type===`media`){let e=r.mediaId??t.get(r.clientId)??CR.get(r.clientId);if(!e)continue;n.push({type:`media`,mediaId:e,alt:r.alt});continue}if(r.mediaId&&!DR(r)){n.push({type:`media`,mediaId:r.mediaId});continue}n.push({type:`text`,contentFormat:`markdown`,content:AT(JSON.stringify(r.bodyJson)),summary:r.summary})}return n}document.addEventListener(`jant:compose-submit-deferred`,async e=>{let t=e,n=t.detail,r=hR(t.target)??document.querySelector(`jant-compose-dialog`),o=!!r?.pageMode,s=r?.labels,c=s?.uploading??`Uploading...`,l=n.threadPosts?n.threadPosts.some(e=>e.body.includes(`"blob:`)):n.body.includes(`"blob:`),u=n.pendingAttachments.length>0||l,f=s?.published??`Published!`,p=s?.view??`View`;u&&d(`compose-deferred`,c);let h=(e,t=`success`)=>{u?_(`compose-deferred`,e,t):a(e,t)},g=()=>{!o||!r||(r.reset(),r.updateComplete.then(()=>{r.querySelector(`jant-compose-editor`)?.focusInput()}))},v=()=>{!o||!r||(r.loading=!1)},y=()=>{if(te){n.editPostId&&r?.clearEditDraftFromStorage?.(n.editPostId);return}r?.clearLocalDraftFromStorage?.()},b=async()=>{if(!(!r||o)){if(te&&n.editPostId){if(typeof r.openEdit!=`function`)return;await r.openEdit(n.editPostId);return}if(n.replyToId){if(typeof r.openReply!=`function`)return;await r.openReply(n.replyToId,void 0,n.replyThreadRootId,n.replyRefreshKind&&n.replyRefreshId?{kind:n.replyRefreshKind,id:n.replyRefreshId}:void 0,{restoreDraft:!0,initialFormat:n.format});return}typeof r.openNew==`function`&&await r.openNew({restoreDraft:!0})}},x=async e=>{v(),await b(),h(e,`error`)},S=async()=>{await r?.refreshCollections()},C=(e,t)=>{m(e,`success`,t)},ee=()=>!o||!r||!r.consumePageLeaveRequest()?!1:(r.preparePageLeave(),globalThis.location.assign(r.closeHref||i(`/`)),!0),te=!!n.editPostId,ne=!!(n.threadPosts&&n.threadPosts.length>=2),re=null;try{let e=n.pendingAttachments.map(e=>e.clientId),t=e.map(e=>xR.get(e)??Promise.resolve(null)),a=await Promise.all(t);if(a.filter((t,n)=>t===null&&!CR.has(e[n]??``)).length>0)if(n.status===`published`&&!te)re=`upload`;else{await x(`Upload failed. Post not created.`);return}let c=new Map;for(let t=0;t<e.length;t++){let n=e[t],r=a[t];n&&r&&c.set(n,r)}if(ne&&n.threadPosts){let e=n.threadPosts,t=re?`draft`:n.status,i=(await Promise.all(e.map(async e=>{let n=e.body;if(n.includes(`"blob:`))try{let e=await $C(JSON.parse(n));n=e?JSON.stringify(e):``}catch{}return{...e,body:n,status:t}}))).map(e=>ER(e,OR(e,c))),a={posts:i};te&&n.editPostId&&(a.replaceThreadId=n.editPostId);let l=await fetch(`/compose/thread`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(a)});if(!l.ok){if(n.status===`published`&&!re){let e={posts:i.map(e=>({...e,status:`draft`}))};if((await fetch(`/compose/thread`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)})).ok){re=`server`,y();let e=s?.publishFailedDraft??`Couldn't publish. Saved as draft.`;await S(),ee()||g(),h(e);return}}await x(w(await le(l),`error`)??`Something went wrong`);return}if(re===`upload`){y();let e=s?.uploadFailedDraft??`Some uploads failed. Saved as draft.`;await S(),g(),h(e);return}let u=await le(l),d=w(u,`status`),m=w(u,`permalink`),_=w(u,`toast`);d===`published`?(y(),o?(await S(),g(),h(f)):(C(f,m?{label:p,href:m}:void 0),globalThis.location.reload())):(y(),await S(),ee()||g(),h(_??`Draft saved.`),kR(r,`draft`));return}let u=OR(n,c);if(l)try{let e=await $C(JSON.parse(n.body));n.body=e?JSON.stringify(e):``}catch{}let d=te?`/api/posts/${n.editPostId}`:`/compose`,m=te?`PUT`:`POST`,_=ER({...n,status:re?`draft`:n.status},u),v=await fetch(d,{method:m,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(_)});if(!v.ok){if(n.status===`published`&&!te&&!re){let e={..._,status:`draft`},t=await fetch(d,{method:m,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)});if(t.ok){re=`server`,y();let e=await le(t),n=s?.publishFailedDraft??`Couldn't publish. Saved as draft.`;await S(),ee()||g(),h(n);let r=w(e,`toast`);r&&h(r);return}}await x(w(await le(v),`error`)??`Something went wrong`);return}if(te){y();let e=await le(v),t=n.editPostId??``,r=w(e,`slug`),a=r?i(`/${r}`):null;if(o)a&&a!==globalThis.location.pathname?(C(`Post updated.`),globalThis.location.assign(a)):t&&await yR(t)?h(`Post updated.`):(C(`Post updated.`),globalThis.location.assign(globalThis.location.pathname));else if(t)if(document.querySelector(`[data-post-view][data-post-view-id="${t}"]`))await yR(t)?h(`Post updated.`):(C(`Post updated.`),globalThis.location.reload());else{let e=document.querySelector(`article[data-post-id="${t}"]`)?.closest(`[data-timeline-item]`)?.dataset.threadRootId;(e?await _R(e):await vR(t))?h(`Post updated.`):(C(`Post updated.`),globalThis.location.reload())}else C(`Post updated.`),globalThis.location.reload();return}if(re===`upload`){y();let e=s?.uploadFailedDraft??`Some uploads failed. Saved as draft.`;await S(),g(),h(e);return}let b=await le(v),ie=w(b,`status`),ae=w(b,`permalink`),oe=w(b,`toast`);if(ie===`published`){if(y(),o)await S(),g(),h(f);else if(n.replyToId){if(await S(),!await bR(n)){C(f,ae?{label:p,href:ae}:void 0),globalThis.location.reload();return}h(f)}else C(f,ae?{label:p,href:ae}:void 0),globalThis.location.reload();return}else y(),await S(),ee()||g(),h(oe??`Draft saved.`),kR(r,`draft`)}catch{await x(`Something went wrong`)}});function kR(e,t){(e??document).dispatchEvent(new CustomEvent(`jant:compose-submit-complete`,{bubbles:!0,detail:{status:t}}))}var AR=`.compose-prompt`,jR=`.compose-prompt-trigger`,MR=`jant.composeOpenShortcutDiscovery`,NR=`/api/settings/discovery/compose-open-shortcut`,PR=350,FR=1800,IR=3,LR=`compose-prompt-discovery-visible`,RR=!1,zR=null,BR=null,VR=null;function HR(){try{return globalThis.localStorage!==void 0}catch{return!1}}function UR(){if(!HR())return{shownCount:0,completed:!1};let e=globalThis.localStorage.getItem(MR);if(!e)return{shownCount:0,completed:!1};try{let t=JSON.parse(e);return{shownCount:typeof t.shownCount==`number`&&t.shownCount>=0?t.shownCount:0,completed:t.completed===!0}}catch{return globalThis.localStorage.removeItem(MR),{shownCount:0,completed:!1}}}function WR(e){if(HR())try{globalThis.localStorage.setItem(MR,JSON.stringify(e))}catch{}}function GR(){zR!==null&&(clearTimeout(zR),zR=null)}function KR(){BR!==null&&(clearTimeout(BR),BR=null)}function qR(){return typeof globalThis.matchMedia==`function`&&globalThis.matchMedia(`(min-width: 700px)`).matches}function JR(e){return UR().completed?!0:e?.dataset.composeOpenShortcutDiscovered===`true`}function YR(e){e&&(e.dataset.composeOpenShortcutDiscovered=`true`,e.classList.remove(LR)),document.querySelectorAll(AR).forEach(e=>{e.dataset.composeOpenShortcutDiscovered=`true`,e.classList.remove(LR)})}function XR(){let e=UR();e.completed||RR||e.shownCount>=IR||(RR=!0,WR({...e,shownCount:e.shownCount+1}))}function ZR(e){return!qR()||JR(e)?!1:UR().shownCount<IR||RR}function QR(e){GR(),KR(),e?e.classList.remove(LR):VR&&VR.classList.remove(LR),(!e||e===VR)&&(VR=null)}function $R(e){ZR(e)&&(QR(VR),VR=e,e.classList.add(LR),XR(),BR=setTimeout(()=>{QR(e)},FR))}function ez(e){ZR(e)&&(e.classList.contains(LR)||(GR(),zR=setTimeout(()=>{$R(e)},PR)))}function tz(e){if(e.dataset.composeOpenShortcutDiscoveryBound===`true`)return;let t=e.querySelector(jR);t&&(e.dataset.composeOpenShortcutDiscoveryBound=`true`,t.addEventListener(`pointerenter`,()=>{ez(e)}),t.addEventListener(`pointerleave`,()=>{QR(e)}),t.addEventListener(`focusin`,()=>{ez(e)}),t.addEventListener(`focusout`,()=>{QR(e)}))}function nz(e=document){e.querySelectorAll(AR).forEach(e=>tz(e))}function rz(){let e=UR();e.completed||WR({shownCount:Math.max(e.shownCount,IR),completed:!0}),YR(VR),QR(VR),typeof globalThis.fetch==`function`&&globalThis.fetch(NR,{method:`POST`,headers:{Accept:`application/json`},credentials:`same-origin`}).catch(()=>{})}document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,()=>{nz()}):nz();var iz=[`input`,`textarea`,`select`,`button`,`a[href]`,`[contenteditable='']`,`[contenteditable='true']`,`[role='textbox']`,`.ProseMirror`].join(`, `);function az(e){return e instanceof globalThis.Element&&e.closest(iz)!==null}function oz(e){if(e.defaultPrevented||e.isComposing||e.repeat||e.metaKey||e.ctrlKey||e.altKey||!oR()||document.querySelector(`[data-page="compose"]`)||document.querySelector(`dialog[open]`))return!0;let t=document.activeElement;return az(e.target)||t!==e.target&&az(t)}async function sz(e,t,n){try{if(!(await fetch(`/api/posts/${e}`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({featured:t})})).ok)throw Error();t?n.setAttribute(`data-post-featured`,``):n.removeAttribute(`data-post-featured`),a(t?`Added to Featured.`:`Removed from Featured.`)}catch{a(`Could not update post. Try again.`,`error`)}}document.addEventListener(`keydown`,e=>{let t=e.key.toLowerCase();if(t!==`n`&&t!==`l`&&t!==`q`&&t!==`r`&&t!==`e`&&t!==`c`&&t!==`f`||oz(e))return;if(t===`n`||t===`l`||t===`q`){e.preventDefault(),rz();let n=sR(),r=t===`l`?`link`:t===`q`?`quote`:void 0;fR({...n?{collectionId:n}:void 0,...r?{initialFormat:r}:void 0});return}let n=cR();if(n){if(t===`r`){e.preventDefault(),pR(n);return}if(t===`e`){let t=n.dataset.postId;if(!t)return;e.preventDefault();let r=oR();r&&r.openEdit(t);return}if(t===`c`){e.preventDefault();let t=document.querySelector(`jant-post-menu`);t&&t.openCollectionsForPost(n);return}if(t===`f`){let t=n.dataset.postId;if(!t)return;e.preventDefault(),sz(t,!n.hasAttribute(`data-post-featured`),n);return}}});var cz=[`en`,`zh-Hans`,`zh-Hant`];function lz(e){return typeof e==`string`&&cz.includes(e)}function uz(e){let t=e.trim();if(!t)return`en`;let n;try{n=new Intl.Locale(t)}catch{return`en`}if(lz(n.baseName))return n.baseName;if(n.language===`zh`){let e=n.region;return n.script===`Hant`||e===`TW`||e===`HK`||e===`MO`?`zh-Hant`:`zh-Hans`}return`en`}var dz={en:1,"zh-Hans":1,"zh-Hant":1},fz=`en.zh-Hans.zh-Hant.ja.ko.es.fr.de.it.pt.ru.ar.hi.bn.ur.tr.vi.th.id.fa.he.nl.pl.sv.da.no.fi.cs.hu.el.ro.uk.en-GB.en-US.fr-CA.pt-BR.es-MX.zh-CN.zh-TW.zh-HK`.split(`.`),pz=null;function mz(e){let t=e,n=e;try{let n=new Intl.DisplayNames([e],{type:`language`}).of(e);typeof n==`string`&&n.length>0&&(t=n)}catch{}try{let t=new Intl.DisplayNames([`en`],{type:`language`}).of(e);typeof t==`string`&&t.length>0&&(n=t)}catch{}return{tag:e,native:t,english:n,coverage:hz(e)}}function hz(e){let t=uz(e);if(t===`en`){let t;try{t=new Intl.Locale(e).language}catch{return 0}if(t!==`en`)return 0}return dz[t]}function gz(){return pz||(pz=fz.map(mz),pz)}function _z(e){let t=e.trim();return gz().find(e=>e.tag===t)||mz(t)}var vz=class extends c{static properties={labels:{type:Object},timezones:{type:Array},cjkFonts:{type:Array,attribute:`cjk-fonts`},siteNameFallback:{type:String,attribute:`sitename-fallback`},siteDescriptionFallback:{type:String,attribute:`sitedescription-fallback`},demoMode:{type:Boolean,attribute:`demo-mode`},mainFeedUrl:{type:String,attribute:`main-feed-url`},latestFeedUrl:{type:String,attribute:`latest-feed-url`},featuredFeedUrl:{type:String,attribute:`featured-feed-url`},_siteName:{state:!0},_siteDescription:{state:!0},_siteFooter:{state:!0},_origSite:{state:!0},_siteDirty:{state:!0},_siteLoading:{state:!0},_siteLanguage:{state:!0},_localeOpen:{state:!0},_localeQuery:{state:!0},_cjkSerifFont:{state:!0},_timeZone:{state:!0},_origLocale:{state:!0},_localeDirty:{state:!0},_localeLoading:{state:!0},_mainRssFeed:{state:!0},_origMainRssFeed:{state:!0},_feedDirty:{state:!0},_feedLoading:{state:!0},_showJantBrandingOnHome:{state:!0},_origShowJantBrandingOnHome:{state:!0},_homeLoading:{state:!0},_noindex:{state:!0},_origNoindex:{state:!0},_searchLoading:{state:!0}};_descEditor=null;_footerEditor=null;createRenderRoot(){return this.innerHTML=``,this}constructor(){super(),this.labels={},this.timezones=[],this.cjkFonts=[],this.siteNameFallback=``,this.siteDescriptionFallback=``,this.demoMode=!1,this.mainFeedUrl=`/feed`,this.latestFeedUrl=`/feed/latest`,this.featuredFeedUrl=`/feed/featured`,this._siteName=``,this._siteDescription=``,this._siteFooter=``,this._origSite={siteName:``,siteDescription:``,siteFooter:``},this._siteDirty=!1,this._siteLoading=!1,this._siteLanguage=`en`,this._localeOpen=!1,this._localeQuery=``,this._cjkSerifFont=`off`,this._timeZone=`UTC`,this._origLocale={siteLanguage:`en`,cjkSerifFont:`off`,timeZone:`UTC`},this._localeDirty=!1,this._localeLoading=!1,this._mainRssFeed=`featured`,this._origMainRssFeed=`featured`,this._feedDirty=!1,this._feedLoading=!1,this._noindex=!1,this._origNoindex=!1,this._showJantBrandingOnHome=!1,this._origShowJantBrandingOnHome=!1,this._homeLoading=!1,this._searchLoading=!1}connectedCallback(){super.connectedCallback(),document.addEventListener(`click`,this._onLocalePickerDocumentClick),document.addEventListener(`keydown`,this._onLocalePickerKeydown)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(`click`,this._onLocalePickerDocumentClick),document.removeEventListener(`keydown`,this._onLocalePickerKeydown),this._descEditor?.destroy(),this._descEditor=null,this._footerEditor?.destroy(),this._footerEditor=null}initData(e){this._siteName=e.siteName,this._siteDescription=e.siteDescription,this._siteFooter=e.siteFooter,this._siteLanguage=e.siteLanguage,this._cjkSerifFont=e.cjkSerifFont,this._timeZone=e.timeZone,this._origLocale={siteLanguage:e.siteLanguage,cjkSerifFont:e.cjkSerifFont,timeZone:e.timeZone},this._mainRssFeed=e.mainRssFeed,this._origMainRssFeed=e.mainRssFeed,this._showJantBrandingOnHome=e.showJantBrandingOnHome,this._origShowJantBrandingOnHome=e.showJantBrandingOnHome,this._noindex=e.noindex,this._origNoindex=e.noindex,this.updateComplete.then(()=>{this._initEditors(),this._origSite={siteName:e.siteName,siteDescription:this._siteDescription,siteFooter:this._siteFooter}})}sectionSaved(e){e===`site`?(this._origSite={siteName:this._siteName,siteDescription:this._siteDescription,siteFooter:this._siteFooter},this._siteDirty=!1,this._siteLoading=!1):e===`language-time`?(this._origLocale={siteLanguage:this._siteLanguage,cjkSerifFont:this._cjkSerifFont,timeZone:this._timeZone},this._localeDirty=!1,this._localeLoading=!1):e===`feeds`?(this._origMainRssFeed=this._mainRssFeed,this._feedDirty=!1,this._feedLoading=!1):e===`home`?(this._origShowJantBrandingOnHome=this._showJantBrandingOnHome,this._homeLoading=!1):e===`search`&&(this._origNoindex=this._noindex,this._searchLoading=!1)}sectionError(e){e===`site`?this._siteLoading=!1:e===`language-time`?this._localeLoading=!1:e===`feeds`?this._feedLoading=!1:e===`home`?(this._showJantBrandingOnHome=this._origShowJantBrandingOnHome,this._homeLoading=!1):e===`search`&&(this._noindex=this._origNoindex,this._searchLoading=!1)}_initEditors(){this._initDescEditor(),this._initFooterEditor()}_initDescEditor(){let e=this.querySelector(`[data-settings-desc-editor]`);if(!e||this._descEditor)return;this._descEditor=NT({element:e,placeholder:this.siteDescriptionFallback,content:this._siteDescription||void 0,onUpdate:e=>{this._siteDescription=e,this._syncSiteDirty()}}),this._siteDescription=MT(this._descEditor.getJSON());let t=e.querySelector(`.ProseMirror`);t&&(t.style.outline=`none`,t.style.minHeight=`3rem`)}_initFooterEditor(){let e=this.querySelector(`[data-settings-footer-editor]`);if(!e||this._footerEditor)return;this._footerEditor=NT({element:e,content:this._siteFooter||void 0,onUpdate:e=>{this._siteFooter=e,this._syncSiteDirty()}}),this._siteFooter=MT(this._footerEditor.getJSON());let t=e.querySelector(`.ProseMirror`);t&&(t.style.outline=`none`,t.style.minHeight=`6rem`)}_syncSiteDirty(){this._siteDirty=this._siteName!==this._origSite.siteName||this._siteDescription!==this._origSite.siteDescription||this._siteFooter!==this._origSite.siteFooter}_saveSite(){this._siteLoading||!this._siteDirty||(this._siteLoading=!0,this.dispatchEvent(new CustomEvent(`jant:settings-save`,{bubbles:!0,detail:{endpoint:`/settings/general`,data:{siteName:this._siteName,siteDescription:this._siteDescription,siteFooter:this._siteFooter},section:`site`}})))}_syncLocaleDirty(){this._localeDirty=this._siteLanguage!==this._origLocale.siteLanguage||this._cjkSerifFont!==this._origLocale.cjkSerifFont||this._timeZone!==this._origLocale.timeZone}_saveLocale(){this._localeLoading||!this._localeDirty||(this._localeLoading=!0,this.dispatchEvent(new CustomEvent(`jant:settings-save`,{bubbles:!0,detail:{endpoint:`/settings/general/language-time`,data:{siteLanguage:this._siteLanguage,cjkSerifFont:this._cjkSerifFont,timeZone:this._timeZone},section:`language-time`}})))}_filteredLocaleEntries(){let e=gz(),t=this._localeQuery.trim().toLowerCase();return t?e.filter(e=>e.tag.toLowerCase().includes(t)||e.native.toLowerCase().includes(t)||e.english.toLowerCase().includes(t)):e}_toggleLocalePicker=()=>{this._localeOpen=!this._localeOpen,this._localeOpen?this.updateComplete.then(()=>{this.querySelector(`[data-locale-search]`)?.focus()}):this._localeQuery=``};_selectLocale(e){this._siteLanguage=e,this._localeOpen=!1,this._localeQuery=``,this._syncLocaleDirty()}_onLocalePickerDocumentClick=e=>{if(!this._localeOpen)return;let t=e.target,n=this.querySelector(`[data-locale-picker]`);n&&t&&!n.contains(t)&&(this._localeOpen=!1)};_onLocalePickerKeydown=e=>{e.key===`Escape`&&this._localeOpen&&(this._localeOpen=!1,this._localeQuery=``)};_renderLanguagePicker(){let e=_z(this._siteLanguage||`en`),t=this._filteredLocaleEntries(),n=this.labels.siteLanguageSearchPlaceholder||`Search…`,r=this.labels.siteLanguageNoMatches||`No matches.`;return u`
|
|
2166
|
+
`+this._getInvalidityExplanation().join(``));if(this._executed)throw Error(`Conversion cannot be executed twice.`);if(this._executed=!0,this.onProgress){let e=this.utilizedTracks.map(e=>e.computeDuration()),t=Math.max(0,...await Promise.all(e));this._computeProgress=!0,this._totalDuration=Math.min(t-this._startTimestamp,this._endTimestamp-this._startTimestamp);for(let e of this.utilizedTracks)this._maxTimestamps.set(e.id,0);this.onProgress?.(0)}await this.output.start(),this._start();try{await Promise.all(this._trackPromises)}catch(e){throw this._canceled||this.cancel(),e}if(this._canceled)throw new VL;await this.output.finalize(),this._computeProgress&&this.onProgress?.(1)}async cancel(){if(!(this.output.state===`finalizing`||this.output.state===`finalized`)){if(this._canceled){console.warn(`Conversion already canceled.`);return}this._canceled=!0,await this.output.cancel()}}async _processVideoTrack(e,t){let n=e.codec;if(!n){this.discardedTracks.push({track:e,reason:`unknown_source_codec`});return}let r,i=LO(e.rotation+(t.rotate??0)),a=i,o=this.output.format.supportsVideoRotationMetadata&&(t.allowRotationMetadata??!0),[s,c]=i%180==0?[e.squarePixelWidth,e.squarePixelHeight]:[e.squarePixelHeight,e.squarePixelWidth],l=t.crop;l&&Zj(l,s,c);let[u,d]=l?[l.width,l.height]:[s,c],f=u,p=d,m=f/p,h=e=>Math.ceil(e/2)*2;t.width!==void 0&&t.height===void 0?(f=h(t.width),p=h(Math.round(f/m))):t.width===void 0&&t.height!==void 0?(p=h(t.height),f=h(Math.round(p*m))):t.width!==void 0&&t.height!==void 0&&(f=h(t.width),p=h(t.height));let g=await e.getFirstTimestamp(),_=this.output.format.getSupportedVideoCodecs(),v=!!t.forceTranscode||g<this._startTimestamp||!!t.frameRate||t.keyFrameInterval!==void 0||t.process!==void 0||t.bitrate!==void 0||!_.includes(n)||t.codec&&t.codec!==n||f!==u||p!==d||i!==0&&!o||!!l,y=t.alpha??`discard`;if(v){if(!await e.canDecode()){this.discardedTracks.push({track:e,reason:`undecodable_source_codec`});return}t.codec&&(_=_.filter(e=>e===t.codec));let n=t.bitrate??_L,s=await xL(_,{width:t.process&&t.processedWidth?t.processedWidth:f,height:t.process&&t.processedHeight?t.processedHeight:p,bitrate:n});if(!s){this.discardedTracks.push({track:e,reason:`no_encodable_target_codec`});return}let c={codec:s,bitrate:n,keyFrameInterval:t.keyFrameInterval,sizeChangeBehavior:t.fit??`passThrough`,alpha:y,hardwareAcceleration:t.hardwareAcceleration},m=new DL(c);r=m;let h=f!==u||p!==d||i!==0&&(!o||t.process!==void 0)||!!l||e.squarePixelWidth!==e.codedWidth||e.squarePixelHeight!==e.codedHeight;if(!h){let t=new FL({format:new cL,target:new eL}),n=new DL(c);t.addVideoTrack(n),await t.start();let r=await new yM(e).getSample(g);if(r)try{await n.add(r),r.close(),await t.finalize()}catch(e){console.info(`Error when probing encoder support. Falling back to rerender path.`,e),h=!0,t.cancel()}else await t.cancel()}h?this._trackPromises.push((async()=>{await this._started;let n=new bM(e,{width:f,height:p,fit:t.fit??`fill`,rotation:i,crop:t.crop,poolSize:1,alpha:y===`keep`}).canvases(this._startTimestamp,this._endTimestamp),r=t.frameRate;a=0;let o=null,s=null,c=null,l=async n=>{U(o),U(r!==void 0);let i=Math.round((n-s)*r);for(let n=1;n<i;n++){let i=new Jj(o,{timestamp:s+n/r,duration:1/r});await this._registerVideoSample(e,t,m,i),i.close()}};for await(let{canvas:i,timestamp:a,duration:u}of n){if(this._canceled)return;let n=Math.max(a-this._startTimestamp,0);if(c=n+u,r!==void 0){let e=Math.floor(n*r)/r;if(o!==null)if(e<=s){o=i,s=e;continue}else await l(e);n=e}let d=new Jj(i,{timestamp:n,duration:r===void 0?u:1/r});await this._registerVideoSample(e,t,m,d),d.close(),r!==void 0&&(o=i,s=n)}o&&(U(c!==null),U(r!==void 0),await l(Math.floor(c*r)/r)),m.close(),this._synchronizer.closeTrack(e.id)})()):this._trackPromises.push((async()=>{await this._started;let n=new yM(e),r=t.frameRate,i=null,a=null,o=null,s=async n=>{U(i),U(r!==void 0);let o=Math.round((n-a)*r);for(let n=1;n<o;n++)i.setTimestamp(a+n/r),i.setDuration(1/r),await this._registerVideoSample(e,t,m,i);i.close()};for await(let c of n.samples(this._startTimestamp,this._endTimestamp)){if(this._canceled){c.close(),i?.close();return}let n=Math.max(c.timestamp-this._startTimestamp,0);if(o=n+c.duration,r!==void 0){let e=Math.floor(n*r)/r;if(i!==null)if(e<=a){i.close(),i=c,a=e;continue}else await s(e);n=e,c.setDuration(1/r)}c.setTimestamp(n),await this._registerVideoSample(e,t,m,c),r===void 0?c.close():(i=c,a=n)}i&&(U(o!==null),U(r!==void 0),await s(Math.floor(o*r)/r)),m.close(),this._synchronizer.closeTrack(e.id)})())}else{let t=new wL(n);r=t,this._trackPromises.push((async()=>{await this._started;let n=new pM(e),r={decoderConfig:await e.getDecoderConfig()??void 0},i=Number.isFinite(this._endTimestamp)?await n.getPacket(this._endTimestamp,{metadataOnly:!0})??void 0:void 0;for await(let a of n.packets(void 0,i,{verifyKeyPackets:!0})){if(this._canceled)return;let n=a.clone({timestamp:a.timestamp-this._startTimestamp,sideData:y===`discard`?{}:a.sideData});U(n.timestamp>=0),this._reportProgress(e.id,n.timestamp),await t.add(n,r),this._synchronizer.shouldWait(e.id,n.timestamp)&&await this._synchronizer.wait(n.timestamp)}t.close(),this._synchronizer.closeTrack(e.id)})())}this.output.addVideoTrack(r,{frameRate:t.frameRate,languageCode:Ck(e.languageCode)?e.languageCode:void 0,name:e.name??void 0,disposition:e.disposition,rotation:a}),this._addedCounts.video++,this._totalTrackCount++,this.utilizedTracks.push(e)}async _registerVideoSample(e,t,n,r){if(this._canceled)return;this._reportProgress(e.id,r.timestamp);let i;if(!t.process)i=[r];else{let e=t.process(r);e instanceof Promise&&(e=await e),Array.isArray(e)||(e=e===null?[]:[e]),i=e.map(e=>e instanceof Jj?e:typeof VideoFrame<`u`&&e instanceof VideoFrame?new Jj(e):new Jj(e,{timestamp:r.timestamp,duration:r.duration}))}for(let t of i){if(this._canceled)break;await n.add(t),this._synchronizer.shouldWait(e.id,t.timestamp)&&await this._synchronizer.wait(t.timestamp)}for(let e of i)e!==r&&e.close()}async _processAudioTrack(e,t){let n=e.codec;if(!n){this.discardedTracks.push({track:e,reason:`unknown_source_codec`});return}let r,i=e.numberOfChannels,a=e.sampleRate,o=await e.getFirstTimestamp(),s=t.numberOfChannels??i,c=t.sampleRate??a,l=s!==i||c!==a||o<this._startTimestamp||o>this._startTimestamp&&!this.output.format.supportsTimestampedMediaData,u=this.output.format.getSupportedAudioCodecs();if(!t.forceTranscode&&!t.bitrate&&!l&&u.includes(n)&&(!t.codec||t.codec===n)&&!t.process){let t=new kL(n);r=t,this._trackPromises.push((async()=>{await this._started;let n=new pM(e),r={decoderConfig:await e.getDecoderConfig()??void 0},i=Number.isFinite(this._endTimestamp)?await n.getPacket(this._endTimestamp,{metadataOnly:!0})??void 0:void 0;for await(let a of n.packets(void 0,i)){if(this._canceled)return;let n=a.clone({timestamp:a.timestamp-this._startTimestamp});U(n.timestamp>=0),this._reportProgress(e.id,n.timestamp),await t.add(n,r),this._synchronizer.shouldWait(e.id,n.timestamp)&&await this._synchronizer.wait(n.timestamp)}t.close(),this._synchronizer.closeTrack(e.id)})())}else{if(!await e.canDecode()){this.discardedTracks.push({track:e,reason:`undecodable_source_codec`});return}let n=null;t.codec&&(u=u.filter(e=>e===t.codec));let i=t.bitrate??_L,a=await bL(u,{numberOfChannels:t.process&&t.processedNumberOfChannels?t.processedNumberOfChannels:s,sampleRate:t.process&&t.processedSampleRate?t.processedSampleRate:c,bitrate:i});if(!a.some(e=>tA.includes(e))&&u.some(e=>tA.includes(e))&&(s!==RL||c!==zL)){let e=(await bL(u,{numberOfChannels:RL,sampleRate:zL,bitrate:i})).find(e=>tA.includes(e));e&&(l=!0,n=e,s=RL,c=zL)}else n=a[0]??null;if(n===null){this.discardedTracks.push({track:e,reason:`no_encodable_target_codec`});return}if(l)r=this._resampleAudio(e,t,n,s,c,i);else{let a=new jL({codec:n,bitrate:i});r=a,this._trackPromises.push((async()=>{await this._started;let n=new CM(e);for await(let r of n.samples(void 0,this._endTimestamp)){if(this._canceled){r.close();return}r.setTimestamp(r.timestamp-this._startTimestamp),await this._registerAudioSample(e,t,a,r),r.close()}a.close(),this._synchronizer.closeTrack(e.id)})())}}this.output.addAudioTrack(r,{languageCode:Ck(e.languageCode)?e.languageCode:void 0,name:e.name??void 0,disposition:e.disposition}),this._addedCounts.audio++,this._totalTrackCount++,this.utilizedTracks.push(e)}async _registerAudioSample(e,t,n,r){if(this._canceled)return;this._reportProgress(e.id,r.timestamp);let i;if(!t.process)i=[r];else{let e=t.process(r);if(e instanceof Promise&&(e=await e),Array.isArray(e)||(e=e===null?[]:[e]),!e.every(e=>e instanceof rM))throw TypeError(`The audio process function must return an AudioSample, null, or an array of AudioSamples.`);i=e}for(let t of i){if(this._canceled)break;await n.add(t),this._synchronizer.shouldWait(e.id,t.timestamp)&&await this._synchronizer.wait(t.timestamp)}for(let e of i)e!==r&&e.close()}_resampleAudio(e,t,n,r,i,a){let o=new jL({codec:n,bitrate:a});return this._trackPromises.push((async()=>{await this._started;let n=new WL({targetNumberOfChannels:r,targetSampleRate:i,startTime:this._startTimestamp,endTime:this._endTimestamp,onSample:async n=>{await this._registerAudioSample(e,t,o,n),n.close()}}),a=new CM(e).samples(this._startTimestamp,this._endTimestamp);for await(let e of a){if(this._canceled){e.close();return}await n.add(e),e.close()}await n.finalize(),o.close(),this._synchronizer.closeTrack(e.id)})()),o}_reportProgress(e,t){if(!this._computeProgress)return;U(this._totalDuration!==null),this._maxTimestamps.set(e,Math.max(t,this._maxTimestamps.get(e)));let n=_k(Math.min(...this._maxTimestamps.values())/this._totalDuration,0,1);n!==this._lastProgress&&(this._lastProgress=n,this.onProgress?.(n))}},VL=class extends Error{constructor(e=`Conversion has been canceled.`){super(e),this.name=`ConversionCanceledError`}},HL=5,UL=class{constructor(){this.maxTimestamps=new Map,this.resolvers=[]}computeMinAndMaybeResolve(){let e=1/0;for(let[,t]of this.maxTimestamps)e=Math.min(e,t);for(let t=0;t<this.resolvers.length;t++){let n=this.resolvers[t];n.timestamp-e<HL&&(n.resolve(),this.resolvers.splice(t,1),t--)}return e}shouldWait(e,t){return this.maxTimestamps.set(e,Math.max(t,this.maxTimestamps.get(e)??-1/0)),t-this.computeMinAndMaybeResolve()>=HL}wait(e){let{promise:t,resolve:n}=ok();return this.resolvers.push({timestamp:e,resolve:n}),t}closeTrack(e){this.maxTimestamps.delete(e),this.computeMinAndMaybeResolve()}},WL=class{constructor(e){this.sourceSampleRate=null,this.sourceNumberOfChannels=null,this.targetSampleRate=e.targetSampleRate,this.targetNumberOfChannels=e.targetNumberOfChannels,this.startTime=e.startTime,this.endTime=e.endTime,this.onSample=e.onSample,this.bufferSizeInFrames=Math.floor(this.targetSampleRate*5),this.bufferSizeInSamples=this.bufferSizeInFrames*this.targetNumberOfChannels,this.outputBuffer=new Float32Array(this.bufferSizeInSamples),this.bufferStartFrame=0,this.maxWrittenFrame=-1}doChannelMixerSetup(){U(this.sourceNumberOfChannels!==null);let e=this.sourceNumberOfChannels,t=this.targetNumberOfChannels;e===1&&t===2?this.channelMixer=(t,n)=>t[n*e]:e===1&&t===4?this.channelMixer=(t,n,r)=>t[n*e]*+(r<2):e===1&&t===6?this.channelMixer=(t,n,r)=>t[n*e]*+(r===2):e===2&&t===1?this.channelMixer=(t,n)=>{let r=n*e;return .5*(t[r]+t[r+1])}:e===2&&t===4||e===2&&t===6?this.channelMixer=(t,n,r)=>t[n*e+r]*+(r<2):e===4&&t===1?this.channelMixer=(t,n)=>{let r=n*e;return .25*(t[r]+t[r+1]+t[r+2]+t[r+3])}:e===4&&t===2?this.channelMixer=(t,n,r)=>{let i=n*e;return .5*(t[i+r]+t[i+r+2])}:e===4&&t===6?this.channelMixer=(t,n,r)=>{let i=n*e;return r<2?t[i+r]:r===2||r===3?0:t[i+r-2]}:e===6&&t===1?this.channelMixer=(t,n)=>{let r=n*e;return Math.SQRT1_2*(t[r]+t[r+1])+t[r+2]+.5*(t[r+4]+t[r+5])}:e===6&&t===2?this.channelMixer=(t,n,r)=>{let i=n*e;return t[i+r]+Math.SQRT1_2*(t[i+2]+t[i+r+4])}:e===6&&t===4?this.channelMixer=(t,n,r)=>{let i=n*e;return r<2?t[i+r]+Math.SQRT1_2*t[i+2]:t[i+r+2]}:this.channelMixer=(t,n,r)=>r<e?t[n*e+r]:0}ensureTempBufferSize(e){let t=this.tempSourceBuffer.length;for(;t<e;)t*=2;if(t!==this.tempSourceBuffer.length){let e=new Float32Array(t);e.set(this.tempSourceBuffer),this.tempSourceBuffer=e}}async add(e){this.sourceSampleRate===null&&(this.sourceSampleRate=e.sampleRate,this.sourceNumberOfChannels=e.numberOfChannels,this.tempSourceBuffer=new Float32Array(this.sourceSampleRate*this.sourceNumberOfChannels),this.doChannelMixerSetup());let t=e.numberOfFrames*e.numberOfChannels;this.ensureTempBufferSize(t);let n=e.allocationSize({planeIndex:0,format:`f32`}),r=new Float32Array(this.tempSourceBuffer.buffer,0,n/4);e.copyTo(r,{planeIndex:0,format:`f32`});let i=e.timestamp-this.startTime,a=e.numberOfFrames/this.sourceSampleRate,o=Math.min(i+a,this.endTime-this.startTime),s=Math.floor(i*this.targetSampleRate),c=Math.ceil(o*this.targetSampleRate);for(let t=s;t<c;t++){if(t<this.bufferStartFrame)continue;for(;t>=this.bufferStartFrame+this.bufferSizeInFrames;)await this.finalizeCurrentBuffer(),this.bufferStartFrame+=this.bufferSizeInFrames;let n=t-this.bufferStartFrame;U(n<this.bufferSizeInFrames);let a=(t/this.targetSampleRate-i)*this.sourceSampleRate,o=Math.floor(a),s=Math.ceil(a),c=a-o;for(let t=0;t<this.targetNumberOfChannels;t++){let i=0,a=0;o>=0&&o<e.numberOfFrames&&(i=this.channelMixer(r,o,t)),s>=0&&s<e.numberOfFrames&&(a=this.channelMixer(r,s,t));let l=i+c*(a-i),u=n*this.targetNumberOfChannels+t;this.outputBuffer[u]+=l}this.maxWrittenFrame=Math.max(this.maxWrittenFrame,n)}}async finalizeCurrentBuffer(){if(this.maxWrittenFrame<0)return;let e=(this.maxWrittenFrame+1)*this.targetNumberOfChannels,t=new Float32Array(e);t.set(this.outputBuffer.subarray(0,e));let n=this.bufferStartFrame/this.targetSampleRate,r=new rM({format:`f32`,sampleRate:this.targetSampleRate,numberOfChannels:this.targetNumberOfChannels,timestamp:n,data:t});await this.onSample(r),this.outputBuffer.fill(0),this.maxWrittenFrame=-1}finalize(){return this.finalizeCurrentBuffer()}};function GL(){return typeof AudioEncoder<`u`}async function KL(e,t){let n=new MP({source:new OP(e),formats:EP}),r=new $I,i=new FL({format:new cL({fastStart:`in-memory`}),target:r});try{let a=await BL.init({input:n,output:i,video:{discard:!0},audio:{codec:`aac`,bitrate:_L}});t&&(a.onProgress=t),await a.execute();let o=r.buffer;if(!o)throw Error(`Audio processing produced no output`);let s=e.name.replace(/\.[^.]+$/,``);return{file:new File([o],`${s}.m4a`,{type:`audio/mp4`})}}finally{n.dispose()}}var qL={isSupported:GL,processToFile:KL},JL=1920,YL=1080,XL=640,ZL=32;function QL(){return typeof VideoEncoder<`u`}async function $L(e){let t=new MP({source:new OP(e),formats:EP});try{let e=await t.getPrimaryVideoTrack();if(!e)return{};let n=e.displayWidth,r=e.displayHeight,i=e.rotation,a=await t.computeDuration(),o=s(a),c=Math.min(a*.1,3),l=await new bM(e).getCanvas(c);if(!l)return{sourceWidth:n,sourceHeight:r,rotation:i,durationSeconds:o};let u=l.canvas,d=u.width,f=u.height,p=Math.min(XL/d,1),m=Math.round(d*p),h=Math.round(f*p),g=document.createElement(`canvas`);g.width=m,g.height=h;let _=g.getContext(`2d`);if(!_)return{sourceWidth:n,sourceHeight:r};_.drawImage(u,0,0,m,h);let v=await new Promise(e=>{g.toBlob(t=>e(t??void 0),`image/webp`,.8)}),y=Math.min(ZL/d,ZL/f,1),b=Math.max(Math.round(d*y),1),x=Math.max(Math.round(f*y),1),S=document.createElement(`canvas`);S.width=b,S.height=x;let C=S.getContext(`2d`);return C?(C.drawImage(u,0,0,b,x),{poster:v,blurhash:AC(C.getImageData(0,0,b,x).data,b,x,4,3),sourceWidth:n,sourceHeight:r,rotation:i,durationSeconds:o}):{poster:v,sourceWidth:n,sourceHeight:r}}catch{return{}}finally{t.dispose()}}async function eR(e,t){let{poster:n,blurhash:r,sourceWidth:i,sourceHeight:a,rotation:o,durationSeconds:s}=await $L(e),c=i||JL,l=a||YL;if(i&&a){let e=Math.max(i,a),t=Math.min(i,a),n=Math.min(JL/e,YL/t,1);c=Math.round(i*n),l=Math.round(a*n)}c+=c%2,l+=l%2;let u=new MP({source:new OP(e),formats:EP}),d=new $I,f=new FL({format:new cL({fastStart:`in-memory`}),target:d});try{let i=await BL.init({input:u,output:f,video:{codec:`avc`,width:c,height:l,fit:`contain`,bitrate:_L},audio:{codec:`aac`}});t&&(i.onProgress=t),await i.execute();let a=d.buffer;if(!a)throw Error(`Video processing produced no output`);let p=e.name.replace(/\.[^.]+$/,``),m=new File([a],`${p}.mp4`,{type:`video/mp4`}),h=await iR(m),g=Math.abs(h.width-c)<=2&&Math.abs(h.height-l)<=2;return o&&!g&&(rR(a),m=new File([a],`${p}.mp4`,{type:`video/mp4`}),h=await iR(m)),{file:m,width:h.width,height:h.height,durationSeconds:s,poster:n,blurhash:r}}finally{u.dispose()}}var tR=[65536,0,0,0,65536,0,0,0,1073741824];function nR(e,t,n,r){let i=t;for(;i+8<=n;){let t=e.getUint32(i),a=String.fromCharCode(e.getUint8(i+4),e.getUint8(i+5),e.getUint8(i+6),e.getUint8(i+7));if(t===0&&(t=n-i),t<8||i+t>n)break;r(i,t,a),(a===`moov`||a===`trak`||a===`mdia`||a===`edts`)&&nR(e,i+8,i+t,r),i+=t}}function rR(e){let t=new DataView(e);nR(t,0,e.byteLength,(n,r,i)=>{if(i!==`tkhd`)return;let a=n+8,o=a+(t.getUint8(a)===0?40:52);if(o+36>e.byteLength)return;let s=!0;for(let e=0;e<9;e++)if(t.getInt32(o+e*4)!==tR[e]){s=!1;break}if(!s)for(let e=0;e<9;e++)t.setInt32(o+e*4,tR[e])})}function iR(e){return new Promise((t,n)=>{let r=URL.createObjectURL(e),i=document.createElement(`video`);i.preload=`metadata`,i.onloadedmetadata=()=>{URL.revokeObjectURL(r),t({width:i.videoWidth,height:i.videoHeight})},i.onerror=()=>{URL.revokeObjectURL(r),n(Error(`Failed to probe transcoded video dimensions`))},i.src=r})}var aR={isSupported:QL,processToFile:eR};function oR(){return document.querySelector(`jant-compose-dialog`)}function sR(){return document.querySelector(`[data-page='collection'][data-collection-id]`)?.dataset.collectionId||void 0}function cR(e=document){if(e===document){let e=document.querySelector(`[data-page='post'] article[data-post]:hover`);if(e)return e}return e.querySelector(`[data-post-current] article[data-post]`)||e.querySelector(`[data-post-view] article[data-post]`)||(e===document?document.querySelector(`article[data-post]:hover`):null)}function lR(e){let t=e.closest(`[data-post-view]`)?.dataset.postViewId;if(t)return{kind:`post-view`,id:t};let n=e.closest(`[data-timeline-item]`),r=n?.dataset.threadRootId??e.dataset.threadRootId??e.dataset.postId;if(n&&r)return{kind:`timeline-item`,id:r};let i=e.dataset.postId;return i?{kind:`post-card`,id:i}:null}function uR(e){let t=e.cloneNode(!0);t.querySelector(`[data-post-meta]`)?.remove(),t.querySelector(`.post-status-badges`)?.remove();let n=e.querySelector(`time.dt-published`);return{contentHtml:t.innerHTML,dateText:n?.textContent?.trim()??``}}function dR(e){let t=e.dataset.format;if(t===`note`||t===`link`||t===`quote`)return t}async function fR(e){await oR()?.openNew(e)}async function pR(e){let t=e.dataset.postId;if(!t)return;let n=oR();if(!n)return;let r=e.dataset.threadRootId??t,i=dR(e);await n.openReply(t,uR(e),r,lR(e)??void 0,i?{initialFormat:i}:void 0)}function mR(e){return e instanceof globalThis.Element?e.closest(`jant-compose-editor`):null}function hR(e){return e instanceof globalThis.Element?e.closest(`jant-compose-dialog`):null}async function gR(e){let t=await fetch(e,{headers:{Accept:`text/html`}});return t.ok?t.text():null}async function _R(e){try{let t=document.querySelector(`[data-timeline-item][data-thread-root-id="${e}"]`)?.querySelector(`[data-timeline-item-content]`);if(!t)return!1;let n=await gR(`/_/timeline-item/${encodeURIComponent(e)}`);return n?(t.innerHTML=n,y(t),!0):!1}catch{return!1}}async function vR(e){try{let t=document.querySelector(`article[data-post-id="${e}"]`)?.closest(`[data-timeline-item]`),n=await gR(`/_/post-card/${encodeURIComponent(e)}`);if(!n)return!1;if(t){let e=t.querySelector(`[data-timeline-item-content]`);return e?(e.innerHTML=n,y(e),!0):!1}let r=document.querySelector(`article[data-post-id="${e}"]`);if(!r)return!1;r.outerHTML=n;let i=document.querySelector(`article[data-post-id="${e}"]`);return i&&y(i),!0}catch{return!1}}async function yR(e){try{let t=document.querySelector(`[data-post-view][data-post-view-id="${e}"]`);if(!t)return!1;let n=await gR(`/_/post-view/${encodeURIComponent(e)}`);if(!n)return!1;t.outerHTML=n;let r=document.querySelector(`[data-post-view][data-post-view-id="${e}"]`);return r&&y(r),!0}catch{return!1}}async function bR(e){return!e.replyRefreshKind||!e.replyRefreshId?!1:e.replyRefreshKind===`timeline-item`?_R(e.replyThreadRootId??e.replyRefreshId):e.replyRefreshKind===`post-view`?yR(e.replyRefreshId):vR(e.replyRefreshId)}var xR=new Map,SR=new Set,CR=new Map;function wR(e){return new Promise(t=>{let n=setTimeout(()=>{a(),t(null)},3e3),r=URL.createObjectURL(e),i=document.createElement(`video`);i.muted=!0,i.playsInline=!0,i.preload=`auto`;function a(){clearTimeout(n),i.removeAttribute(`src`),i.load(),URL.revokeObjectURL(r)}i.onloadeddata=()=>{try{let e=i.videoWidth,n=i.videoHeight;if(!e||!n){a(),t(null);return}let r=Math.min(640/e,1),o=Math.round(e*r),s=Math.round(n*r),c=document.createElement(`canvas`);c.width=o,c.height=s;let l=c.getContext(`2d`);if(!l){a(),t(null);return}l.drawImage(i,0,0,o,s),c.toBlob(e=>{a(),t(e)},`image/webp`,.6)}catch{a(),t(null)}},i.onerror=()=>{a(),t(null)},i.src=r})}async function TR(e,t,n){try{let r,i,o,s,c,l,u;if(e.type.startsWith(`video/`)){if(!aR.isSupported())return n?.updateAttachmentStatus(t,`error`,null,`Your browser doesn't support video processing. Use Chrome or Edge to upload videos.`),null;wR(e).then(e=>{e&&n?.updateAttachmentPoster(t,e)}),n?.updateAttachmentStatus(t,`processing`,null,null);let a=await aR.processToFile(e,e=>{n?.updateAttachmentProgress(t,e)});r=a.file,i=a.width,o=a.height,s=a.durationSeconds,c=a.blurhash,u=a.poster,u&&n?.updateAttachmentPoster(t,u)}else if(e.type.startsWith(`audio/`)){if(!qL.isSupported())return n?.updateAttachmentStatus(t,`error`,null,`Your browser doesn't support audio processing. Use Chrome or Edge to upload audio.`),null;try{l=await NC(e)}catch{}n?.updateAttachmentStatus(t,`processing`,null,null),r=(await qL.processToFile(e,e=>{n?.updateAttachmentProgress(t,e)})).file}else if(e.type.startsWith(`image/`)||/\.heic$/i.test(e.name)||/\.heif$/i.test(e.name)){let s=e;try{let{isHeic:a,heicTo:c}=await kO(async()=>{let{isHeic:e,heicTo:t}=await import(`./chunks/heic-to-DUUaO23q.js`);return{isHeic:e,heicTo:t}},[]);if(await a(e)){n?.updateAttachmentStatus(t,`processing`,null,null);let r=await c({blob:e,type:`image/jpeg`,quality:.92});s=new File([r],e.name.replace(/\.heic$/i,`.jpg`),{type:`image/jpeg`}),n?.updateAttachmentPreview(t,s)}let l=await re.processToFile(s);r=l.file,i=l.width,o=l.height}catch{return n?.removeAttachment(t),a(`Image format not supported.`,`error`),null}}else r=e;if(n?.updateAttachmentStatus(t,`uploading`,null,null),!e.type.startsWith(`video/`)){let e=await PC(r);i??=e.width,o??=e.height,c??=e.blurhash,l??=e.waveform,!u&&e.poster&&(u=e.poster,n?.updateAttachmentPoster(t,u))}let d,f;if(sS(e.type)===`text`)try{let e=await r.text(),t=e.replace(/\s+/g,` `).trim();f=e.length,d=t.length<=100?t:t.slice(0,100)+`…`}catch{}let p=await GC(r,{width:i,height:o,durationSeconds:s,blurhash:c,waveform:l,poster:u,summary:d,chars:f},e=>{n?.updateAttachmentProgress(t,e)});return n?.updateAttachmentStatus(t,`done`,p.id,null),CR.set(t,p.id),p.id}catch(e){let r=e instanceof Error?e.message:`Upload failed`;return n?.updateAttachmentStatus(t,`error`,null,r),n||a(r,`error`),null}}document.addEventListener(`jant:attachment-removed`,e=>{let{clientId:t,mediaId:n}=e.detail;CR.delete(t),n?fetch(`/api/upload/${n}`,{method:`DELETE`}).catch(()=>{}):SR.add(t)}),document.addEventListener(`jant:files-selected`,e=>{let t=e,n=mR(t.target);for(let{file:e,clientId:r}of t.detail.files){let t=TR(e,r,n).then(e=>SR.has(r)?(SR.delete(r),e&&fetch(`/api/upload/${e}`,{method:`DELETE`}).catch(()=>{}),null):e);xR.set(r,t),t.finally(()=>xR.delete(r))}}),document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-reply-trigger]`);if(!t)return;let n=t.closest(`article[data-post]`);n&&pR(n)});function ER(e,t){let n=e.format===`quote`,r=e.format===`link`,i=!!e.editPostId,a=e=>e||void 0,o=e=>e||null;return{format:e.format,title:n?void 0:i?o(e.title):a(e.title),body:i?o(e.body):a(e.body),url:r?i?o(e.url):a(e.url):i?null:void 0,sourceName:n?i?o(e.quoteAuthor):a(e.quoteAuthor):void 0,sourceUrl:n?i?o(e.url):a(e.url):void 0,quoteText:n?i?o(e.quoteText):a(e.quoteText):i?null:void 0,slug:e.slug||void 0,status:e.status,publishedAt:e.status===`published`?e.publishedAt:void 0,visibility:e.visibility||void 0,rating:i?e.rating>0?e.rating:null:e.rating||void 0,collectionIds:e.collectionIds,attachments:t.length>0?t:void 0,replyToId:e.replyToId||void 0,quietReply:e.quietReply||void 0}}function DR(e){return JSON.stringify(e.bodyJson)!==JSON.stringify(e.originalBodyJson??null)}function OR(e,t){let n=[];for(let r of e.attachments){if(r.type===`media`){let e=r.mediaId??t.get(r.clientId)??CR.get(r.clientId);if(!e)continue;n.push({type:`media`,mediaId:e,alt:r.alt});continue}if(r.mediaId&&!DR(r)){n.push({type:`media`,mediaId:r.mediaId});continue}n.push({type:`text`,contentFormat:`markdown`,content:AT(JSON.stringify(r.bodyJson)),summary:r.summary})}return n}document.addEventListener(`jant:compose-submit-deferred`,async e=>{let t=e,n=t.detail,r=hR(t.target)??document.querySelector(`jant-compose-dialog`),o=!!r?.pageMode,s=r?.labels,c=s?.uploading??`Uploading...`,l=n.threadPosts?n.threadPosts.some(e=>e.body.includes(`"blob:`)):n.body.includes(`"blob:`),u=n.pendingAttachments.length>0||l,f=s?.published??`Published!`,p=s?.view??`View`;u&&d(`compose-deferred`,c);let h=(e,t=`success`)=>{u?_(`compose-deferred`,e,t):a(e,t)},g=()=>{!o||!r||(r.reset(),r.updateComplete.then(()=>{r.querySelector(`jant-compose-editor`)?.focusInput()}))},v=()=>{!o||!r||(r.loading=!1)},y=()=>{if(te){n.editPostId&&r?.clearEditDraftFromStorage?.(n.editPostId);return}r?.clearLocalDraftFromStorage?.()},b=async()=>{if(!(!r||o)){if(te&&n.editPostId){if(typeof r.openEdit!=`function`)return;await r.openEdit(n.editPostId);return}if(n.replyToId){if(typeof r.openReply!=`function`)return;await r.openReply(n.replyToId,void 0,n.replyThreadRootId,n.replyRefreshKind&&n.replyRefreshId?{kind:n.replyRefreshKind,id:n.replyRefreshId}:void 0,{restoreDraft:!0,initialFormat:n.format});return}typeof r.openNew==`function`&&await r.openNew({restoreDraft:!0})}},x=async e=>{v(),await b(),h(e,`error`)},S=async()=>{await r?.refreshCollections()},C=(e,t)=>{m(e,`success`,t)},ee=()=>!o||!r||!r.consumePageLeaveRequest()?!1:(r.preparePageLeave(),globalThis.location.assign(r.closeHref||i(`/`)),!0),te=!!n.editPostId,ne=!!(n.threadPosts&&n.threadPosts.length>=2),re=null;try{let e=n.pendingAttachments.map(e=>e.clientId),t=e.map(e=>xR.get(e)??Promise.resolve(null)),a=await Promise.all(t);if(a.filter((t,n)=>t===null&&!CR.has(e[n]??``)).length>0)if(n.status===`published`&&!te)re=`upload`;else{await x(`Upload failed. Post not created.`);return}let c=new Map;for(let t=0;t<e.length;t++){let n=e[t],r=a[t];n&&r&&c.set(n,r)}if(ne&&n.threadPosts){let e=n.threadPosts,t=re?`draft`:n.status,i=(await Promise.all(e.map(async e=>{let n=e.body;if(n.includes(`"blob:`))try{let e=await $C(JSON.parse(n));n=e?JSON.stringify(e):``}catch{}return{...e,body:n,status:t}}))).map(e=>ER(e,OR(e,c))),a={posts:i};te&&n.editPostId&&(a.replaceThreadId=n.editPostId);let l=await fetch(`/compose/thread`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(a)});if(!l.ok){if(n.status===`published`&&!re){let e={posts:i.map(e=>({...e,status:`draft`}))};if((await fetch(`/compose/thread`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)})).ok){re=`server`,y();let e=s?.publishFailedDraft??`Couldn't publish. Saved as draft.`;await S(),ee()||g(),h(e);return}}await x(w(await le(l),`error`)??`Something went wrong`);return}if(re===`upload`){y();let e=s?.uploadFailedDraft??`Some uploads failed. Saved as draft.`;await S(),g(),h(e);return}let u=await le(l),d=w(u,`status`),m=w(u,`permalink`),_=w(u,`toast`);d===`published`?(y(),o?(await S(),g(),h(f)):(C(f,m?{label:p,href:m}:void 0),globalThis.location.reload())):(y(),await S(),ee()||g(),h(_??`Draft saved.`),kR(r,`draft`));return}let u=OR(n,c);if(l)try{let e=await $C(JSON.parse(n.body));n.body=e?JSON.stringify(e):``}catch{}let d=te?`/api/posts/${n.editPostId}`:`/compose`,m=te?`PUT`:`POST`,_=ER({...n,status:re?`draft`:n.status},u),v=await fetch(d,{method:m,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(_)});if(!v.ok){if(n.status===`published`&&!te&&!re){let e={..._,status:`draft`},t=await fetch(d,{method:m,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)});if(t.ok){re=`server`,y();let e=await le(t),n=s?.publishFailedDraft??`Couldn't publish. Saved as draft.`;await S(),ee()||g(),h(n);let r=w(e,`toast`);r&&h(r);return}}await x(w(await le(v),`error`)??`Something went wrong`);return}if(te){y();let e=await le(v),t=n.editPostId??``,r=w(e,`slug`),a=r?i(`/${r}`):null;if(o)a&&a!==globalThis.location.pathname?(C(`Post updated.`),globalThis.location.assign(a)):t&&await yR(t)?h(`Post updated.`):(C(`Post updated.`),globalThis.location.assign(globalThis.location.pathname));else if(t)if(document.querySelector(`[data-post-view][data-post-view-id="${t}"]`)){if(a&&a!==globalThis.location.pathname){C(`Post updated.`),globalThis.location.assign(a);return}await yR(t)?h(`Post updated.`):(C(`Post updated.`),globalThis.location.reload())}else{let e=document.querySelector(`article[data-post-id="${t}"]`)?.closest(`[data-timeline-item]`)?.dataset.threadRootId;(e?await _R(e):await vR(t))?h(`Post updated.`):(C(`Post updated.`),globalThis.location.reload())}else C(`Post updated.`),globalThis.location.reload();return}if(re===`upload`){y();let e=s?.uploadFailedDraft??`Some uploads failed. Saved as draft.`;await S(),g(),h(e);return}let b=await le(v),ie=w(b,`status`),ae=w(b,`permalink`),oe=w(b,`toast`);if(ie===`published`){if(y(),o)await S(),g(),h(f);else if(n.replyToId){if(await S(),!await bR(n)){C(f,ae?{label:p,href:ae}:void 0),globalThis.location.reload();return}h(f)}else C(f,ae?{label:p,href:ae}:void 0),globalThis.location.reload();return}else y(),await S(),ee()||g(),h(oe??`Draft saved.`),kR(r,`draft`)}catch{await x(`Something went wrong`)}});function kR(e,t){(e??document).dispatchEvent(new CustomEvent(`jant:compose-submit-complete`,{bubbles:!0,detail:{status:t}}))}var AR=`.compose-prompt`,jR=`.compose-prompt-trigger`,MR=`jant.composeOpenShortcutDiscovery`,NR=`/api/settings/discovery/compose-open-shortcut`,PR=350,FR=1800,IR=3,LR=`compose-prompt-discovery-visible`,RR=!1,zR=null,BR=null,VR=null;function HR(){try{return globalThis.localStorage!==void 0}catch{return!1}}function UR(){if(!HR())return{shownCount:0,completed:!1};let e=globalThis.localStorage.getItem(MR);if(!e)return{shownCount:0,completed:!1};try{let t=JSON.parse(e);return{shownCount:typeof t.shownCount==`number`&&t.shownCount>=0?t.shownCount:0,completed:t.completed===!0}}catch{return globalThis.localStorage.removeItem(MR),{shownCount:0,completed:!1}}}function WR(e){if(HR())try{globalThis.localStorage.setItem(MR,JSON.stringify(e))}catch{}}function GR(){zR!==null&&(clearTimeout(zR),zR=null)}function KR(){BR!==null&&(clearTimeout(BR),BR=null)}function qR(){return typeof globalThis.matchMedia==`function`&&globalThis.matchMedia(`(min-width: 700px)`).matches}function JR(e){return UR().completed?!0:e?.dataset.composeOpenShortcutDiscovered===`true`}function YR(e){e&&(e.dataset.composeOpenShortcutDiscovered=`true`,e.classList.remove(LR)),document.querySelectorAll(AR).forEach(e=>{e.dataset.composeOpenShortcutDiscovered=`true`,e.classList.remove(LR)})}function XR(){let e=UR();e.completed||RR||e.shownCount>=IR||(RR=!0,WR({...e,shownCount:e.shownCount+1}))}function ZR(e){return!qR()||JR(e)?!1:UR().shownCount<IR||RR}function QR(e){GR(),KR(),e?e.classList.remove(LR):VR&&VR.classList.remove(LR),(!e||e===VR)&&(VR=null)}function $R(e){ZR(e)&&(QR(VR),VR=e,e.classList.add(LR),XR(),BR=setTimeout(()=>{QR(e)},FR))}function ez(e){ZR(e)&&(e.classList.contains(LR)||(GR(),zR=setTimeout(()=>{$R(e)},PR)))}function tz(e){if(e.dataset.composeOpenShortcutDiscoveryBound===`true`)return;let t=e.querySelector(jR);t&&(e.dataset.composeOpenShortcutDiscoveryBound=`true`,t.addEventListener(`pointerenter`,()=>{ez(e)}),t.addEventListener(`pointerleave`,()=>{QR(e)}),t.addEventListener(`focusin`,()=>{ez(e)}),t.addEventListener(`focusout`,()=>{QR(e)}))}function nz(e=document){e.querySelectorAll(AR).forEach(e=>tz(e))}function rz(){let e=UR();e.completed||WR({shownCount:Math.max(e.shownCount,IR),completed:!0}),YR(VR),QR(VR),typeof globalThis.fetch==`function`&&globalThis.fetch(NR,{method:`POST`,headers:{Accept:`application/json`},credentials:`same-origin`}).catch(()=>{})}document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,()=>{nz()}):nz();var iz=[`input`,`textarea`,`select`,`button`,`a[href]`,`[contenteditable='']`,`[contenteditable='true']`,`[role='textbox']`,`.ProseMirror`].join(`, `);function az(e){return e instanceof globalThis.Element&&e.closest(iz)!==null}function oz(e){if(e.defaultPrevented||e.isComposing||e.repeat||e.metaKey||e.ctrlKey||e.altKey||!oR()||document.querySelector(`[data-page="compose"]`)||document.querySelector(`dialog[open]`))return!0;let t=document.activeElement;return az(e.target)||t!==e.target&&az(t)}async function sz(e,t,n){try{if(!(await fetch(`/api/posts/${e}`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({featured:t})})).ok)throw Error();t?n.setAttribute(`data-post-featured`,``):n.removeAttribute(`data-post-featured`),a(t?`Added to Featured.`:`Removed from Featured.`)}catch{a(`Could not update post. Try again.`,`error`)}}document.addEventListener(`keydown`,e=>{let t=e.key.toLowerCase();if(t!==`n`&&t!==`l`&&t!==`q`&&t!==`r`&&t!==`e`&&t!==`c`&&t!==`f`||oz(e))return;if(t===`n`||t===`l`||t===`q`){e.preventDefault(),rz();let n=sR(),r=t===`l`?`link`:t===`q`?`quote`:void 0;fR({...n?{collectionId:n}:void 0,...r?{initialFormat:r}:void 0});return}let n=cR();if(n){if(t===`r`){e.preventDefault(),pR(n);return}if(t===`e`){let t=n.dataset.postId;if(!t)return;e.preventDefault();let r=oR();r&&r.openEdit(t);return}if(t===`c`){e.preventDefault();let t=document.querySelector(`jant-post-menu`);t&&t.openCollectionsForPost(n);return}if(t===`f`){let t=n.dataset.postId;if(!t)return;e.preventDefault(),sz(t,!n.hasAttribute(`data-post-featured`),n);return}}});var cz=[`en`,`zh-Hans`,`zh-Hant`];function lz(e){return typeof e==`string`&&cz.includes(e)}function uz(e){let t=e.trim();if(!t)return`en`;let n;try{n=new Intl.Locale(t)}catch{return`en`}if(lz(n.baseName))return n.baseName;if(n.language===`zh`){let e=n.region;return n.script===`Hant`||e===`TW`||e===`HK`||e===`MO`?`zh-Hant`:`zh-Hans`}return`en`}var dz={en:1,"zh-Hans":1,"zh-Hant":1},fz=`en.zh-Hans.zh-Hant.ja.ko.es.fr.de.it.pt.ru.ar.hi.bn.ur.tr.vi.th.id.fa.he.nl.pl.sv.da.no.fi.cs.hu.el.ro.uk.en-GB.en-US.fr-CA.pt-BR.es-MX.zh-CN.zh-TW.zh-HK`.split(`.`),pz=null;function mz(e){let t=e,n=e;try{let n=new Intl.DisplayNames([e],{type:`language`}).of(e);typeof n==`string`&&n.length>0&&(t=n)}catch{}try{let t=new Intl.DisplayNames([`en`],{type:`language`}).of(e);typeof t==`string`&&t.length>0&&(n=t)}catch{}return{tag:e,native:t,english:n,coverage:hz(e)}}function hz(e){let t=uz(e);if(t===`en`){let t;try{t=new Intl.Locale(e).language}catch{return 0}if(t!==`en`)return 0}return dz[t]}function gz(){return pz||(pz=fz.map(mz),pz)}function _z(e){let t=e.trim();return gz().find(e=>e.tag===t)||mz(t)}var vz=class extends c{static properties={labels:{type:Object},timezones:{type:Array},cjkFonts:{type:Array,attribute:`cjk-fonts`},siteNameFallback:{type:String,attribute:`sitename-fallback`},siteDescriptionFallback:{type:String,attribute:`sitedescription-fallback`},demoMode:{type:Boolean,attribute:`demo-mode`},mainFeedUrl:{type:String,attribute:`main-feed-url`},latestFeedUrl:{type:String,attribute:`latest-feed-url`},featuredFeedUrl:{type:String,attribute:`featured-feed-url`},_siteName:{state:!0},_siteDescription:{state:!0},_siteFooter:{state:!0},_origSite:{state:!0},_siteDirty:{state:!0},_siteLoading:{state:!0},_siteLanguage:{state:!0},_localeOpen:{state:!0},_localeQuery:{state:!0},_cjkSerifFont:{state:!0},_timeZone:{state:!0},_origLocale:{state:!0},_localeDirty:{state:!0},_localeLoading:{state:!0},_mainRssFeed:{state:!0},_origMainRssFeed:{state:!0},_feedDirty:{state:!0},_feedLoading:{state:!0},_showJantBrandingOnHome:{state:!0},_origShowJantBrandingOnHome:{state:!0},_homeLoading:{state:!0},_noindex:{state:!0},_origNoindex:{state:!0},_searchLoading:{state:!0}};_descEditor=null;_footerEditor=null;createRenderRoot(){return this.innerHTML=``,this}constructor(){super(),this.labels={},this.timezones=[],this.cjkFonts=[],this.siteNameFallback=``,this.siteDescriptionFallback=``,this.demoMode=!1,this.mainFeedUrl=`/feed`,this.latestFeedUrl=`/feed/latest`,this.featuredFeedUrl=`/feed/featured`,this._siteName=``,this._siteDescription=``,this._siteFooter=``,this._origSite={siteName:``,siteDescription:``,siteFooter:``},this._siteDirty=!1,this._siteLoading=!1,this._siteLanguage=`en`,this._localeOpen=!1,this._localeQuery=``,this._cjkSerifFont=`off`,this._timeZone=`UTC`,this._origLocale={siteLanguage:`en`,cjkSerifFont:`off`,timeZone:`UTC`},this._localeDirty=!1,this._localeLoading=!1,this._mainRssFeed=`featured`,this._origMainRssFeed=`featured`,this._feedDirty=!1,this._feedLoading=!1,this._noindex=!1,this._origNoindex=!1,this._showJantBrandingOnHome=!1,this._origShowJantBrandingOnHome=!1,this._homeLoading=!1,this._searchLoading=!1}connectedCallback(){super.connectedCallback(),document.addEventListener(`click`,this._onLocalePickerDocumentClick),document.addEventListener(`keydown`,this._onLocalePickerKeydown)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(`click`,this._onLocalePickerDocumentClick),document.removeEventListener(`keydown`,this._onLocalePickerKeydown),this._descEditor?.destroy(),this._descEditor=null,this._footerEditor?.destroy(),this._footerEditor=null}initData(e){this._siteName=e.siteName,this._siteDescription=e.siteDescription,this._siteFooter=e.siteFooter,this._siteLanguage=e.siteLanguage,this._cjkSerifFont=e.cjkSerifFont,this._timeZone=e.timeZone,this._origLocale={siteLanguage:e.siteLanguage,cjkSerifFont:e.cjkSerifFont,timeZone:e.timeZone},this._mainRssFeed=e.mainRssFeed,this._origMainRssFeed=e.mainRssFeed,this._showJantBrandingOnHome=e.showJantBrandingOnHome,this._origShowJantBrandingOnHome=e.showJantBrandingOnHome,this._noindex=e.noindex,this._origNoindex=e.noindex,this.updateComplete.then(()=>{this._initEditors(),this._origSite={siteName:e.siteName,siteDescription:this._siteDescription,siteFooter:this._siteFooter}})}sectionSaved(e){e===`site`?(this._origSite={siteName:this._siteName,siteDescription:this._siteDescription,siteFooter:this._siteFooter},this._siteDirty=!1,this._siteLoading=!1):e===`language-time`?(this._origLocale={siteLanguage:this._siteLanguage,cjkSerifFont:this._cjkSerifFont,timeZone:this._timeZone},this._localeDirty=!1,this._localeLoading=!1):e===`feeds`?(this._origMainRssFeed=this._mainRssFeed,this._feedDirty=!1,this._feedLoading=!1):e===`home`?(this._origShowJantBrandingOnHome=this._showJantBrandingOnHome,this._homeLoading=!1):e===`search`&&(this._origNoindex=this._noindex,this._searchLoading=!1)}sectionError(e){e===`site`?this._siteLoading=!1:e===`language-time`?this._localeLoading=!1:e===`feeds`?this._feedLoading=!1:e===`home`?(this._showJantBrandingOnHome=this._origShowJantBrandingOnHome,this._homeLoading=!1):e===`search`&&(this._noindex=this._origNoindex,this._searchLoading=!1)}_initEditors(){this._initDescEditor(),this._initFooterEditor()}_initDescEditor(){let e=this.querySelector(`[data-settings-desc-editor]`);if(!e||this._descEditor)return;this._descEditor=NT({element:e,placeholder:this.siteDescriptionFallback,content:this._siteDescription||void 0,onUpdate:e=>{this._siteDescription=e,this._syncSiteDirty()}}),this._siteDescription=MT(this._descEditor.getJSON());let t=e.querySelector(`.ProseMirror`);t&&(t.style.outline=`none`,t.style.minHeight=`3rem`)}_initFooterEditor(){let e=this.querySelector(`[data-settings-footer-editor]`);if(!e||this._footerEditor)return;this._footerEditor=NT({element:e,content:this._siteFooter||void 0,onUpdate:e=>{this._siteFooter=e,this._syncSiteDirty()}}),this._siteFooter=MT(this._footerEditor.getJSON());let t=e.querySelector(`.ProseMirror`);t&&(t.style.outline=`none`,t.style.minHeight=`6rem`)}_syncSiteDirty(){this._siteDirty=this._siteName!==this._origSite.siteName||this._siteDescription!==this._origSite.siteDescription||this._siteFooter!==this._origSite.siteFooter}_saveSite(){this._siteLoading||!this._siteDirty||(this._siteLoading=!0,this.dispatchEvent(new CustomEvent(`jant:settings-save`,{bubbles:!0,detail:{endpoint:`/settings/general`,data:{siteName:this._siteName,siteDescription:this._siteDescription,siteFooter:this._siteFooter},section:`site`}})))}_syncLocaleDirty(){this._localeDirty=this._siteLanguage!==this._origLocale.siteLanguage||this._cjkSerifFont!==this._origLocale.cjkSerifFont||this._timeZone!==this._origLocale.timeZone}_saveLocale(){this._localeLoading||!this._localeDirty||(this._localeLoading=!0,this.dispatchEvent(new CustomEvent(`jant:settings-save`,{bubbles:!0,detail:{endpoint:`/settings/general/language-time`,data:{siteLanguage:this._siteLanguage,cjkSerifFont:this._cjkSerifFont,timeZone:this._timeZone},section:`language-time`}})))}_filteredLocaleEntries(){let e=gz(),t=this._localeQuery.trim().toLowerCase();return t?e.filter(e=>e.tag.toLowerCase().includes(t)||e.native.toLowerCase().includes(t)||e.english.toLowerCase().includes(t)):e}_toggleLocalePicker=()=>{this._localeOpen=!this._localeOpen,this._localeOpen?this.updateComplete.then(()=>{this.querySelector(`[data-locale-search]`)?.focus()}):this._localeQuery=``};_selectLocale(e){this._siteLanguage=e,this._localeOpen=!1,this._localeQuery=``,this._syncLocaleDirty()}_onLocalePickerDocumentClick=e=>{if(!this._localeOpen)return;let t=e.target,n=this.querySelector(`[data-locale-picker]`);n&&t&&!n.contains(t)&&(this._localeOpen=!1)};_onLocalePickerKeydown=e=>{e.key===`Escape`&&this._localeOpen&&(this._localeOpen=!1,this._localeQuery=``)};_renderLanguagePicker(){let e=_z(this._siteLanguage||`en`),t=this._filteredLocaleEntries(),n=this.labels.siteLanguageSearchPlaceholder||`Search…`,r=this.labels.siteLanguageNoMatches||`No matches.`;return u`
|
|
2167
2167
|
<div class="relative" data-locale-picker>
|
|
2168
2168
|
<button
|
|
2169
2169
|
type="button"
|
|
@@ -4616,4 +4616,4 @@ Check the discardedTracks field for more info.`)}return e}async execute(){if(!th
|
|
|
4616
4616
|
`:this._query.trim()&&!this._loading?u`<div class="command-palette-empty">No results</div>`:g}
|
|
4617
4617
|
</div>
|
|
4618
4618
|
</dialog>
|
|
4619
|
-
`}};customElements.get(`jant-command-palette`)||customElements.define(`jant-command-palette`,iV),document.addEventListener(`keydown`,e=>{if(e.key.toLowerCase()!==`k`||!(e.metaKey||e.ctrlKey)||e.altKey||e.shiftKey||e.defaultPrevented||e.isComposing)return;e.preventDefault();let t=document.querySelector(`jant-command-palette`);if(t){if(t.querySelector(`dialog[open]`)){t.close();return}document.querySelector(`dialog[open]`)||t.open()}}),document.querySelector(`jant-compose-fullscreen`)||document.body.appendChild(document.createElement(`jant-compose-fullscreen`)),ye(),document.querySelector(`jant-command-palette`)||document.body.appendChild(document.createElement(`jant-command-palette`));
|
|
4619
|
+
`}};customElements.get(`jant-command-palette`)||customElements.define(`jant-command-palette`,iV),document.addEventListener(`keydown`,e=>{if(e.key.toLowerCase()!==`k`||!(e.metaKey||e.ctrlKey)||e.altKey||e.shiftKey||e.defaultPrevented||e.isComposing)return;e.preventDefault();let t=document.querySelector(`jant-command-palette`);if(t){if(t.querySelector(`dialog[open]`)){t.close();return}document.querySelector(`dialog[open]`)||t.open()}}),document.addEventListener(`click`,e=>{let t=e.target;if(!(t instanceof globalThis.Element)||!t.closest(`.site-header-search-link`)||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||e.button!==0||e.defaultPrevented)return;let n=document.querySelector(`jant-command-palette`);n&&(document.querySelector(`dialog[open]`)||(e.preventDefault(),n.open()))}),document.querySelector(`jant-compose-fullscreen`)||document.body.appendChild(document.createElement(`jant-compose-fullscreen`)),ye(),document.querySelector(`jant-command-palette`)||document.body.appendChild(document.createElement(`jant-command-palette`));
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _ as url_exports } from "./url-umUptr5z.js";
|
|
2
|
-
import { A as NAV_ITEM_TYPES, C as toPostView, D as MAX_MEDIA_ATTACHMENTS, E as FORMATS, M as STATUSES, N as TEXT_ATTACHMENT_CONTENT_FORMATS, O as MAX_PINNED_POSTS, S as toNavItemViews, T as toSearchResultView, _ as createMediaContext, b as toMediaView, f as defaultFeedRenderer, j as SORT_ORDERS, k as MEDIA_KINDS, t as createApp, v as toArchiveGroups, w as toPostViews, x as toNavItemView, y as toArchiveGroupsWithMedia } from "./app-
|
|
2
|
+
import { A as NAV_ITEM_TYPES, C as toPostView, D as MAX_MEDIA_ATTACHMENTS, E as FORMATS, M as STATUSES, N as TEXT_ATTACHMENT_CONTENT_FORMATS, O as MAX_PINNED_POSTS, S as toNavItemViews, T as toSearchResultView, _ as createMediaContext, b as toMediaView, f as defaultFeedRenderer, j as SORT_ORDERS, k as MEDIA_KINDS, t as createApp, v as toArchiveGroups, w as toPostViews, x as toNavItemView, y as toArchiveGroupsWithMedia } from "./app-B9XQDSoB.js";
|
|
3
3
|
import { T as time_exports, a as markdown_exports } from "./export-ZBlfKSKm.js";
|
|
4
4
|
import "./env-CgaH9Mut.js";
|
|
5
5
|
import "./github-sync-bL1hnx3Q.js";
|
package/dist/node.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./url-umUptr5z.js";
|
|
2
|
-
import { F as BUILTIN_COLOR_THEMES, I as getPublicAssetBasePath, L as isAssetPath, P as buildThemeStyle, a as resolveDatabaseDialect, c as resolveConfig, d as getFontThemeCssVariables, g as schema_exports, h as createNodeDatabase, i as createSiteService, l as BUILTIN_FONT_THEMES, m as sqliteSchemaBundle, n as createNodeCliRuntime, o as getHostBasedStartupConfigurationIssues, p as pgSchemaBundle, r as createNodeRequestRuntime, s as createStorageDriver, t as createApp, u as getCjkSerifCssVariables } from "./app-
|
|
2
|
+
import { F as BUILTIN_COLOR_THEMES, I as getPublicAssetBasePath, L as isAssetPath, P as buildThemeStyle, a as resolveDatabaseDialect, c as resolveConfig, d as getFontThemeCssVariables, g as schema_exports, h as createNodeDatabase, i as createSiteService, l as BUILTIN_FONT_THEMES, m as sqliteSchemaBundle, n as createNodeCliRuntime, o as getHostBasedStartupConfigurationIssues, p as pgSchemaBundle, r as createNodeRequestRuntime, s as createStorageDriver, t as createApp, u as getCjkSerifCssVariables } from "./app-B9XQDSoB.js";
|
|
3
3
|
import { t as createExportService } from "./export-ZBlfKSKm.js";
|
|
4
4
|
import { b as getSiteResolutionMode, i as getConfiguredSingleSitePathPrefix, l as getEnvString, r as getConfiguredSingleSiteOrigin, x as shouldTrustProxy, y as getPort } from "./env-CgaH9Mut.js";
|
|
5
5
|
import "./github-sync-bL1hnx3Q.js";
|
|
@@ -474,7 +474,7 @@ async function createNodeRequestHandler(options) {
|
|
|
474
474
|
async function start(env = process.env, app) {
|
|
475
475
|
const handler = await createNodeRequestHandler({
|
|
476
476
|
env,
|
|
477
|
-
app: async () => app ?? (await import("./app-
|
|
477
|
+
app: async () => app ?? (await import("./app-CHW6VVQt.js")).createApp()
|
|
478
478
|
});
|
|
479
479
|
const hostname = resolveHost(env);
|
|
480
480
|
const port = resolvePort(env);
|
package/package.json
CHANGED
|
@@ -961,6 +961,11 @@ document.addEventListener("jant:compose-submit-deferred", async (e: Event) => {
|
|
|
961
961
|
`[data-post-view][data-post-view-id="${editPostId}"]`,
|
|
962
962
|
);
|
|
963
963
|
if (postView) {
|
|
964
|
+
if (newPath && newPath !== globalThis.location.pathname) {
|
|
965
|
+
queueSuccessToast("Post updated.");
|
|
966
|
+
globalThis.location.assign(newPath);
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
964
969
|
const refreshed = await refreshPostPageView(editPostId);
|
|
965
970
|
if (refreshed) {
|
|
966
971
|
toastMsg("Post updated.");
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Header search-link click handler (auth-only).
|
|
3
|
+
*
|
|
4
|
+
* Intercepts clicks on `.site-header-search-link` (the magnifying-glass icon
|
|
5
|
+
* shown when the inline search form collapses) and opens the command palette
|
|
6
|
+
* instead of navigating to /search. The anchor's `href` remains a working
|
|
7
|
+
* fallback for anonymous visitors (this script is not loaded for them) and
|
|
8
|
+
* for modifier-clicks that should open a new tab.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { JantCommandPalette } from "./components/jant-command-palette.js";
|
|
12
|
+
|
|
13
|
+
document.addEventListener("click", (event: globalThis.MouseEvent) => {
|
|
14
|
+
const target = event.target;
|
|
15
|
+
if (!(target instanceof globalThis.Element)) return;
|
|
16
|
+
|
|
17
|
+
const link = target.closest<HTMLAnchorElement>(".site-header-search-link");
|
|
18
|
+
if (!link) return;
|
|
19
|
+
|
|
20
|
+
// Let modifier-clicks fall through (new tab/window, save link, etc.)
|
|
21
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
22
|
+
if (event.button !== 0) return;
|
|
23
|
+
if (event.defaultPrevented) return;
|
|
24
|
+
|
|
25
|
+
const palette = document.querySelector<JantCommandPalette>(
|
|
26
|
+
"jant-command-palette",
|
|
27
|
+
);
|
|
28
|
+
if (!palette) return;
|
|
29
|
+
|
|
30
|
+
// Skip if another dialog (compose, confirm) is already open
|
|
31
|
+
if (document.querySelector("dialog[open]")) return;
|
|
32
|
+
|
|
33
|
+
event.preventDefault();
|
|
34
|
+
void palette.open();
|
|
35
|
+
});
|
package/src/client-auth.ts
CHANGED
|
@@ -31,6 +31,7 @@ import "./client/collection-page-actions.js";
|
|
|
31
31
|
import "./client/custom-url-menu.js";
|
|
32
32
|
import "./client/components/jant-command-palette.js";
|
|
33
33
|
import "./client/palette-shortcuts.js";
|
|
34
|
+
import "./client/palette-search-trigger.js";
|
|
34
35
|
|
|
35
36
|
// Mount fullscreen overlay at body level to escape the dialog's containing
|
|
36
37
|
// block (dialog animation creates a containing block that traps fixed children).
|
|
@@ -27,7 +27,7 @@ const aliasDomain: SiteDomain = {
|
|
|
27
27
|
describe("hosted canonical redirects", () => {
|
|
28
28
|
it("bypasses hosted redirects for admin and auth paths", () => {
|
|
29
29
|
expect(
|
|
30
|
-
shouldBypassHostedCanonicalRedirect("/.well-known/jant-
|
|
30
|
+
shouldBypassHostedCanonicalRedirect("/.well-known/jant-verification"),
|
|
31
31
|
).toBe(true);
|
|
32
32
|
expect(shouldBypassHostedCanonicalRedirect("/signin")).toBe(true);
|
|
33
33
|
expect(shouldBypassHostedCanonicalRedirect("/settings/account")).toBe(true);
|