PluginProbe
Gutenberg / 22.7.0
Gutenberg v22.7.0
24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 All 403 releases
← All changes | build/scripts/upload-media/index.js +317 -2087 23.6.2 → 22.7.0 View file →
@@ -44,8 +44,15 @@
44 44 module.exports = window.wp.data;
45 45 }
46 46 });
47 47
48 + // package-external:@wordpress/url
49 + var require_url = __commonJS({
50 + "package-external:@wordpress/url"(exports, module) {
51 + module.exports = window.wp.url;
52 + }
53 + });
54 +
48 55 // package-external:@wordpress/i18n
49 56 var require_i18n = __commonJS({
50 57 "package-external:@wordpress/i18n"(exports, module) {
51 58 module.exports = window.wp.i18n;
@@ -51,15 +58,8 @@
51 58 module.exports = window.wp.i18n;
52 59 }
53 60 });
54 61
55 - // package-external:@wordpress/url
56 - var require_url = __commonJS({
57 - "package-external:@wordpress/url"(exports, module) {
58 - module.exports = window.wp.url;
59 - }
60 - });
61 -
62 62 // package-external:@wordpress/blob
63 63 var require_blob = __commonJS({
64 64 "package-external:@wordpress/blob"(exports, module) {
65 65 module.exports = window.wp.blob;
@@ -96,16 +96,13 @@
96 96
97 97 // packages/upload-media/build-module/index.mjs
98 98 var index_exports = {};
99 99 __export(index_exports, {
100 - ErrorCode: () => ErrorCode,
101 100 MediaUploadProvider: () => provider_default,
102 101 UploadError: () => UploadError,
103 102 clearFeatureDetectionCache: () => clearFeatureDetectionCache,
104 103 detectClientSideMediaSupport: () => detectClientSideMediaSupport,
105 - getErrorMessage: () => getErrorMessage,
106 104 isClientSideMediaSupported: () => isClientSideMediaSupported,
107 - isHeicCanvasSupported: () => isHeicCanvasSupported,
108 105 store: () => store
109 106 });
110 107
111 108 // packages/upload-media/build-module/store/index.mjs
@@ -118,9 +115,8 @@
118 115 Type2["Prepare"] = "PREPARE_ITEM";
119 116 Type2["Cancel"] = "CANCEL_ITEM";
120 117 Type2["Remove"] = "REMOVE_ITEM";
121 118 Type2["RetryItem"] = "RETRY_ITEM";
122 - Type2["ScheduleRetry"] = "SCHEDULE_RETRY";
123 119 Type2["PauseItem"] = "PAUSE_ITEM";
124 120 Type2["ResumeItem"] = "RESUME_ITEM";
125 121 Type2["PauseQueue"] = "PAUSE_QUEUE";
126 122 Type2["ResumeQueue"] = "RESUME_QUEUE";
@@ -129,9 +125,8 @@
129 125 Type2["AddOperations"] = "ADD_OPERATIONS";
130 126 Type2["CacheBlobUrl"] = "CACHE_BLOB_URL";
131 127 Type2["RevokeBlobUrls"] = "REVOKE_BLOB_URLS";
132 128 Type2["UpdateProgress"] = "UPDATE_PROGRESS";
133 - Type2["AccumulateSubSize"] = "ACCUMULATE_SUB_SIZE";
134 129 Type2["UpdateSettings"] = "UPDATE_SETTINGS";
135 130 return Type2;
136 131 })(Type || {});
137 132 var ItemStatus = /* @__PURE__ */ ((ItemStatus2) => {
@@ -137,9 +132,8 @@
137 132 var ItemStatus = /* @__PURE__ */ ((ItemStatus2) => {
138 133 ItemStatus2["Queued"] = "QUEUED";
139 134 ItemStatus2["Processing"] = "PROCESSING";
140 135 ItemStatus2["Paused"] = "PAUSED";
141 - ItemStatus2["PendingRetry"] = "PENDING_RETRY";
142 136 ItemStatus2["Uploaded"] = "UPLOADED";
143 137 ItemStatus2["Error"] = "ERROR";
144 138 return ItemStatus2;
145 139 })(ItemStatus || {});
@@ -148,12 +142,9 @@
148 142 OperationType2["Upload"] = "UPLOAD";
149 143 OperationType2["ResizeCrop"] = "RESIZE_CROP";
150 144 OperationType2["Rotate"] = "ROTATE";
151 145 OperationType2["TranscodeImage"] = "TRANSCODE_IMAGE";
152 - OperationType2["TranscodeGif"] = "TRANSCODE_GIF";
153 146 OperationType2["ThumbnailGeneration"] = "THUMBNAIL_GENERATION";
154 - OperationType2["Finalize"] = "FINALIZE";
155 - OperationType2["DetectUltraHdr"] = "DETECT_ULTRAHDR";
156 147 return OperationType2;
157 148 })(OperationType || {});
158 149
159 150 // packages/upload-media/build-module/store/constants.mjs
@@ -159,15 +150,8 @@
159 150 // packages/upload-media/build-module/store/constants.mjs
160 151 var STORE_NAME = "core/upload-media";
161 152 var DEFAULT_MAX_CONCURRENT_UPLOADS = 5;
162 153 var DEFAULT_MAX_CONCURRENT_IMAGE_PROCESSING = 2;
163 - var DEFAULT_RETRY_SETTINGS = {
164 - maxRetryAttempts: 3,
165 - initialRetryDelayMs: 1e3,
166 - maxRetryDelayMs: 3e4,
167 - backoffMultiplier: 2,
168 - retryJitter: 0.1
169 - };
170 154 var CLIENT_SIDE_SUPPORTED_MIME_TYPES = [
171 155 "image/jpeg",
172 156 "image/png",
173 157 "image/gif",
@@ -173,12 +157,8 @@
173 157 "image/gif",
174 158 "image/webp",
175 159 "image/avif"
176 160 ];
177 - var HEIC_MIME_TYPES = [
178 - "image/heic",
179 - "image/heif"
180 - ];
181 161
182 162 // packages/upload-media/build-module/store/reducer.mjs
183 163 var noop = () => {
184 164 };
@@ -188,10 +168,9 @@
188 168 blobUrls: {},
189 169 settings: {
190 170 mediaUpload: noop,
191 171 maxConcurrentUploads: DEFAULT_MAX_CONCURRENT_UPLOADS,
192 - maxConcurrentImageProcessing: DEFAULT_MAX_CONCURRENT_IMAGE_PROCESSING,
193 - retry: { ...DEFAULT_RETRY_SETTINGS }
172 + maxConcurrentImageProcessing: DEFAULT_MAX_CONCURRENT_IMAGE_PROCESSING
194 173 }
195 174 };
196 175 function reducer(state = DEFAULT_STATE, action = { type: Type.Unknown }) {
197 176 switch (action.type) {
@@ -249,26 +228,12 @@
249 228 (item) => item.id === action.id ? {
250 229 ...item,
251 230 status: ItemStatus.Processing,
252 231 error: void 0,
253 - retryCount: (item.retryCount ?? 0) + 1,
254 - abortController: new AbortController()
232 + retryCount: (item.retryCount ?? 0) + 1
255 233 } : item
256 234 )
257 235 };
258 - case Type.ScheduleRetry:
259 - return {
260 - ...state,
261 - queue: state.queue.map(
262 - (item) => item.id === action.id ? {
263 - ...item,
264 - status: ItemStatus.PendingRetry,
265 - error: action.error,
266 - retryCount: action.retryCount,
267 - nextRetryTimestamp: action.nextRetryTimestamp
268 - } : item
269 - )
270 - };
271 236 case Type.Remove:
272 237 return {
273 238 ...state,
274 239 queue: state.queue.filter((item) => item.id !== action.id)
@@ -352,21 +317,8 @@
352 317 progress: action.progress
353 318 } : item
354 319 )
355 320 };
356 - case Type.AccumulateSubSize:
357 - return {
358 - ...state,
359 - queue: state.queue.map(
360 - (item) => item.id === action.id ? {
361 - ...item,
362 - subSizes: [
363 - ...item.subSizes || [],
364 - action.subSize
365 - ]
366 - } : item
367 - )
368 - };
369 321 case Type.UpdateSettings: {
370 322 return {
371 323 ...state,
372 324 settings: {
@@ -413,20 +365,20 @@
413 365 var private_selectors_exports = {};
414 366 __export(private_selectors_exports, {
415 367 getActiveImageProcessingCount: () => getActiveImageProcessingCount,
416 368 getActiveUploadCount: () => getActiveUploadCount,
417 - getActiveVideoProcessingCount: () => getActiveVideoProcessingCount,
418 369 getAllItems: () => getAllItems,
419 370 getBlobUrls: () => getBlobUrls,
420 371 getFailedItems: () => getFailedItems,
421 372 getItem: () => getItem,
422 373 getItemProgress: () => getItemProgress,
374 + getPausedUploadForPost: () => getPausedUploadForPost,
423 375 getPendingImageProcessing: () => getPendingImageProcessing,
424 376 getPendingUploads: () => getPendingUploads,
425 - getPendingVideoProcessing: () => getPendingVideoProcessing,
426 377 hasPendingItemsByParentId: () => hasPendingItemsByParentId,
427 378 isBatchUploaded: () => isBatchUploaded,
428 - isPaused: () => isPaused
379 + isPaused: () => isPaused,
380 + isUploadingToPost: () => isUploadingToPost
429 381 });
430 382 function getAllItems(state) {
431 383 return state.queue;
432 384 }
@@ -438,8 +390,18 @@
438 390 (item) => batchId === item.batchId
439 391 );
440 392 return batchItems.length === 0;
441 393 }
394 + function isUploadingToPost(state, postOrAttachmentId) {
395 + return state.queue.some(
396 + (item) => item.currentOperation === OperationType.Upload && item.additionalData.post === postOrAttachmentId
397 + );
398 + }
399 + function getPausedUploadForPost(state, postOrAttachmentId) {
400 + return state.queue.find(
401 + (item) => item.status === ItemStatus.Paused && item.additionalData.post === postOrAttachmentId
402 + );
403 + }
442 404 function isPaused(state) {
443 405 return state.queueStatus === "paused";
444 406 }
445 407 function getBlobUrls(state, id) {
@@ -460,13 +422,8 @@
460 422 return state.queue.filter(
461 423 (item) => item.currentOperation === OperationType.ResizeCrop || item.currentOperation === OperationType.Rotate
462 424 ).length;
463 425 }
464 - function getActiveVideoProcessingCount(state) {
465 - return state.queue.filter(
466 - (item) => item.currentOperation === OperationType.TranscodeGif
467 - ).length;
468 - }
469 426 function getPendingImageProcessing(state) {
470 427 return state.queue.filter((item) => {
471 428 const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
472 429 return (nextOperation === OperationType.ResizeCrop || nextOperation === OperationType.Rotate) && item.currentOperation !== OperationType.ResizeCrop && item.currentOperation !== OperationType.Rotate;
@@ -471,14 +428,8 @@
471 428 const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
472 429 return (nextOperation === OperationType.ResizeCrop || nextOperation === OperationType.Rotate) && item.currentOperation !== OperationType.ResizeCrop && item.currentOperation !== OperationType.Rotate;
473 430 });
474 431 }
475 - function getPendingVideoProcessing(state) {
476 - return state.queue.filter((item) => {
477 - const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
478 - return nextOperation === OperationType.TranscodeGif && item.currentOperation !== OperationType.TranscodeGif;
479 - });
480 - }
481 432 function getFailedItems(state) {
482 433 return state.queue.filter((item) => item.error !== void 0);
483 434 }
484 435 function hasPendingItemsByParentId(state, parentId) {
@@ -493,48 +444,50 @@
493 444 var actions_exports = {};
494 445 __export(actions_exports, {
495 446 addItems: () => addItems,
496 447 cancelItem: () => cancelItem,
497 - executeRetry: () => executeRetry,
498 - retryItem: () => retryItem,
499 - scheduleRetry: () => scheduleRetry
448 + retryItem: () => retryItem
500 449 });
501 450
502 - // node_modules/uuid/dist/stringify.js
451 + // node_modules/uuid/dist/esm-browser/rng.js
452 + var getRandomValues;
453 + var rnds8 = new Uint8Array(16);
454 + function rng() {
455 + if (!getRandomValues) {
456 + getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
457 + if (!getRandomValues) {
458 + throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
459 + }
460 + }
461 + return getRandomValues(rnds8);
462 + }
463 +
464 + // node_modules/uuid/dist/esm-browser/stringify.js
503 465 var byteToHex = [];
504 466 for (let i = 0; i < 256; ++i) {
505 467 byteToHex.push((i + 256).toString(16).slice(1));
506 468 }
507 469 function unsafeStringify(arr, offset = 0) {
508 - return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
470 + return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
509 471 }
510 472
511 - // node_modules/uuid/dist/rng.js
512 - var rnds8 = new Uint8Array(16);
513 - function rng() {
514 - return crypto.getRandomValues(rnds8);
515 - }
473 + // node_modules/uuid/dist/esm-browser/native.js
474 + var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
475 + var native_default = {
476 + randomUUID
477 + };
516 478
517 - // node_modules/uuid/dist/v4.js
479 + // node_modules/uuid/dist/esm-browser/v4.js
518 480 function v4(options, buf, offset) {
519 - if (!buf && !options && crypto.randomUUID) {
520 - return crypto.randomUUID();
481 + if (native_default.randomUUID && !buf && !options) {
482 + return native_default.randomUUID();
521 483 }
522 - return _v4(options, buf, offset);
523 - }
524 - function _v4(options, buf, offset) {
525 484 options = options || {};
526 - const rnds = options.random ?? options.rng?.() ?? rng();
527 - if (rnds.length < 16) {
528 - throw new Error("Random bytes length must be >= 16");
529 - }
485 + const rnds = options.random || (options.rng || rng)();
530 486 rnds[6] = rnds[6] & 15 | 64;
531 487 rnds[8] = rnds[8] & 63 | 128;
532 488 if (buf) {
533 489 offset = offset || 0;
534 - if (offset < 0 || offset + 16 > buf.length) {
535 - throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
536 - }
537 490 for (let i = 0; i < 16; ++i) {
538 491 buf[offset + i] = rnds[i];
539 492 }
540 493 return buf;
@@ -542,50 +495,8 @@
542 495 return unsafeStringify(rnds);
543 496 }
544 497 var v4_default = v4;
545 498
546 - // packages/upload-media/build-module/store/actions.mjs
547 - var import_i18n5 = __toESM(require_i18n(), 1);
548 -
549 - // packages/upload-media/build-module/store/utils/retry.mjs
550 - function calculateRetryDelay(options) {
551 - const { attempt, initialDelay, maxDelay, multiplier, jitter } = options;
552 - const exponentialDelay = initialDelay * Math.pow(multiplier, attempt - 1);
553 - const cappedDelay = Math.min(exponentialDelay, maxDelay);
554 - const jitterFactor = 1 + (Math.random() * 2 - 1) * jitter;
555 - return Math.floor(cappedDelay * jitterFactor);
556 - }
557 - var RETRYABLE_MESSAGE_PATTERNS = [
558 - /network/i,
559 - /timeout/i,
560 - /ECONNRESET/i,
561 - /fetch failed/i,
562 - /connection/i,
563 - /socket/i,
564 - /ETIMEDOUT/i,
565 - /ENOTFOUND/i,
566 - /Could not get a valid response/i,
567 - /Failed to fetch/i,
568 - /Load failed/i
569 - ];
570 - function shouldRetryError(error, retryCount, maxRetries) {
571 - if (retryCount >= maxRetries) {
572 - return false;
573 - }
574 - const message = typeof error === "string" ? error : error?.message || "";
575 - return RETRYABLE_MESSAGE_PATTERNS.some(
576 - (pattern) => pattern.test(message)
577 - );
578 - }
579 - var retryTimers = /* @__PURE__ */ new Map();
580 - function clearRetryTimer(id) {
581 - const pendingTimer = retryTimers.get(id);
582 - if (pendingTimer !== void 0) {
583 - clearTimeout(pendingTimer);
584 - retryTimers.delete(id);
585 - }
586 - }
587 -
588 499 // packages/upload-media/build-module/image-file.mjs
589 500 var ImageFile = class extends File {
590 501 width = 0;
591 502 height = 0;
@@ -636,24 +547,8 @@
636 547 }
637 548 function getFileBasename(name) {
638 549 return name.includes(".") ? name.split(".").slice(0, -1).join(".") : name;
639 550 }
640 - function isAnimatedGif(buffer) {
641 - const view = new Uint8Array(buffer);
642 - if (view.length < 4 || view[0] !== 71 || view[1] !== 73 || view[2] !== 70 || view[3] !== 56) {
643 - return false;
644 - }
645 - let frameCount = 0;
646 - for (let i = 0; i < view.length - 2; i++) {
647 - if (view[i] === 0 && view[i + 1] === 33 && view[i + 2] === 249) {
648 - frameCount++;
649 - if (frameCount > 1) {
650 - return true;
651 - }
652 - }
653 - }
654 - return false;
655 - }
656 551
657 552 // packages/upload-media/build-module/store/utils/index.mjs
658 553 var vipsModulePromise;
659 554 var vipsModule;
@@ -667,9 +562,9 @@
667 562 );
668 563 }
669 564 return vipsModulePromise;
670 565 }
671 - async function vipsConvertImageFormat(id, file, type, options = {}) {
566 + async function vipsConvertImageFormat(id, file, type, quality, interlaced) {
672 567 const { vipsConvertImageFormat: convertImageFormat } = await loadVipsModule();
673 568 const buffer = await convertImageFormat(
674 569 id,
675 570 await file.arrayBuffer(),
@@ -674,9 +569,10 @@
674 569 id,
675 570 await file.arrayBuffer(),
676 571 file.type,
677 572 type,
678 - options
573 + quality,
574 + interlaced
679 575 );
680 576 const ext = type.split("/")[1];
681 577 const fileName = `${getFileBasename(file.name)}.${ext}`;
682 578 return new File([new Blob([buffer])], fileName, {
@@ -690,32 +586,21 @@
690 586 throw new Error(`Failed to fetch image: ${response.status}`);
691 587 }
692 588 return hasTransparency(await response.arrayBuffer());
693 589 }
694 - async function vipsGetUltraHdrInfo(buffer) {
695 - const { vipsGetUltraHdrInfo: getUltraHdrInfo } = await loadVipsModule();
696 - return getUltraHdrInfo(buffer);
697 - }
698 - async function vipsResizeImage(id, file, resize, options = {}) {
699 - const {
700 - smartCrop = false,
701 - addSuffix = false,
702 - signal,
703 - scaledSuffix,
704 - quality,
705 - stripMeta,
706 - maxBitdepth
707 - } = options;
590 + async function vipsResizeImage(id, file, resize, smartCrop, addSuffix, signal, scaledSuffix, quality) {
708 591 if (signal?.aborted) {
709 592 throw new Error("Operation aborted");
710 593 }
711 594 const { vipsResizeImage: resizeImage } = await loadVipsModule();
712 - const { buffer, width, height, originalWidth, originalHeight } = await resizeImage(id, await file.arrayBuffer(), file.type, resize, {
595 + const { buffer, width, height, originalWidth, originalHeight } = await resizeImage(
596 + id,
597 + await file.arrayBuffer(),
598 + file.type,
599 + resize,
713 600 smartCrop,
714 - quality,
715 - stripMeta,
716 - maxBitdepth
717 - });
601 + quality
602 + );
718 603 let fileName = file.name;
719 604 const wasResized = originalWidth > width || originalHeight > height;
720 605 if (wasResized) {
721 606 const basename = getFileBasename(file.name);
@@ -782,171 +667,13 @@
782 667 if (vipsModule) {
783 668 vipsModule.terminateVipsWorker();
784 669 }
785 670 }
786 - var completedVipsOperations = 0;
787 - var MAX_VIPS_OPS_BEFORE_RECYCLE = 50;
788 - function maybeRecycleVipsWorker(activeImageProcessingCount) {
789 - completedVipsOperations++;
790 - if (completedVipsOperations >= MAX_VIPS_OPS_BEFORE_RECYCLE && activeImageProcessingCount === 0) {
791 - terminateVipsWorker();
792 - completedVipsOperations = 0;
793 - }
794 - }
795 671
796 - // packages/upload-media/build-module/store/utils/video-conversion.mjs
797 - var UNSUPPORTED_ERROR_PREFIX = "Unsupported";
798 - var SIZE_LIMIT_ERROR_PREFIX = `${UNSUPPORTED_ERROR_PREFIX}: GIF exceeds maximum conversion size`;
799 - var CONVERSION_TIMEOUT_ERROR_PREFIX = "GIF to video conversion timed out";
800 - var DEFAULT_CONVERSION_TIMEOUT = 3e4;
801 - function isUnsupportedConversionError(error) {
802 - return error instanceof Error && error.message.startsWith(UNSUPPORTED_ERROR_PREFIX);
803 - }
804 - function isSizeLimitConversionError(error) {
805 - return error instanceof Error && error.message.startsWith(SIZE_LIMIT_ERROR_PREFIX);
806 - }
807 - function isConversionTimeoutError(error) {
808 - return error instanceof Error && error.message.startsWith(CONVERSION_TIMEOUT_ERROR_PREFIX);
809 - }
810 - var videoConversionModulePromise;
811 - var videoConversionModule;
812 - function loadVideoConversionModule() {
813 - if (!videoConversionModulePromise) {
814 - videoConversionModulePromise = import("@wordpress/video-conversion/worker").then((mod) => {
815 - videoConversionModule = mod;
816 - return mod;
817 - }).catch((error) => {
818 - videoConversionModulePromise = void 0;
819 - throw error;
820 - });
821 - }
822 - return videoConversionModulePromise;
823 - }
824 - async function convertGifToVideo(id, file, outputMimeType, {
825 - maxDimensions,
826 - timeout = DEFAULT_CONVERSION_TIMEOUT,
827 - maxTotalPixels
828 - } = {}) {
829 - const mod = await loadVideoConversionModule();
830 - const conversion = mod.convertGifToVideo(
831 - id,
832 - file,
833 - outputMimeType,
834 - maxDimensions,
835 - maxTotalPixels
836 - );
837 - let buffer;
838 - if (timeout > 0) {
839 - let timer;
840 - try {
841 - buffer = await Promise.race([
842 - conversion,
843 - new Promise((_, reject) => {
844 - timer = setTimeout(() => {
845 - reject(
846 - new Error(
847 - `${CONVERSION_TIMEOUT_ERROR_PREFIX} after ${timeout}ms`
848 - )
849 - );
850 - }, timeout);
851 - })
852 - ]);
853 - } catch (error) {
854 - if (isConversionTimeoutError(error)) {
855 - conversion.catch(() => {
856 - });
857 - mod.cancelGifToVideoOperations(id).catch(() => {
858 - });
859 - }
860 - throw error;
861 - } finally {
862 - clearTimeout(timer);
863 - }
864 - } else {
865 - buffer = await conversion;
866 - }
867 - const ext = outputMimeType === "video/webm" ? "webm" : "mp4";
868 - const fileName = `${getFileBasename(file.name)}.${ext}`;
869 - return new File(
870 - [new Blob([buffer], { type: outputMimeType })],
871 - fileName,
872 - { type: outputMimeType }
873 - );
874 - }
875 - async function cancelGifToVideoOperations(id) {
876 - const mod = videoConversionModule ?? (videoConversionModulePromise ? await videoConversionModulePromise.catch(() => void 0) : void 0);
877 - if (!mod) {
878 - return false;
879 - }
880 - return mod.cancelGifToVideoOperations(id);
881 - }
882 - function terminateVideoConversionWorker() {
883 - if (videoConversionModule) {
884 - videoConversionModule.terminateVideoConversionWorker();
885 - return;
886 - }
887 - if (videoConversionModulePromise) {
888 - void videoConversionModulePromise.then((mod) => mod.terminateVideoConversionWorker()).catch(() => {
889 - });
890 - }
891 - }
672 + // packages/upload-media/build-module/validate-mime-type.mjs
673 + var import_i18n2 = __toESM(require_i18n(), 1);
892 674
893 - // packages/upload-media/build-module/store/utils/debug-logger.mjs
894 - function isDebugEnabled() {
895 - return true;
896 - }
897 - function debug(message, ...args) {
898 - if (!isDebugEnabled()) {
899 - return;
900 - }
901 - console.debug(`[upload-media] ${message}`, ...args);
902 - }
903 - function measure(options) {
904 - if (!isDebugEnabled()) {
905 - return;
906 - }
907 - const {
908 - measureName,
909 - startTime,
910 - endTime = performance.now(),
911 - tooltipText,
912 - properties
913 - } = options;
914 - const detail = {
915 - devtools: {
916 - dataType: "track-entry",
917 - track: "Upload Media",
918 - tooltipText,
919 - properties: properties?.map(([key, value]) => ({
920 - key,
921 - value
922 - }))
923 - }
924 - };
925 - try {
926 - performance.measure(measureName, {
927 - start: startTime,
928 - end: endTime,
929 - detail
930 - });
931 - } catch {
932 - }
933 - }
934 -
935 675 // packages/upload-media/build-module/upload-error.mjs
936 - var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
937 - ErrorCode2["EMPTY_FILE"] = "EMPTY_FILE";
938 - ErrorCode2["SIZE_ABOVE_LIMIT"] = "SIZE_ABOVE_LIMIT";
939 - ErrorCode2["MIME_TYPE_NOT_SUPPORTED"] = "MIME_TYPE_NOT_SUPPORTED";
940 - ErrorCode2["MIME_TYPE_NOT_ALLOWED_FOR_USER"] = "MIME_TYPE_NOT_ALLOWED_FOR_USER";
941 - ErrorCode2["HEIC_DECODE_ERROR"] = "HEIC_DECODE_ERROR";
942 - ErrorCode2["IMAGE_TRANSCODING_ERROR"] = "IMAGE_TRANSCODING_ERROR";
943 - ErrorCode2["IMAGE_ROTATION_ERROR"] = "IMAGE_ROTATION_ERROR";
944 - ErrorCode2["MEDIA_TRANSCODING_ERROR"] = "MEDIA_TRANSCODING_ERROR";
945 - ErrorCode2["GIF_TRANSCODING_ERROR"] = "GIF_TRANSCODING_ERROR";
946 - ErrorCode2["GENERAL"] = "GENERAL";
947 - return ErrorCode2;
948 - })(ErrorCode || {});
949 676 var UploadError = class extends Error {
950 677 code;
951 678 file;
952 679 constructor({ code, message, file, cause }) {
@@ -957,9 +684,8 @@
957 684 }
958 685 };
959 686
960 687 // packages/upload-media/build-module/validate-mime-type.mjs
961 - var import_i18n2 = __toESM(require_i18n(), 1);
962 688 function validateMimeType(file, allowedTypes) {
963 689 if (!allowedTypes) {
964 690 return;
965 691 }
@@ -970,9 +696,9 @@
970 696 return file.type.startsWith(`${allowedType}/`);
971 697 });
972 698 if (file.type && !isAllowedType) {
973 699 throw new UploadError({
974 - code: ErrorCode.MIME_TYPE_NOT_SUPPORTED,
700 + code: "MIME_TYPE_NOT_SUPPORTED",
975 701 message: (0, import_i18n2.sprintf)(
976 702 // translators: %s: file name.
977 703 (0, import_i18n2.__)("%s: Sorry, this file type is not supported here."),
978 704 file.name
@@ -1014,9 +740,9 @@
1014 740 file.type
1015 741 );
1016 742 if (file.type && !isAllowedMimeTypeForUser) {
1017 743 throw new UploadError({
1018 - code: ErrorCode.MIME_TYPE_NOT_ALLOWED_FOR_USER,
744 + code: "MIME_TYPE_NOT_ALLOWED_FOR_USER",
1019 745 message: (0, import_i18n3.sprintf)(
1020 746 // translators: %s: file name.
1021 747 (0, import_i18n3.__)(
1022 748 "%s: Sorry, you are not allowed to upload this file type."
@@ -1032,9 +758,9 @@
1032 758 var import_i18n4 = __toESM(require_i18n(), 1);
1033 759 function validateFileSize(file, maxUploadFileSize) {
1034 760 if (file.size <= 0) {
1035 761 throw new UploadError({
1036 - code: ErrorCode.EMPTY_FILE,
762 + code: "EMPTY_FILE",
1037 763 message: (0, import_i18n4.sprintf)(
1038 764 // translators: %s: file name.
1039 765 (0, import_i18n4.__)("%s: This file is empty."),
1040 766 file.name
@@ -1043,9 +769,9 @@
1043 769 });
1044 770 }
1045 771 if (maxUploadFileSize && file.size > maxUploadFileSize) {
1046 772 throw new UploadError({
1047 - code: ErrorCode.SIZE_ABOVE_LIMIT,
773 + code: "SIZE_ABOVE_LIMIT",
1048 774 message: (0, import_i18n4.sprintf)(
1049 775 // translators: %s: file name.
1050 776 (0, import_i18n4.__)(
1051 777 "%s: This file exceeds the maximum upload size for this site."
@@ -1106,38 +832,17 @@
1106 832 const item = select2.getItem(id);
1107 833 if (!item) {
1108 834 return;
1109 835 }
1110 - clearRetryTimer(id);
1111 - if (!silent && error && !item.parentId && !item.attachment?.id) {
1112 - const settings = select2.getSettings();
1113 - const retrySettings = settings.retry;
1114 - if (retrySettings) {
1115 - const retryCount = item.retryCount ?? 0;
1116 - const maxRetries = retrySettings.maxRetryAttempts;
1117 - if (shouldRetryError(error, retryCount, maxRetries)) {
1118 - dispatch.scheduleRetry(id, error);
1119 - return;
1120 - }
1121 - }
1122 - }
1123 836 item.abortController?.abort();
1124 - vipsCancelOperations(id).catch(() => {
1125 - });
1126 - cancelGifToVideoOperations(id).catch(() => {
1127 - });
837 + await vipsCancelOperations(id);
1128 838 if (!silent) {
1129 839 const { onError } = item;
1130 840 onError?.(error ?? new Error("Upload cancelled"));
1131 - if (!onError && error && !item.parentId) {
841 + if (!onError && error) {
1132 842 console.error("Upload cancelled", error);
1133 843 }
1134 - } else {
1135 - debug(
1136 - `Item cancelled: ${item.file.name} (item ${id}): ${error instanceof Error ? error.message : error}`
1137 - );
1138 844 }
1139 - const { currentOperation, parentId, batchId } = item;
1140 845 dispatch({
1141 846 type: Type.Cancel,
1142 847 id,
1143 848 error
@@ -1143,59 +848,9 @@
1143 848 error
1144 849 });
1145 850 dispatch.removeItem(id);
1146 851 dispatch.revokeBlobUrls(id);
1147 - if (currentOperation === OperationType.ResizeCrop || currentOperation === OperationType.Rotate) {
1148 - for (const pending of select2.getPendingImageProcessing()) {
1149 - dispatch.processItem(pending.id);
1150 - }
1151 - }
1152 - if (currentOperation === OperationType.Upload) {
1153 - for (const pending of select2.getPendingUploads()) {
1154 - dispatch.processItem(pending.id);
1155 - }
1156 - }
1157 - if (currentOperation === OperationType.TranscodeGif) {
1158 - for (const pending of select2.getPendingVideoProcessing()) {
1159 - dispatch.processItem(pending.id);
1160 - }
1161 - }
1162 - if (currentOperation === OperationType.ResizeCrop || currentOperation === OperationType.Rotate || currentOperation === OperationType.TranscodeImage) {
1163 - maybeRecycleVipsWorker(select2.getActiveImageProcessingCount());
1164 - }
1165 - if (parentId) {
1166 - const parentItem = select2.getItem(parentId);
1167 - if (parentItem) {
1168 - const isOptionalCompanion = item.additionalData?.image_size === "animated_video" || item.additionalData?.image_size === "animated_video_poster";
1169 - if (select2.hasPendingItemsByParentId(parentId)) {
1170 - if (parentItem.operations && parentItem.operations.length > 0) {
1171 - dispatch.processItem(parentId);
1172 - }
1173 - } else if (parentItem.subSizes && parentItem.subSizes.length > 0 || isOptionalCompanion) {
1174 - if (parentItem.operations && parentItem.operations.length > 0) {
1175 - dispatch.processItem(parentId);
1176 - }
1177 - } else {
1178 - const parentAttachmentId = parentItem.attachment?.id;
1179 - const { mediaDelete } = select2.getSettings();
1180 - if (parentAttachmentId && mediaDelete) {
1181 - mediaDelete(parentAttachmentId).catch(() => {
1182 - });
1183 - }
1184 - await dispatch.cancelItem(
1185 - parentId,
1186 - new UploadError({
1187 - code: error instanceof UploadError && error.code || ErrorCode.GENERAL,
1188 - message: error?.message || (0, import_i18n5.__)("The image could not be uploaded."),
1189 - file: parentItem.file,
1190 - cause: error instanceof Error ? error : void 0
1191 - })
1192 - );
1193 - }
1194 - }
1195 - }
1196 - if (batchId && select2.isBatchUploaded(batchId)) {
1197 - debug(`Batch completed: ${batchId}`);
852 + if (item.batchId && select2.isBatchUploaded(item.batchId)) {
1198 853 item.onBatchSuccess?.();
1199 854 }
1200 855 };
1201 856 }
@@ -1214,57 +869,8 @@
1214 869 });
1215 870 dispatch.processItem(id);
1216 871 };
1217 872 }
1218 - function scheduleRetry(id, error) {
1219 - return async ({ select: select2, dispatch }) => {
1220 - const item = select2.getItem(id);
1221 - if (!item) {
1222 - return;
1223 - }
1224 - const settings = select2.getSettings();
1225 - const retrySettings = settings.retry;
1226 - if (!retrySettings) {
1227 - return;
1228 - }
1229 - const currentRetryCount = item.retryCount ?? 0;
1230 - const delay = calculateRetryDelay({
1231 - attempt: currentRetryCount + 1,
1232 - initialDelay: retrySettings.initialRetryDelayMs,
1233 - maxDelay: retrySettings.maxRetryDelayMs,
1234 - multiplier: retrySettings.backoffMultiplier,
1235 - jitter: retrySettings.retryJitter
1236 - });
1237 - const timerId = setTimeout(() => {
1238 - retryTimers.delete(id);
1239 - dispatch.executeRetry(id);
1240 - }, delay);
1241 - retryTimers.set(id, timerId);
1242 - dispatch({
1243 - type: Type.ScheduleRetry,
1244 - id,
1245 - error,
1246 - retryCount: currentRetryCount,
1247 - nextRetryTimestamp: Date.now() + delay
1248 - });
1249 - };
1250 - }
1251 - function executeRetry(id) {
1252 - return async ({ select: select2, dispatch }) => {
1253 - const item = select2.getItem(id);
1254 - if (!item || item.status !== ItemStatus.PendingRetry) {
1255 - return;
1256 - }
1257 - if (select2.isPaused()) {
1258 - return;
1259 - }
1260 - dispatch({
1261 - type: Type.RetryItem,
1262 - id
1263 - });
1264 - dispatch.processItem(id);
1265 - };
1266 - }
1267 873
1268 874 // packages/upload-media/build-module/store/private-actions.mjs
1269 875 var private_actions_exports = {};
1270 876 __export(private_actions_exports, {
@@ -1269,10 +875,8 @@
1269 875 var private_actions_exports = {};
1270 876 __export(private_actions_exports, {
1271 877 addItem: () => addItem,
1272 878 addSideloadItem: () => addSideloadItem,
1273 - detectUltraHdr: () => detectUltraHdr,
1274 - finalizeItem: () => finalizeItem,
1275 879 finishOperation: () => finishOperation,
1276 880 generateThumbnails: () => generateThumbnails,
1277 881 getTranscodeImageOperation: () => getTranscodeImageOperation,
1278 882 pauseItem: () => pauseItem,
@@ -1280,13 +884,13 @@
1280 884 prepareItem: () => prepareItem,
1281 885 processItem: () => processItem,
1282 886 removeItem: () => removeItem,
1283 887 resizeCropItem: () => resizeCropItem,
888 + resumeItemByPostId: () => resumeItemByPostId,
1284 889 resumeQueue: () => resumeQueue,
1285 890 revokeBlobUrls: () => revokeBlobUrls,
1286 891 rotateItem: () => rotateItem,
1287 892 sideloadItem: () => sideloadItem,
1288 - transcodeGifItem: () => transcodeGifItem,
1289 893 transcodeImageItem: () => transcodeImageItem,
1290 894 updateItemProgress: () => updateItemProgress,
1291 895 updateSettings: () => updateSettings,
1292 896 uploadItem: () => uploadItem
@@ -1291,1010 +895,9 @@
1291 895 updateSettings: () => updateSettings,
1292 896 uploadItem: () => uploadItem
1293 897 });
1294 898 var import_blob = __toESM(require_blob(), 1);
1295 - var import_i18n6 = __toESM(require_i18n(), 1);
1296 899
1297 - // packages/upload-media/build-module/heic-parser.mjs
1298 - var Reader = class {
1299 - view;
1300 - buffer;
1301 - pos;
1302 - constructor(buffer, offset = 0) {
1303 - this.buffer = buffer;
1304 - this.view = new DataView(buffer);
1305 - this.pos = offset;
1306 - }
1307 - u8() {
1308 - const v = this.view.getUint8(this.pos);
1309 - this.pos += 1;
1310 - return v;
1311 - }
1312 - u16() {
1313 - const v = this.view.getUint16(this.pos);
1314 - this.pos += 2;
1315 - return v;
1316 - }
1317 - u32() {
1318 - const v = this.view.getUint32(this.pos);
1319 - this.pos += 4;
1320 - return v;
1321 - }
1322 - u64() {
1323 - const hi = this.view.getUint32(this.pos);
1324 - const lo = this.view.getUint32(this.pos + 4);
1325 - this.pos += 8;
1326 - return hi * 4294967296 + lo;
1327 - }
1328 - /**
1329 - * Read a variable-width unsigned integer (0, 4 or 8 bytes).
1330 - *
1331 - * @param size Byte width to read (0, 4, or 8).
1332 - */
1333 - uN(size) {
1334 - if (size === 0) {
1335 - return 0;
1336 - }
1337 - if (size === 4) {
1338 - return this.u32();
1339 - }
1340 - if (size === 8) {
1341 - return this.u64();
1342 - }
1343 - throw new Error(`Unsupported uint size: ${size}`);
1344 - }
1345 - str(len) {
1346 - let s = "";
1347 - for (let i = 0; i < len; i++) {
1348 - s += String.fromCharCode(this.view.getUint8(this.pos + i));
1349 - }
1350 - this.pos += len;
1351 - return s;
1352 - }
1353 - bytes(len) {
1354 - const b = new Uint8Array(this.buffer, this.pos, len);
1355 - this.pos += len;
1356 - return new Uint8Array(b);
1357 - }
1358 - };
1359 - function readBox(r) {
1360 - if (r.pos + 8 > r.view.byteLength) {
1361 - return null;
1362 - }
1363 - const offset = r.pos;
1364 - let size = r.u32();
1365 - const type = r.str(4);
1366 - let headerSize = 8;
1367 - if (size === 1) {
1368 - size = r.u64();
1369 - headerSize = 16;
1370 - } else if (size === 0) {
1371 - size = r.view.byteLength - offset;
1372 - }
1373 - return { type, offset, size, headerSize };
1374 - }
1375 - function findBoxes(r, start, end) {
1376 - const boxes = [];
1377 - r.pos = start;
1378 - while (r.pos < end) {
1379 - const box = readBox(r);
1380 - if (!box || box.size < 8) {
1381 - break;
1382 - }
1383 - boxes.push(box);
1384 - r.pos = box.offset + box.size;
1385 - }
1386 - return boxes;
1387 - }
1388 - function findBox(r, start, end, type) {
1389 - r.pos = start;
1390 - while (r.pos < end) {
1391 - const box = readBox(r);
1392 - if (!box || box.size < 8) {
1393 - break;
1394 - }
1395 - if (box.type === type) {
1396 - return box;
1397 - }
1398 - r.pos = box.offset + box.size;
1399 - }
1400 - return void 0;
1401 - }
1402 - function parsePitm(r, box) {
1403 - r.pos = box.offset + box.headerSize;
1404 - const version = r.u8();
1405 - r.pos += 3;
1406 - return version === 0 ? r.u16() : r.u32();
1407 - }
1408 - function parseIloc(r, box) {
1409 - r.pos = box.offset + box.headerSize;
1410 - const version = r.u8();
1411 - r.pos += 3;
1412 - const byte1 = r.u8();
1413 - const offsetSize = byte1 >> 4 & 15;
1414 - const lengthSize = byte1 & 15;
1415 - const byte2 = r.u8();
1416 - const baseOffsetSize = byte2 >> 4 & 15;
1417 - const indexSize = version >= 1 ? byte2 & 15 : 0;
1418 - const itemCount = version < 2 ? r.u16() : r.u32();
1419 - const items = /* @__PURE__ */ new Map();
1420 - for (let i = 0; i < itemCount; i++) {
1421 - const itemId = version < 2 ? r.u16() : r.u32();
1422 - let constructionMethod = 0;
1423 - if (version === 1 || version === 2) {
1424 - const cm = r.u16();
1425 - constructionMethod = cm & 15;
1426 - }
1427 - r.u16();
1428 - const baseOffset = r.uN(baseOffsetSize);
1429 - const extentCount = r.u16();
1430 - const extents = [];
1431 - for (let j = 0; j < extentCount; j++) {
1432 - if (version >= 1) {
1433 - r.uN(indexSize);
1434 - }
1435 - const extOffset = r.uN(offsetSize);
1436 - const extLength = r.uN(lengthSize);
1437 - extents.push({
1438 - offset: baseOffset + extOffset,
1439 - length: extLength
1440 - });
1441 - }
1442 - items.set(itemId, { constructionMethod, extents });
1443 - }
1444 - return items;
1445 - }
1446 - function parseIpma(r, box) {
1447 - r.pos = box.offset + box.headerSize;
1448 - const vf = r.u32();
1449 - const version = vf >>> 24;
1450 - const flags = vf & 16777215;
1451 - const largeIndex = (flags & 1) !== 0;
1452 - const entryCount = r.u32();
1453 - const associations = /* @__PURE__ */ new Map();
1454 - for (let i = 0; i < entryCount; i++) {
1455 - const itemId = version < 1 ? r.u16() : r.u32();
1456 - const assocCount = r.u8();
1457 - const indices = [];
1458 - for (let j = 0; j < assocCount; j++) {
1459 - if (largeIndex) {
1460 - indices.push(r.u16() & 32767);
1461 - } else {
1462 - indices.push(r.u8() & 127);
1463 - }
1464 - }
1465 - associations.set(itemId, indices);
1466 - }
1467 - return associations;
1468 - }
1469 - function parseIspe(r, box) {
1470 - r.pos = box.offset + box.headerSize + 4;
1471 - return { width: r.u32(), height: r.u32() };
1472 - }
1473 - function parseIrot(r, box) {
1474 - r.pos = box.offset + box.headerSize;
1475 - return (r.u8() & 3) * 90;
1476 - }
1477 - function parseIinf(r, box) {
1478 - r.pos = box.offset + box.headerSize;
1479 - const version = r.u8();
1480 - r.pos += 3;
1481 - const entryCount = version === 0 ? r.u16() : r.u32();
1482 - const itemTypes = /* @__PURE__ */ new Map();
1483 - const entriesStart = r.pos;
1484 - const boxEnd = box.offset + box.size;
1485 - const infeBoxes = findBoxes(r, entriesStart, boxEnd);
1486 - for (let i = 0; i < Math.min(entryCount, infeBoxes.length); i++) {
1487 - const infe = infeBoxes[i];
1488 - if (infe.type !== "infe") {
1489 - continue;
1490 - }
1491 - r.pos = infe.offset + infe.headerSize;
1492 - const infeVersion = r.u8();
1493 - r.pos += 3;
1494 - if (infeVersion >= 2) {
1495 - const itemId = infeVersion === 2 ? r.u16() : r.u32();
1496 - r.u16();
1497 - const itemType = r.str(4);
1498 - itemTypes.set(itemId, itemType);
1499 - }
1500 - }
1501 - return itemTypes;
1502 - }
1503 - function parseIref(r, box, refType) {
1504 - r.pos = box.offset + box.headerSize;
1505 - const version = r.u8();
1506 - r.pos += 3;
1507 - const refs = /* @__PURE__ */ new Map();
1508 - const boxEnd = box.offset + box.size;
1509 - while (r.pos < boxEnd) {
1510 - const refBox = readBox(r);
1511 - if (!refBox || refBox.size < 8) {
1512 - break;
1513 - }
1514 - r.pos = refBox.offset + refBox.headerSize;
1515 - const fromId = version === 0 ? r.u16() : r.u32();
1516 - const refCount = r.u16();
1517 - const toIds = [];
1518 - for (let i = 0; i < refCount; i++) {
1519 - toIds.push(version === 0 ? r.u16() : r.u32());
1520 - }
1521 - if (refBox.type === refType) {
1522 - refs.set(fromId, toIds);
1523 - }
1524 - r.pos = refBox.offset + refBox.size;
1525 - }
1526 - return refs;
1527 - }
1528 - function reverseBits32(n) {
1529 - n = n >>> 1 & 1431655765 | (n & 1431655765) << 1;
1530 - n = n >>> 2 & 858993459 | (n & 858993459) << 2;
1531 - n = n >>> 4 & 252645135 | (n & 252645135) << 4;
1532 - n = n >>> 8 & 16711935 | (n & 16711935) << 8;
1533 - n = n >>> 16 | n << 16;
1534 - return n >>> 0;
1535 - }
1536 - function buildCodecString(r, recordOffset) {
1537 - r.pos = recordOffset;
1538 - r.u8();
1539 - const byte1 = r.u8();
1540 - const profileSpace = byte1 >> 6 & 3;
1541 - const tierFlag = byte1 >> 5 & 1;
1542 - const profileIdc = byte1 & 31;
1543 - const compatFlags = r.u32();
1544 - const constraintBytes = r.bytes(6);
1545 - const levelIdc = r.u8();
1546 - const spacePrefix = profileSpace > 0 ? String.fromCharCode(64 + profileSpace) : "";
1547 - const compatHex = reverseBits32(compatFlags).toString(16).toUpperCase();
1548 - const tierChar = tierFlag ? "H" : "L";
1549 - let lastNonZero = -1;
1550 - for (let i = 5; i >= 0; i--) {
1551 - if (constraintBytes[i] !== 0) {
1552 - lastNonZero = i;
1553 - break;
1554 - }
1555 - }
1556 - let constraintStr = "";
1557 - if (lastNonZero >= 0) {
1558 - const parts = [];
1559 - for (let i = 0; i <= lastNonZero; i++) {
1560 - parts.push(constraintBytes[i].toString(16).toUpperCase());
1561 - }
1562 - constraintStr = "." + parts.join(".");
1563 - }
1564 - return `hvc1.${spacePrefix}${profileIdc}.${compatHex}.${tierChar}${levelIdc}${constraintStr}`;
1565 - }
1566 - function readItemData(buffer, loc, idatOffset) {
1567 - const baseOffset = loc.constructionMethod === 1 ? idatOffset : 0;
1568 - if (loc.extents.length === 1) {
1569 - const ext = loc.extents[0];
1570 - const start = baseOffset + ext.offset;
1571 - return new Uint8Array(buffer.slice(start, start + ext.length));
1572 - }
1573 - let totalLength = 0;
1574 - for (const ext of loc.extents) {
1575 - totalLength += ext.length;
1576 - }
1577 - const data = new Uint8Array(totalLength);
1578 - let pos = 0;
1579 - for (const ext of loc.extents) {
1580 - const start = baseOffset + ext.offset;
1581 - data.set(
1582 - new Uint8Array(buffer.slice(start, start + ext.length)),
1583 - pos
1584 - );
1585 - pos += ext.length;
1586 - }
1587 - return data;
1588 - }
1589 - function findHvcProperties(propIndices, properties) {
1590 - let hvcCBox;
1591 - let ispeBox;
1592 - let irotBox;
1593 - for (const idx of propIndices) {
1594 - if (idx < 1 || idx > properties.length) {
1595 - continue;
1596 - }
1597 - const prop = properties[idx - 1];
1598 - if (prop.type === "hvcC" && !hvcCBox) {
1599 - hvcCBox = prop;
1600 - }
1601 - if (prop.type === "ispe" && !ispeBox) {
1602 - ispeBox = prop;
1603 - }
1604 - if (prop.type === "irot" && !irotBox) {
1605 - irotBox = prop;
1606 - }
1607 - }
1608 - if (!hvcCBox) {
1609 - throw new Error("No HEVC configuration (hvcC) found");
1610 - }
1611 - if (!ispeBox) {
1612 - throw new Error("No image dimensions (ispe) found");
1613 - }
1614 - return { hvcCBox, ispeBox, irotBox };
1615 - }
1616 - function parseHeic(buffer) {
1617 - const r = new Reader(buffer);
1618 - const fileEnd = buffer.byteLength;
1619 - const metaBox = findBox(r, 0, fileEnd, "meta");
1620 - if (!metaBox) {
1621 - throw new Error("No meta box found in HEIC file");
1622 - }
1623 - const metaChildStart = metaBox.offset + metaBox.headerSize + 4;
1624 - const metaEnd = metaBox.offset + metaBox.size;
1625 - const children = findBoxes(r, metaChildStart, metaEnd);
1626 - const pitmBox = children.find((b) => b.type === "pitm");
1627 - const ilocBox = children.find((b) => b.type === "iloc");
1628 - const iprpBox = children.find((b) => b.type === "iprp");
1629 - const iinfBox = children.find((b) => b.type === "iinf");
1630 - const irefBox = children.find((b) => b.type === "iref");
1631 - const idatBox = children.find((b) => b.type === "idat");
1632 - const idatOffset = idatBox ? idatBox.offset + idatBox.headerSize : 0;
1633 - if (!pitmBox || !ilocBox || !iprpBox) {
1634 - throw new Error("Missing required boxes (pitm, iloc, iprp) in HEIC");
1635 - }
1636 - const primaryId = parsePitm(r, pitmBox);
1637 - const locations = parseIloc(r, ilocBox);
1638 - const iprpStart = iprpBox.offset + iprpBox.headerSize;
1639 - const iprpEnd = iprpBox.offset + iprpBox.size;
1640 - const iprpChildren = findBoxes(r, iprpStart, iprpEnd);
1641 - const ipcoBox = iprpChildren.find((b) => b.type === "ipco");
1642 - const ipmaBox = iprpChildren.find((b) => b.type === "ipma");
1643 - if (!ipcoBox || !ipmaBox) {
1644 - throw new Error("Missing ipco or ipma in HEIC properties");
1645 - }
1646 - const allAssoc = parseIpma(r, ipmaBox);
1647 - const ipcoStart = ipcoBox.offset + ipcoBox.headerSize;
1648 - const ipcoEnd = ipcoBox.offset + ipcoBox.size;
1649 - const properties = findBoxes(r, ipcoStart, ipcoEnd);
1650 - let primaryItemType = "hvc1";
1651 - if (iinfBox) {
1652 - const itemTypes = parseIinf(r, iinfBox);
1653 - const t = itemTypes.get(primaryId);
1654 - if (t) {
1655 - primaryItemType = t;
1656 - }
1657 - }
1658 - if (primaryItemType === "grid") {
1659 - return parseGridImage(
1660 - r,
1661 - buffer,
1662 - primaryId,
1663 - locations,
1664 - allAssoc,
1665 - properties,
1666 - irefBox,
1667 - idatOffset
1668 - );
1669 - }
1670 - const primaryLoc = locations.get(primaryId);
1671 - if (!primaryLoc || primaryLoc.extents.length === 0) {
1672 - throw new Error(`No location data for primary item ${primaryId}`);
1673 - }
1674 - const primaryPropIndices = allAssoc.get(primaryId);
1675 - if (!primaryPropIndices || primaryPropIndices.length === 0) {
1676 - throw new Error("No property associations for primary item");
1677 - }
1678 - const { hvcCBox, ispeBox, irotBox } = findHvcProperties(
1679 - primaryPropIndices,
1680 - properties
1681 - );
1682 - const hvcCDataStart = hvcCBox.offset + hvcCBox.headerSize;
1683 - const hvcCDataSize = hvcCBox.size - hvcCBox.headerSize;
1684 - const description = new Uint8Array(
1685 - buffer.slice(hvcCDataStart, hvcCDataStart + hvcCDataSize)
1686 - );
1687 - const codecString = buildCodecString(r, hvcCDataStart);
1688 - const { width, height } = parseIspe(r, ispeBox);
1689 - const rotation = irotBox ? parseIrot(r, irotBox) : 0;
1690 - return {
1691 - codecString,
1692 - description,
1693 - tiles: [
1694 - {
1695 - data: readItemData(buffer, primaryLoc, idatOffset),
1696 - x: 0,
1697 - y: 0
1698 - }
1699 - ],
1700 - tileWidth: width,
1701 - tileHeight: height,
1702 - outputWidth: width,
1703 - outputHeight: height,
1704 - rotation,
1705 - exifOrientation: rotation === 0 ? getUnappliedExifOrientation(buffer) : 1
1706 - };
1707 - }
1708 - function parseGridImage(r, buffer, gridItemId, locations, allAssoc, properties, irefBox, idatOffset) {
1709 - const gridLoc = locations.get(gridItemId);
1710 - if (!gridLoc || gridLoc.extents.length === 0) {
1711 - throw new Error("No location data for grid item");
1712 - }
1713 - const gridData = readItemData(buffer, gridLoc, idatOffset);
1714 - const largeFields = gridData.length > 1 && (gridData[1] & 1) !== 0;
1715 - const minGridSize = largeFields ? 12 : 8;
1716 - if (gridData.length < minGridSize) {
1717 - throw new Error(
1718 - `Grid descriptor too short: ${gridData.length} bytes`
1719 - );
1720 - }
1721 - const rows = gridData[2] + 1;
1722 - const columns = gridData[3] + 1;
1723 - const gv = new DataView(gridData.buffer, gridData.byteOffset);
1724 - let outputWidth;
1725 - let outputHeight;
1726 - if (largeFields) {
1727 - outputWidth = gv.getUint32(4);
1728 - outputHeight = gv.getUint32(8);
1729 - } else {
1730 - outputWidth = gv.getUint16(4);
1731 - outputHeight = gv.getUint16(6);
1732 - }
1733 - if (!irefBox) {
1734 - throw new Error("Grid image requires iref box");
1735 - }
1736 - const dimgRefs = parseIref(r, irefBox, "dimg");
1737 - const tileItemIds = dimgRefs.get(gridItemId);
1738 - if (!tileItemIds || tileItemIds.length === 0) {
1739 - throw new Error("No tile references found for grid item");
1740 - }
1741 - const expectedTiles = rows * columns;
1742 - if (tileItemIds.length < expectedTiles) {
1743 - throw new Error(
1744 - `Grid expects ${expectedTiles} tiles but found ${tileItemIds.length}`
1745 - );
1746 - }
1747 - const firstTileProps = allAssoc.get(tileItemIds[0]);
1748 - if (!firstTileProps || firstTileProps.length === 0) {
1749 - throw new Error("No property associations for tile item");
1750 - }
1751 - const { hvcCBox, ispeBox } = findHvcProperties(
1752 - firstTileProps,
1753 - properties
1754 - );
1755 - const gridProps = allAssoc.get(gridItemId) || [];
1756 - let irotBox;
1757 - for (const idx of gridProps) {
1758 - if (idx >= 1 && idx <= properties.length) {
1759 - const prop = properties[idx - 1];
1760 - if (prop.type === "irot") {
1761 - irotBox = prop;
1762 - break;
1763 - }
1764 - }
1765 - }
1766 - const hvcCDataStart = hvcCBox.offset + hvcCBox.headerSize;
1767 - const hvcCDataSize = hvcCBox.size - hvcCBox.headerSize;
1768 - const description = new Uint8Array(
1769 - buffer.slice(hvcCDataStart, hvcCDataStart + hvcCDataSize)
1770 - );
1771 - const codecString = buildCodecString(r, hvcCDataStart);
1772 - const { width: tileWidth, height: tileHeight } = parseIspe(r, ispeBox);
1773 - const tiles = [];
1774 - for (let row = 0; row < rows; row++) {
1775 - for (let col = 0; col < columns; col++) {
1776 - const tileIdx = row * columns + col;
1777 - const tileId = tileItemIds[tileIdx];
1778 - const tileLoc = locations.get(tileId);
1779 - if (!tileLoc || tileLoc.extents.length === 0) {
1780 - throw new Error(`No location data for tile item ${tileId}`);
1781 - }
1782 - tiles.push({
1783 - data: readItemData(buffer, tileLoc, idatOffset),
1784 - x: col * tileWidth,
1785 - y: row * tileHeight
1786 - });
1787 - }
1788 - }
1789 - const rotation = irotBox ? parseIrot(r, irotBox) : 0;
1790 - return {
1791 - codecString,
1792 - description,
1793 - tiles,
1794 - tileWidth,
1795 - tileHeight,
1796 - outputWidth,
1797 - outputHeight,
1798 - rotation,
1799 - exifOrientation: rotation === 0 ? getUnappliedExifOrientation(buffer) : 1
1800 - };
1801 - }
1802 - function readTiffOrientation(payload) {
1803 - if (payload.length < 8) {
1804 - return 1;
1805 - }
1806 - const view = new DataView(
1807 - payload.buffer,
1808 - payload.byteOffset,
1809 - payload.byteLength
1810 - );
1811 - let tiffStart = 0;
1812 - const firstWord = view.getUint16(0);
1813 - if (firstWord !== 18761 && firstWord !== 19789) {
1814 - tiffStart = view.getUint32(0) + 4;
1815 - }
1816 - if (tiffStart + 8 > payload.length) {
1817 - return 1;
1818 - }
1819 - const byteOrder = view.getUint16(tiffStart);
1820 - let little;
1821 - if (byteOrder === 18761) {
1822 - little = true;
1823 - } else if (byteOrder === 19789) {
1824 - little = false;
1825 - } else {
1826 - return 1;
1827 - }
1828 - const ifd0 = tiffStart + view.getUint32(tiffStart + 4, little);
1829 - if (ifd0 + 2 > payload.length) {
1830 - return 1;
1831 - }
1832 - const entryCount = view.getUint16(ifd0, little);
1833 - for (let i = 0; i < entryCount; i++) {
1834 - const entry = ifd0 + 2 + i * 12;
1835 - if (entry + 12 > payload.length) {
1836 - break;
1837 - }
1838 - if (view.getUint16(entry, little) === 274) {
1839 - const value = view.getUint16(entry + 8, little);
1840 - return value >= 1 && value <= 8 ? value : 1;
1841 - }
1842 - }
1843 - return 1;
1844 - }
1845 - function findMeta(r) {
1846 - const metaBox = findBox(r, 0, r.view.byteLength, "meta");
1847 - if (!metaBox) {
1848 - return null;
1849 - }
1850 - const start = metaBox.offset + metaBox.headerSize + 4;
1851 - const end = metaBox.offset + metaBox.size;
1852 - return { box: metaBox, children: findBoxes(r, start, end) };
1853 - }
1854 - function parseExifOrientation(buffer) {
1855 - try {
1856 - const r = new Reader(buffer);
1857 - const meta = findMeta(r);
1858 - if (!meta) {
1859 - return 1;
1860 - }
1861 - const iinfBox = meta.children.find((b) => b.type === "iinf");
1862 - const ilocBox = meta.children.find((b) => b.type === "iloc");
1863 - if (!iinfBox || !ilocBox) {
1864 - return 1;
1865 - }
1866 - const itemTypes = parseIinf(r, iinfBox);
1867 - let exifItemId;
1868 - for (const [id, type] of itemTypes) {
1869 - if (type === "Exif") {
1870 - exifItemId = id;
1871 - break;
1872 - }
1873 - }
1874 - if (exifItemId === void 0) {
1875 - return 1;
1876 - }
1877 - const loc = parseIloc(r, ilocBox).get(exifItemId);
1878 - if (!loc || loc.extents.length === 0) {
1879 - return 1;
1880 - }
1881 - const idatBox = meta.children.find((b) => b.type === "idat");
1882 - const idatOffset = idatBox ? idatBox.offset + idatBox.headerSize : 0;
1883 - return readTiffOrientation(readItemData(buffer, loc, idatOffset));
1884 - } catch {
1885 - return 1;
1886 - }
1887 - }
1888 - function hasNativeTransform(r) {
1889 - const meta = findMeta(r);
1890 - if (!meta) {
1891 - return false;
1892 - }
1893 - const iprp = meta.children.find((b) => b.type === "iprp");
1894 - if (!iprp) {
1895 - return false;
1896 - }
1897 - const ipco = findBox(
1898 - r,
1899 - iprp.offset + iprp.headerSize,
1900 - iprp.offset + iprp.size,
1901 - "ipco"
1902 - );
1903 - if (!ipco) {
1904 - return false;
1905 - }
1906 - const start = ipco.offset + ipco.headerSize;
1907 - const end = ipco.offset + ipco.size;
1908 - return Boolean(
1909 - findBox(r, start, end, "irot") || findBox(r, start, end, "imir")
1910 - );
1911 - }
1912 - function getUnappliedExifOrientation(buffer) {
1913 - try {
1914 - if (hasNativeTransform(new Reader(buffer))) {
1915 - return 1;
1916 - }
1917 - } catch {
1918 - return 1;
1919 - }
1920 - return parseExifOrientation(buffer);
1921 - }
1922 -
1923 - // packages/upload-media/build-module/canvas-utils.mjs
1924 - async function canvasConvertToJpeg(file, quality = 0.82) {
1925 - const baseName = getFileBasename(file.name);
1926 - try {
1927 - const bitmap = await createImageBitmap(file);
1928 - try {
1929 - const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
1930 - const ctx = canvas.getContext("2d");
1931 - if (!ctx) {
1932 - throw new Error("Could not get canvas 2d context");
1933 - }
1934 - ctx.drawImage(bitmap, 0, 0);
1935 - const jpegBlob = await canvas.convertToBlob({
1936 - type: "image/jpeg",
1937 - quality
1938 - });
1939 - return new File([jpegBlob], `${baseName}.jpg`, {
1940 - type: "image/jpeg"
1941 - });
1942 - } finally {
1943 - bitmap.close();
1944 - }
1945 - } catch {
1946 - }
1947 - if (typeof ImageDecoder !== "undefined") {
1948 - const supported = await ImageDecoder.isTypeSupported(file.type);
1949 - if (supported) {
1950 - const decoder = new ImageDecoder({
1951 - type: file.type,
1952 - data: file.stream()
1953 - });
1954 - try {
1955 - const { image: videoFrame } = await decoder.decode();
1956 - try {
1957 - const canvas = new OffscreenCanvas(
1958 - videoFrame.displayWidth,
1959 - videoFrame.displayHeight
1960 - );
1961 - const ctx = canvas.getContext("2d");
1962 - if (!ctx) {
1963 - throw new Error("Could not get canvas 2d context");
1964 - }
1965 - ctx.drawImage(videoFrame, 0, 0);
1966 - const jpegBlob = await canvas.convertToBlob({
1967 - type: "image/jpeg",
1968 - quality
1969 - });
1970 - return new File([jpegBlob], `${baseName}.jpg`, {
1971 - type: "image/jpeg"
1972 - });
1973 - } finally {
1974 - videoFrame.close();
1975 - }
1976 - } finally {
1977 - decoder.close();
1978 - }
1979 - }
1980 - }
1981 - if (typeof VideoDecoder !== "undefined") {
1982 - try {
1983 - const heicData = parseHeic(await file.arrayBuffer());
1984 - const support = await VideoDecoder.isConfigSupported({
1985 - codec: heicData.codecString
1986 - });
1987 - if (support.supported) {
1988 - const canvas = new OffscreenCanvas(
1989 - heicData.outputWidth,
1990 - heicData.outputHeight
1991 - );
1992 - const ctx = canvas.getContext("2d");
1993 - if (!ctx) {
1994 - throw new Error("Could not get canvas 2d context");
1995 - }
1996 - for (const tile of heicData.tiles) {
1997 - const frame = await decodeHevcFrame(
1998 - heicData.codecString,
1999 - heicData.description,
2000 - heicData.tileWidth,
2001 - heicData.tileHeight,
2002 - tile.data
2003 - );
2004 - try {
2005 - ctx.drawImage(frame, tile.x, tile.y);
2006 - } finally {
2007 - frame.close();
2008 - }
2009 - }
2010 - const outputCanvas = heicData.rotation !== 0 ? applyRotation(canvas, heicData.rotation) : applyExifOrientation(
2011 - canvas,
2012 - heicData.exifOrientation
2013 - );
2014 - const jpegBlob = await outputCanvas.convertToBlob({
2015 - type: "image/jpeg",
2016 - quality
2017 - });
2018 - return new File([jpegBlob], `${baseName}.jpg`, {
2019 - type: "image/jpeg"
2020 - });
2021 - }
2022 - } catch {
2023 - }
2024 - }
2025 - throw new Error(
2026 - "This browser cannot decode HEIC images. Please use Safari or convert to JPEG before uploading."
2027 - );
2028 - }
2029 - function applyRotation(source, rotation) {
2030 - if (rotation === 0) {
2031 - return source;
2032 - }
2033 - const swap = rotation === 90 || rotation === 270;
2034 - const w = swap ? source.height : source.width;
2035 - const h = swap ? source.width : source.height;
2036 - const rotated = new OffscreenCanvas(w, h);
2037 - const ctx = rotated.getContext("2d");
2038 - if (!ctx) {
2039 - return source;
2040 - }
2041 - ctx.translate(w / 2, h / 2);
2042 - ctx.rotate(-rotation * Math.PI / 180);
2043 - ctx.drawImage(source, -source.width / 2, -source.height / 2);
2044 - return rotated;
2045 - }
2046 - function applyExifOrientation(source, orientation) {
2047 - if (orientation <= 1 || orientation > 8) {
2048 - return source;
2049 - }
2050 - const { width: sw, height: sh } = source;
2051 - const swap = orientation >= 5;
2052 - const out = new OffscreenCanvas(swap ? sh : sw, swap ? sw : sh);
2053 - const ctx = out.getContext("2d");
2054 - if (!ctx) {
2055 - return source;
2056 - }
2057 - switch (orientation) {
2058 - case 2:
2059 - ctx.transform(-1, 0, 0, 1, sw, 0);
2060 - break;
2061 - case 3:
2062 - ctx.transform(-1, 0, 0, -1, sw, sh);
2063 - break;
2064 - case 4:
2065 - ctx.transform(1, 0, 0, -1, 0, sh);
2066 - break;
2067 - case 5:
2068 - ctx.transform(0, 1, 1, 0, 0, 0);
2069 - break;
2070 - case 6:
2071 - ctx.transform(0, 1, -1, 0, sh, 0);
2072 - break;
2073 - case 7:
2074 - ctx.transform(0, -1, -1, 0, sh, sw);
2075 - break;
2076 - case 8:
2077 - ctx.transform(0, -1, 1, 0, 0, sw);
2078 - break;
2079 - }
2080 - ctx.drawImage(source, 0, 0);
2081 - return out;
2082 - }
2083 - function decodeHevcFrame(codec, description, width, height, data) {
2084 - return new Promise((resolve, reject) => {
2085 - const decoder = new VideoDecoder({
2086 - output: (frame) => {
2087 - decoder.close();
2088 - resolve(frame);
2089 - },
2090 - error: (e) => {
2091 - if (decoder.state !== "closed") {
2092 - decoder.close();
2093 - }
2094 - reject(e);
2095 - }
2096 - });
2097 - decoder.configure({
2098 - codec,
2099 - codedWidth: width,
2100 - codedHeight: height,
2101 - description
2102 - });
2103 - decoder.decode(
2104 - new EncodedVideoChunk({
2105 - type: "key",
2106 - timestamp: 0,
2107 - data
2108 - })
2109 - );
2110 - decoder.flush().catch((e) => {
2111 - if (decoder.state !== "closed") {
2112 - decoder.close();
2113 - }
2114 - reject(e);
2115 - });
2116 - });
2117 - }
2118 -
2119 - // packages/upload-media/build-module/feature-detection.mjs
2120 - var cachedResult = null;
2121 - function detectClientSideMediaSupport() {
2122 - if (cachedResult !== null) {
2123 - return cachedResult;
2124 - }
2125 - if (typeof WebAssembly === "undefined") {
2126 - cachedResult = {
2127 - supported: false,
2128 - reason: "WebAssembly is not supported in this browser."
2129 - };
2130 - return cachedResult;
2131 - }
2132 - if (typeof SharedArrayBuffer === "undefined") {
2133 - cachedResult = {
2134 - supported: false,
2135 - reason: "SharedArrayBuffer is not available. This may be due to missing cross-origin isolation headers."
2136 - };
2137 - return cachedResult;
2138 - }
2139 - if (typeof Worker === "undefined") {
2140 - cachedResult = {
2141 - supported: false,
2142 - reason: "Web Workers are not supported in this browser."
2143 - };
2144 - return cachedResult;
2145 - }
2146 - if (typeof navigator !== "undefined" && "deviceMemory" in navigator && navigator.deviceMemory <= 2) {
2147 - cachedResult = {
2148 - supported: false,
2149 - reason: "Device has insufficient memory for client-side media processing."
2150 - };
2151 - return cachedResult;
2152 - }
2153 - if (typeof navigator !== "undefined" && "hardwareConcurrency" in navigator && navigator.hardwareConcurrency < 2) {
2154 - cachedResult = {
2155 - supported: false,
2156 - reason: "Device has insufficient CPU cores for client-side media processing."
2157 - };
2158 - return cachedResult;
2159 - }
2160 - if (typeof navigator !== "undefined") {
2161 - const connection = navigator.connection;
2162 - if (connection) {
2163 - if (connection.saveData) {
2164 - cachedResult = {
2165 - supported: false,
2166 - reason: "Data saver mode is enabled."
2167 - };
2168 - return cachedResult;
2169 - }
2170 - if (connection.effectiveType === "slow-2g" || connection.effectiveType === "2g") {
2171 - cachedResult = {
2172 - supported: false,
2173 - reason: "Network connection is too slow for client-side media processing."
2174 - };
2175 - return cachedResult;
2176 - }
2177 - }
2178 - }
2179 - if (typeof window !== "undefined") {
2180 - try {
2181 - const testBlob = new Blob([""], {
2182 - type: "application/javascript"
2183 - });
2184 - const testUrl = URL.createObjectURL(testBlob);
2185 - try {
2186 - const testWorker = new Worker(testUrl);
2187 - testWorker.terminate();
2188 - } finally {
2189 - URL.revokeObjectURL(testUrl);
2190 - }
2191 - } catch {
2192 - cachedResult = {
2193 - supported: false,
2194 - reason: "The site's Content Security Policy (CSP) does not allow blob: workers. The worker-src directive must include blob: to enable client-side media processing."
2195 - };
2196 - return cachedResult;
2197 - }
2198 - }
2199 - cachedResult = { supported: true };
2200 - return cachedResult;
2201 - }
2202 - function isClientSideMediaSupported() {
2203 - return detectClientSideMediaSupport().supported;
2204 - }
2205 - function isHeicCanvasSupported() {
2206 - return typeof createImageBitmap !== "undefined" && typeof OffscreenCanvas !== "undefined";
2207 - }
2208 - function clearFeatureDetectionCache() {
2209 - cachedResult = null;
2210 - }
2211 - var BYTES_PER_PIXEL = 4;
2212 - var INTERLACED_MEMORY_BUDGET = 0.5 * 1024 * 1024 * 1024;
2213 - var BASELINE_MEMORY_BUDGET = 0.9 * 1024 * 1024 * 1024;
2214 - function exceedsClientProcessingMemory(dimensions) {
2215 - const { width, height, interlaced } = dimensions;
2216 - const estimatedBytes = width * height * BYTES_PER_PIXEL;
2217 - const budget = interlaced ? INTERLACED_MEMORY_BUDGET : BASELINE_MEMORY_BUDGET;
2218 - return estimatedBytes > budget;
2219 - }
2220 -
2221 - // packages/upload-media/build-module/get-image-dimensions.mjs
2222 - var MAX_HEADER_BYTES = 512 * 1024;
2223 - function parseJpeg(view) {
2224 - let offset = 2;
2225 - while (offset < view.byteLength) {
2226 - if (view.getUint8(offset) !== 255) {
2227 - return null;
2228 - }
2229 - while (offset < view.byteLength && view.getUint8(offset) === 255) {
2230 - offset++;
2231 - }
2232 - if (offset >= view.byteLength) {
2233 - return null;
2234 - }
2235 - const marker = view.getUint8(offset);
2236 - offset++;
2237 - if (marker === 1 || marker >= 208 && marker <= 217) {
2238 - continue;
2239 - }
2240 - if (marker === 218) {
2241 - return null;
2242 - }
2243 - if (offset + 2 > view.byteLength) {
2244 - return null;
2245 - }
2246 - const segmentLength = view.getUint16(offset);
2247 - if (segmentLength < 2) {
2248 - return null;
2249 - }
2250 - const isStartOfFrame = marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204;
2251 - if (isStartOfFrame) {
2252 - if (offset + 7 > view.byteLength) {
2253 - return null;
2254 - }
2255 - const height = view.getUint16(offset + 3);
2256 - const width = view.getUint16(offset + 5);
2257 - const interlaced = marker === 194 || marker === 198 || marker === 202 || marker === 206;
2258 - return { width, height, interlaced };
2259 - }
2260 - offset += segmentLength;
2261 - }
2262 - return null;
2263 - }
2264 - function parsePng(view) {
2265 - if (view.byteLength < 29) {
2266 - return null;
2267 - }
2268 - const isIhdr = view.getUint8(12) === 73 && // I
2269 - view.getUint8(13) === 72 && // H
2270 - view.getUint8(14) === 68 && // D
2271 - view.getUint8(15) === 82;
2272 - if (!isIhdr) {
2273 - return null;
2274 - }
2275 - const width = view.getUint32(16);
2276 - const height = view.getUint32(20);
2277 - const interlaceMethod = view.getUint8(28);
2278 - return { width, height, interlaced: interlaceMethod !== 0 };
2279 - }
2280 - async function getImageDimensions(file) {
2281 - try {
2282 - const headerBytes = Math.min(file.size, MAX_HEADER_BYTES);
2283 - const buffer = await file.slice(0, headerBytes).arrayBuffer();
2284 - const view = new DataView(buffer);
2285 - if (view.byteLength >= 3 && view.getUint16(0) === 65496) {
2286 - return parseJpeg(view);
2287 - }
2288 - if (view.byteLength >= 8 && view.getUint32(0) === 2303741511 && view.getUint32(4) === 218765834) {
2289 - return parsePng(view);
2290 - }
2291 - return null;
2292 - } catch {
2293 - return null;
2294 - }
2295 - }
2296 -
2297 900 // packages/upload-media/build-module/stub-file.mjs
2298 901 var StubFile = class extends File {
2299 902 constructor(fileName = "stub-file") {
2300 903 super([], fileName);
@@ -2302,9 +905,14 @@
2302 905 };
2303 906
2304 907 // packages/upload-media/build-module/store/private-actions.mjs
2305 908 var DEFAULT_OUTPUT_QUALITY = 0.82;
2306 - var ultraHdrItems = /* @__PURE__ */ new Set();
909 + function shouldPauseForSideload(item, operation, select2) {
910 + if (operation !== OperationType.Upload || !item.parentId || !item.additionalData.post) {
911 + return false;
912 + }
913 + return select2.isUploadingToPost(item.additionalData.post);
914 + }
2307 915 function addItem({
2308 916 file: fileOrBlob,
2309 917 batchId,
2310 918 onChange,
@@ -2340,8 +948,9 @@
2340 948 attachment: {
2341 949 url: blobUrl
2342 950 },
2343 951 additionalData: {
952 + convert_format: false,
2344 953 generate_sub_sizes: false,
2345 954 ...additionalData
2346 955 },
2347 956 onChange,
@@ -2405,8 +1014,15 @@
2405 1014 parentId
2406 1015 } = item;
2407 1016 const operation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
2408 1017 const operationArgs = Array.isArray(item.operations?.[0]) ? item.operations[0][1] : void 0;
1018 + if (shouldPauseForSideload(item, operation, select2)) {
1019 + dispatch({
1020 + type: Type.PauseItem,
1021 + id
1022 + });
1023 + return;
1024 + }
2409 1025 if (operation === OperationType.Upload) {
2410 1026 const settings = select2.getSettings();
2411 1027 const activeCount = select2.getActiveUploadCount();
2412 1028 if (activeCount >= settings.maxConcurrentUploads) {
@@ -2419,19 +1035,10 @@
2419 1035 if (activeCount >= settings.maxConcurrentImageProcessing) {
2420 1036 return;
2421 1037 }
2422 1038 }
2423 - if (operation === OperationType.TranscodeGif) {
2424 - const activeCount = select2.getActiveVideoProcessingCount();
2425 - if (activeCount >= 1) {
2426 - return;
2427 - }
2428 - }
2429 1039 if (attachment) {
2430 - const isHeicUrl = attachment.url && /\.hei[cf]$/i.test(attachment.url);
2431 - if (!isHeicUrl) {
2432 - onChange?.([attachment]);
2433 - }
1040 + onChange?.([attachment]);
2434 1041 }
2435 1042 if (!operation) {
2436 1043 if (parentId || !parentId && !select2.hasPendingItemsByParentId(id)) {
2437 1044 if (attachment) {
@@ -2447,12 +1054,8 @@
2447 1054 const parentItem = select2.getItem(parentId);
2448 1055 if (!parentItem) {
2449 1056 return;
2450 1057 }
2451 - if (parentItem.operations && parentItem.operations.length > 0) {
2452 - dispatch.processItem(parentId);
2453 - return;
2454 - }
2455 1058 if (attachment) {
2456 1059 parentItem.onSuccess?.([attachment]);
2457 1060 }
2458 1061 dispatch.removeItem(parentId);
@@ -2462,19 +1065,13 @@
2462 1065 }
2463 1066 }
2464 1067 return;
2465 1068 }
2466 - if (operation === OperationType.Finalize && select2.hasPendingItemsByParentId(id)) {
2467 - return;
2468 - }
2469 1069 dispatch({
2470 1070 type: Type.OperationStart,
2471 1071 id,
2472 1072 operation
2473 1073 });
2474 - debug(
2475 - `Starting operation ${operation} for ${item.file.name} (item ${item.id})`
2476 - );
2477 1074 switch (operation) {
2478 1075 case OperationType.Prepare:
2479 1076 dispatch.prepareItem(item.id);
2480 1077 break;
@@ -2495,14 +1092,8 @@
2495 1092 item.id,
2496 1093 operationArgs
2497 1094 );
2498 1095 break;
2499 - case OperationType.TranscodeGif:
2500 - dispatch.transcodeGifItem(
2501 - item.id,
2502 - operationArgs
2503 - );
2504 - break;
2505 1096 case OperationType.Upload:
2506 1097 if (item.parentId) {
2507 1098 dispatch.sideloadItem(id);
2508 1099 } else {
@@ -2511,14 +1102,8 @@
2511 1102 break;
2512 1103 case OperationType.ThumbnailGeneration:
2513 1104 dispatch.generateThumbnails(id);
2514 1105 break;
2515 - case OperationType.Finalize:
2516 - dispatch.finalizeItem(id);
2517 - break;
2518 - case OperationType.DetectUltraHdr:
2519 - dispatch.detectUltraHdr(id);
2520 - break;
2521 1106 }
2522 1107 };
2523 1108 }
2524 1109 function pauseQueue() {
@@ -2531,13 +1116,9 @@
2531 1116 dispatch({
2532 1117 type: Type.ResumeQueue
2533 1118 });
2534 1119 for (const item of select2.getAllItems()) {
2535 - if (item.status === ItemStatus.PendingRetry) {
2536 - dispatch.executeRetry(item.id);
2537 - } else {
2538 - dispatch.processItem(item.id);
2539 - }
1120 + dispatch.processItem(item.id);
2540 1121 }
2541 1122 };
2542 1123 }
2543 1124 function pauseItem(id) {
@@ -2547,8 +1128,20 @@
2547 1128 id
2548 1129 });
2549 1130 };
2550 1131 }
1132 + function resumeItemByPostId(postOrAttachmentId) {
1133 + return async ({ select: select2, dispatch }) => {
1134 + const item = select2.getPausedUploadForPost(postOrAttachmentId);
1135 + if (item) {
1136 + dispatch({
1137 + type: Type.ResumeItem,
1138 + id: item.id
1139 + });
1140 + dispatch.processItem(item.id);
1141 + }
1142 + };
1143 + }
2551 1144 function removeItem(id) {
2552 1145 return async ({ select: select2, dispatch }) => {
2553 1146 const item = select2.getItem(id);
2554 1147 if (!item) {
@@ -2553,10 +1146,8 @@
2553 1146 const item = select2.getItem(id);
2554 1147 if (!item) {
2555 1148 return;
2556 1149 }
2557 - ultraHdrItems.delete(id);
2558 - clearRetryTimer(id);
2559 1150 dispatch({
2560 1151 type: Type.Remove,
2561 1152 id
2562 1153 });
@@ -2561,9 +1152,8 @@
2561 1152 id
2562 1153 });
2563 1154 if (select2.getAllItems().length === 0) {
2564 1155 terminateVipsWorker();
2565 - terminateVideoConversionWorker();
2566 1156 }
2567 1157 };
2568 1158 }
2569 1159 function finishOperation(id, updates) {
@@ -2587,17 +1177,8 @@
2587 1177 for (const pendingItem of pendingItems) {
2588 1178 dispatch.processItem(pendingItem.id);
2589 1179 }
2590 1180 }
2591 - if (previousOperation === OperationType.TranscodeGif) {
2592 - const pendingItems = select2.getPendingVideoProcessing();
2593 - for (const pendingItem of pendingItems) {
2594 - dispatch.processItem(pendingItem.id);
2595 - }
2596 - }
2597 - if (previousOperation === OperationType.ResizeCrop || previousOperation === OperationType.Rotate || previousOperation === OperationType.TranscodeImage) {
2598 - maybeRecycleVipsWorker(select2.getActiveImageProcessingCount());
2599 - }
2600 1181 };
2601 1182 }
2602 1183 var VALID_IMAGE_FORMATS = ["jpeg", "webp", "avif", "png", "gif"];
2603 1184 function isValidImageFormat(format) {
@@ -2602,9 +1183,21 @@
2602 1183 var VALID_IMAGE_FORMATS = ["jpeg", "webp", "avif", "png", "gif"];
2603 1184 function isValidImageFormat(format) {
2604 1185 return VALID_IMAGE_FORMATS.includes(format);
2605 1186 }
2606 - async function getTranscodeImageOperation(file, outputMimeType, interlaced = false, quality = DEFAULT_OUTPUT_QUALITY) {
1187 + function getInterlacedSetting(outputMimeType, settings) {
1188 + switch (outputMimeType) {
1189 + case "image/jpeg":
1190 + return settings.jpegInterlaced ?? false;
1191 + case "image/png":
1192 + return settings.pngInterlaced ?? false;
1193 + case "image/gif":
1194 + return settings.gifInterlaced ?? false;
1195 + default:
1196 + return false;
1197 + }
1198 + }
1199 + async function getTranscodeImageOperation(file, outputMimeType, settings) {
2607 1200 if (file.type === "image/png" && outputMimeType === "image/jpeg") {
2608 1201 const blobUrl = (0, import_blob.createBlobURL)(file);
2609 1202 try {
2610 1203 const hasAlpha = await vipsHasTransparency(blobUrl);
@@ -2624,10 +1217,10 @@
2624 1217 return [
2625 1218 OperationType.TranscodeImage,
2626 1219 {
2627 1220 outputFormat: formatPart,
2628 - outputQuality: quality,
2629 - interlaced
1221 + outputQuality: DEFAULT_OUTPUT_QUALITY,
1222 + interlaced: getInterlacedSetting(outputMimeType, settings)
2630 1223 }
2631 1224 ];
2632 1225 }
2633 1226 function prepareItem(id) {
@@ -2638,86 +1231,28 @@
2638 1231 }
2639 1232 const { file } = item;
2640 1233 const operations = [];
2641 1234 const settings = select2.getSettings();
2642 - if (file.type === "image/gif" && settings.gifConvert !== false && typeof ImageDecoder !== "undefined" && typeof VideoEncoder !== "undefined") {
2643 - let isAnimated = false;
2644 - try {
2645 - isAnimated = isAnimatedGif(await file.arrayBuffer());
2646 - } catch {
2647 - isAnimated = false;
2648 - }
2649 - if (isAnimated) {
2650 - let hasTransparency = false;
2651 - const blobUrl = (0, import_blob.createBlobURL)(file);
2652 - try {
2653 - hasTransparency = await vipsHasTransparency(blobUrl);
2654 - } catch {
2655 - hasTransparency = true;
2656 - } finally {
2657 - (0, import_blob.revokeBlobURL)(blobUrl);
2658 - }
2659 - if (!hasTransparency) {
2660 - operations.push(
2661 - OperationType.Upload,
2662 - OperationType.ThumbnailGeneration,
2663 - OperationType.Finalize
2664 - );
2665 - dispatch({
2666 - type: Type.AddOperations,
2667 - id,
2668 - operations
2669 - });
2670 - dispatch.finishOperation(id, {
2671 - animatedGifFile: item.file
2672 - });
2673 - return;
2674 - }
2675 - }
2676 - }
2677 - let heicJpeg = null;
2678 1235 const isImage = file.type.startsWith("image/");
2679 1236 const isVipsSupported = CLIENT_SIDE_SUPPORTED_MIME_TYPES.includes(
2680 1237 file.type
2681 1238 );
2682 - const isHeic = HEIC_MIME_TYPES.includes(file.type);
2683 - let tooLargeForClient = false;
2684 1239 if (isImage && isVipsSupported) {
2685 - const dimensions = await getImageDimensions(file);
2686 - if (dimensions && exceedsClientProcessingMemory(dimensions)) {
2687 - tooLargeForClient = true;
2688 - }
2689 - }
2690 - if (file.type === "image/jpeg" && !tooLargeForClient) {
2691 - operations.push(OperationType.DetectUltraHdr);
2692 - }
2693 - if (isImage && isVipsSupported && !tooLargeForClient) {
2694 - operations.push(
2695 - OperationType.Upload,
2696 - OperationType.ThumbnailGeneration,
2697 - OperationType.Finalize
2698 - );
2699 - } else if (isImage && isHeic) {
2700 - try {
2701 - heicJpeg = await canvasConvertToJpeg(
1240 + const { imageOutputFormats } = settings;
1241 + const outputMimeType = imageOutputFormats?.[file.type];
1242 + if (outputMimeType && outputMimeType !== file.type) {
1243 + const transcodeOperation = await getTranscodeImageOperation(
2702 1244 file,
2703 - settings.imageQuality ?? DEFAULT_OUTPUT_QUALITY
1245 + outputMimeType,
1246 + settings
2704 1247 );
2705 - } catch {
2706 - dispatch.cancelItem(
2707 - id,
2708 - new UploadError({
2709 - code: ErrorCode.HEIC_DECODE_ERROR,
2710 - message: "This browser cannot decode HEIC images and the server does not support them either. Please convert to JPEG before uploading.",
2711 - file
2712 - })
2713 - );
2714 - return;
1248 + if (transcodeOperation) {
1249 + operations.push(transcodeOperation);
1250 + }
2715 1251 }
2716 1252 operations.push(
2717 1253 OperationType.Upload,
2718 - OperationType.ThumbnailGeneration,
2719 - OperationType.Finalize
1254 + OperationType.ThumbnailGeneration
2720 1255 );
2721 1256 } else {
2722 1257 operations.push(OperationType.Upload);
2723 1258 }
@@ -2725,58 +1260,17 @@
2725 1260 type: Type.AddOperations,
2726 1261 id,
2727 1262 operations
2728 1263 });
2729 - let updates;
2730 - if (isHeic && heicJpeg) {
2731 - const vipsAvailable = isClientSideMediaSupported();
2732 - updates = {
2733 - file: heicJpeg,
2734 - sourceFile: heicJpeg,
2735 - originalHeicFile: item.file,
2736 - additionalData: {
2737 - ...item.additionalData,
2738 - generate_sub_sizes: !vipsAvailable,
2739 - convert_format: true
2740 - }
2741 - };
2742 - } else if (!isVipsSupported || !isImage || tooLargeForClient) {
2743 - updates = {
2744 - additionalData: {
2745 - ...item.additionalData,
2746 - generate_sub_sizes: true,
2747 - convert_format: true
2748 - }
2749 - };
2750 - } else {
2751 - updates = {
2752 - additionalData: {
2753 - ...item.additionalData,
2754 - generate_sub_sizes: false
2755 - }
2756 - };
2757 - }
1264 + const updates = !isVipsSupported || !isImage ? {
1265 + additionalData: {
1266 + ...item.additionalData,
1267 + generate_sub_sizes: true
1268 + }
1269 + } : {};
2758 1270 dispatch.finishOperation(id, updates);
2759 1271 };
2760 1272 }
2761 - function detectUltraHdr(id) {
2762 - return async ({ select: select2, dispatch }) => {
2763 - const item = select2.getItem(id);
2764 - if (!item) {
2765 - return;
2766 - }
2767 - let info;
2768 - try {
2769 - const buffer = await item.file.arrayBuffer();
2770 - info = await vipsGetUltraHdrInfo(buffer);
2771 - } catch {
2772 - }
2773 - if (info) {
2774 - ultraHdrItems.add(id);
2775 - }
2776 - dispatch.finishOperation(id, {});
2777 - };
2778 - }
2779 1273 function uploadItem(id) {
2780 1274 return async ({ select: select2, dispatch }) => {
2781 1275 const item = select2.getItem(id);
2782 1276 if (!item) {
@@ -2781,42 +1275,23 @@
2781 1275 const item = select2.getItem(id);
2782 1276 if (!item) {
2783 1277 return;
2784 1278 }
2785 - const startTime = performance.now();
2786 - let finished = false;
2787 - const finishUpload = (attachment) => {
2788 - if (finished) {
2789 - return;
2790 - }
2791 - finished = true;
2792 - measure({
2793 - measureName: `Upload ${item.file.name}`,
2794 - startTime,
2795 - tooltipText: item.file.name,
2796 - properties: [
2797 - ["Item ID", item.id],
2798 - ["File name", item.file.name]
2799 - ]
2800 - });
2801 - dispatch.finishOperation(id, { attachment });
2802 - };
2803 1279 select2.getSettings().mediaUpload({
2804 1280 filesList: [item.file],
2805 1281 additionalData: item.additionalData,
2806 1282 signal: item.abortController?.signal,
2807 - // The queue's own items drive upload progress UI and save
2808 - // locking; without this, consumers that track uploads themselves
2809 - // (e.g. the editor's progress snackbar) would count this file a
2810 - // second time.
2811 - isTransportOnly: true,
2812 1283 onFileChange: ([attachment]) => {
2813 - if (attachment && !(0, import_blob.isBlobURL)(attachment.url)) {
2814 - finishUpload(attachment);
1284 + if (!(0, import_blob.isBlobURL)(attachment.url)) {
1285 + dispatch.finishOperation(id, {
1286 + attachment
1287 + });
2815 1288 }
2816 1289 },
2817 1290 onSuccess: ([attachment]) => {
2818 - finishUpload(attachment);
1291 + dispatch.finishOperation(id, {
1292 + attachment
1293 + });
2819 1294 },
2820 1295 onError: (error) => {
2821 1296 dispatch.cancelItem(id, error);
2822 1297 }
@@ -2834,35 +1309,20 @@
2834 1309 if (!mediaSideload) {
2835 1310 dispatch.finishOperation(id, {});
2836 1311 return;
2837 1312 }
2838 - const startTime = performance.now();
2839 1313 mediaSideload({
2840 1314 file: item.file,
2841 1315 attachmentId: post,
2842 1316 additionalData,
2843 1317 signal: item.abortController?.signal,
2844 - onSuccess: (subSize) => {
2845 - measure({
2846 - measureName: `Sideload ${item.file.name}`,
2847 - startTime,
2848 - tooltipText: item.file.name,
2849 - properties: [
2850 - ["Item ID", item.id],
2851 - ["File name", item.file.name]
2852 - ]
2853 - });
2854 - if (item.parentId) {
2855 - dispatch({
2856 - type: Type.AccumulateSubSize,
2857 - id: item.parentId,
2858 - subSize
2859 - });
2860 - }
2861 - dispatch.finishOperation(id, {});
1318 + onFileChange: ([attachment]) => {
1319 + dispatch.finishOperation(id, { attachment });
1320 + dispatch.resumeItemByPostId(post);
2862 1321 },
2863 1322 onError: (error) => {
2864 1323 dispatch.cancelItem(id, error);
1324 + dispatch.resumeItemByPostId(post);
2865 1325 }
2866 1326 });
2867 1327 };
2868 1328 }
@@ -2877,36 +1337,21 @@
2877 1337 file: item.file
2878 1338 });
2879 1339 return;
2880 1340 }
2881 - const startTime = performance.now();
2882 1341 const addSuffix = Boolean(item.parentId);
2883 1342 const scaledSuffix = Boolean(args.isThresholdResize);
2884 - const { imageStripMeta, imageMaxBitDepth } = select2.getSettings();
2885 1343 try {
2886 1344 const file = await vipsResizeImage(
2887 1345 item.id,
2888 1346 item.file,
2889 1347 args.resize,
2890 - {
2891 - smartCrop: false,
2892 - addSuffix,
2893 - signal: item.abortController?.signal,
2894 - scaledSuffix,
2895 - quality: args.quality,
2896 - stripMeta: imageStripMeta,
2897 - maxBitdepth: imageMaxBitDepth
2898 - }
1348 + false,
1349 + // smartCrop
1350 + addSuffix,
1351 + item.abortController?.signal,
1352 + scaledSuffix
2899 1353 );
2900 - measure({
2901 - measureName: `ResizeCrop ${item.file.name}`,
2902 - startTime,
2903 - tooltipText: item.file.name,
2904 - properties: [
2905 - ["Item ID", item.id],
2906 - ["File name", item.file.name]
2907 - ]
2908 - });
2909 1354 const blobUrl = (0, import_blob.createBlobURL)(file);
2910 1355 dispatch({
2911 1356 type: Type.CacheBlobUrl,
2912 1357 id,
@@ -2921,12 +1366,10 @@
2921 1366 } catch (error) {
2922 1367 dispatch.cancelItem(
2923 1368 id,
2924 1369 new UploadError({
2925 - code: ErrorCode.IMAGE_TRANSCODING_ERROR,
2926 - message: (0, import_i18n6.__)(
2927 - "The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading."
2928 - ),
1370 + code: "IMAGE_TRANSCODING_ERROR",
1371 + message: "File could not be uploaded",
2929 1372 file: item.file,
2930 1373 cause: error instanceof Error ? error : void 0
2931 1374 })
2932 1375 );
@@ -2944,9 +1387,8 @@
2944 1387 file: item.file
2945 1388 });
2946 1389 return;
2947 1390 }
2948 - const startTime = performance.now();
2949 1391 try {
2950 1392 const file = await vipsRotateImage(
2951 1393 item.id,
2952 1394 item.file,
@@ -2952,17 +1394,8 @@
2952 1394 item.file,
2953 1395 args.orientation,
2954 1396 item.abortController?.signal
2955 1397 );
2956 - measure({
2957 - measureName: `Rotate ${item.file.name}`,
2958 - startTime,
2959 - tooltipText: item.file.name,
2960 - properties: [
2961 - ["Item ID", item.id],
2962 - ["File name", item.file.name]
2963 - ]
2964 - });
2965 1398 const blobUrl = (0, import_blob.createBlobURL)(file);
2966 1399 dispatch({
2967 1400 type: Type.CacheBlobUrl,
2968 1401 id,
@@ -2977,12 +1410,10 @@
2977 1410 } catch (error) {
2978 1411 dispatch.cancelItem(
2979 1412 id,
2980 1413 new UploadError({
2981 - code: ErrorCode.IMAGE_ROTATION_ERROR,
2982 - message: (0, import_i18n6.__)(
2983 - "The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading."
2984 - ),
1414 + code: "IMAGE_ROTATION_ERROR",
1415 + message: "Image could not be rotated",
2985 1416 file: item.file,
2986 1417 cause: error instanceof Error ? error : void 0
2987 1418 })
2988 1419 );
@@ -3000,34 +1431,19 @@
3000 1431 file: item.file
3001 1432 });
3002 1433 return;
3003 1434 }
3004 - const startTime = performance.now();
3005 1435 const outputMimeType = `image/${args.outputFormat}`;
3006 1436 const quality = args.outputQuality ?? DEFAULT_OUTPUT_QUALITY;
3007 1437 const interlaced = args.interlaced ?? false;
3008 - const { imageStripMeta, imageMaxBitDepth } = select2.getSettings();
3009 1438 try {
3010 1439 const file = await vipsConvertImageFormat(
3011 1440 item.id,
3012 1441 item.file,
3013 1442 outputMimeType,
3014 - {
3015 - quality,
3016 - interlaced,
3017 - stripMeta: imageStripMeta,
3018 - maxBitdepth: imageMaxBitDepth
3019 - }
1443 + quality,
1444 + interlaced
3020 1445 );
3021 - measure({
3022 - measureName: `Transcode ${item.file.name}`,
3023 - startTime,
3024 - tooltipText: item.file.name,
3025 - properties: [
3026 - ["Item ID", item.id],
3027 - ["File name", item.file.name]
3028 - ]
3029 - });
3030 1446 const blobUrl = (0, import_blob.createBlobURL)(file);
3031 1447 dispatch({
3032 1448 type: Type.CacheBlobUrl,
3033 1449 id,
@@ -3042,9 +1458,9 @@
3042 1458 } catch (error) {
3043 1459 dispatch.cancelItem(
3044 1460 id,
3045 1461 new UploadError({
3046 - code: ErrorCode.MEDIA_TRANSCODING_ERROR,
1462 + code: "MEDIA_TRANSCODING_ERROR",
3047 1463 message: "Image could not be transcoded to the target format",
3048 1464 file: item.file,
3049 1465 cause: error instanceof Error ? error : void 0
3050 1466 })
@@ -3051,91 +1467,8 @@
3051 1467 );
3052 1468 }
3053 1469 };
3054 1470 }
3055 - function transcodeGifItem(id, args) {
3056 - return async ({ select: select2, dispatch }) => {
3057 - const item = select2.getItem(id);
3058 - if (!item) {
3059 - return;
3060 - }
3061 - const outputFormat = args?.outputFormat ?? "mp4";
3062 - const outputMimeType = `video/${outputFormat}`;
3063 - const gifFile = item.file;
3064 - try {
3065 - const file = await convertGifToVideo(
3066 - item.id,
3067 - gifFile,
3068 - outputMimeType,
3069 - {
3070 - timeout: args?.timeout,
3071 - maxTotalPixels: args?.maxTotalPixels
3072 - }
3073 - );
3074 - dispatch.finishOperation(id, { file });
3075 - dispatch.addSideloadItem({
3076 - file: gifFile,
3077 - batchId: v4_default(),
3078 - parentId: item.parentId,
3079 - additionalData: {
3080 - post: item.additionalData?.post,
3081 - image_size: "animated_video_poster",
3082 - convert_format: false
3083 - },
3084 - operations: [
3085 - [
3086 - OperationType.TranscodeImage,
3087 - {
3088 - outputFormat: "jpeg",
3089 - outputQuality: DEFAULT_OUTPUT_QUALITY,
3090 - interlaced: false
3091 - }
3092 - ],
3093 - OperationType.Upload
3094 - ]
3095 - });
3096 - } catch (error) {
3097 - if (isUnsupportedConversionError(error)) {
3098 - if (isSizeLimitConversionError(error)) {
3099 - debug(
3100 - `Skipping GIF to video conversion: ${error instanceof Error ? error.message : error}`
3101 - );
3102 - }
3103 - dispatch.cancelItem(
3104 - id,
3105 - new Error("Animated GIF conversion unsupported"),
3106 - true
3107 - );
3108 - return;
3109 - }
3110 - if (isConversionTimeoutError(error)) {
3111 - debug(
3112 - `GIF to video conversion timed out; keeping the original GIF only: ${error instanceof Error ? error.message : error}`
3113 - );
3114 - dispatch.cancelItem(
3115 - id,
3116 - new Error("Animated GIF conversion timed out"),
3117 - true
3118 - );
3119 - return;
3120 - }
3121 - console.error(
3122 - "[video-conversion] GIF to video conversion failed:",
3123 - error
3124 - );
3125 - dispatch.cancelItem(
3126 - id,
3127 - new UploadError({
3128 - code: ErrorCode.GIF_TRANSCODING_ERROR,
3129 - message: "Animated GIF could not be converted to video",
3130 - file: item.file,
3131 - cause: error instanceof Error ? error : void 0
3132 - }),
3133 - true
3134 - );
3135 - }
3136 - };
3137 - }
3138 1471 function generateThumbnails(id) {
3139 1472 return async ({ select: select2, dispatch }) => {
3140 1473 const item = select2.getItem(id);
3141 1474 if (!item) {
@@ -3145,74 +1478,19 @@
3145 1478 dispatch.finishOperation(id, {});
3146 1479 return;
3147 1480 }
3148 1481 const attachment = item.attachment;
3149 - const settings = select2.getSettings();
3150 - if (item.originalHeicFile && attachment.id) {
3151 - dispatch.addSideloadItem({
3152 - file: item.originalHeicFile,
3153 - batchId: v4_default(),
3154 - parentId: item.id,
3155 - additionalData: {
3156 - post: attachment.id,
3157 - image_size: "source_original",
3158 - convert_format: false
3159 - },
3160 - operations: [OperationType.Upload]
3161 - });
3162 - }
3163 - if (item.animatedGifFile && attachment.id) {
3164 - const outputFormat = settings.videoOutputFormat === "video/webm" ? "webm" : "mp4";
3165 - dispatch.addSideloadItem({
3166 - file: item.animatedGifFile,
3167 - batchId: v4_default(),
3168 - parentId: item.id,
3169 - additionalData: {
3170 - post: attachment.id,
3171 - image_size: "animated_video",
3172 - convert_format: false
3173 - },
3174 - operations: [
3175 - [
3176 - OperationType.TranscodeGif,
3177 - {
3178 - outputFormat
3179 - }
3180 - ],
3181 - OperationType.Upload
3182 - ]
3183 - });
3184 - }
3185 - let exifOrientation = attachment.exif_orientation || 1;
3186 - const sourceType = item.sourceFile.type;
3187 - const isHeifFamily = sourceType === "image/avif" || sourceType === "image/heif";
3188 - let needsClientRotation = false;
3189 - if (isHeifFamily) {
3190 - exifOrientation = getUnappliedExifOrientation(
3191 - await item.sourceFile.arrayBuffer()
3192 - );
3193 - needsClientRotation = exifOrientation !== 1;
3194 - }
3195 - let rotatedSource;
3196 - {
3197 - const needsRotation = exifOrientation !== 1 && !item.file.name.includes("-scaled");
3198 - if ((needsRotation || needsClientRotation) && attachment.id) {
3199 - try {
3200 - rotatedSource = await vipsRotateImage(
3201 - item.id,
3202 - item.sourceFile,
3203 - exifOrientation,
3204 - item.abortController?.signal
3205 - );
3206 - } catch {
3207 - console.warn(
3208 - "Failed to rotate image, continuing with thumbnails"
3209 - );
3210 - }
3211 - }
3212 - if (needsRotation && rotatedSource && attachment.id) {
1482 + const needsRotation = attachment.exif_orientation && attachment.exif_orientation !== 1 && !item.file.name.includes("-scaled");
1483 + if (needsRotation && attachment.id) {
1484 + try {
1485 + const rotatedFile = await vipsRotateImage(
1486 + item.id,
1487 + item.sourceFile,
1488 + attachment.exif_orientation,
1489 + item.abortController?.signal
1490 + );
3213 1491 dispatch.addSideloadItem({
3214 - file: rotatedSource,
1492 + file: rotatedFile,
3215 1493 batchId: v4_default(),
3216 1494 parentId: item.id,
3217 1495 additionalData: {
3218 1496 post: attachment.id,
@@ -3220,40 +1498,31 @@
3220 1498 convert_format: false
3221 1499 },
3222 1500 operations: [OperationType.Upload]
3223 1501 });
1502 + } catch {
1503 + console.warn(
1504 + "Failed to rotate image, continuing with thumbnails"
1505 + );
3224 1506 }
3225 1507 }
3226 1508 if (!item.parentId && attachment.missing_image_sizes && attachment.missing_image_sizes.length > 0) {
1509 + const file = attachment.filename ? renameFile(item.sourceFile, attachment.filename) : item.sourceFile;
1510 + const batchId = v4_default();
1511 + const settings = select2.getSettings();
3227 1512 const allImageSizes = settings.allImageSizes || {};
3228 - const sizesToGenerate = attachment.missing_image_sizes;
3229 - const thumbnailSource = needsClientRotation && rotatedSource ? rotatedSource : item.sourceFile;
3230 - const file = attachment.filename ? renameFile(thumbnailSource, attachment.filename) : thumbnailSource;
3231 - const batchId = v4_default();
3232 - const isUltraHdr = ultraHdrItems.has(item.id);
3233 - const outputMimeType = attachment.image_output_format;
3234 - const interlaced = attachment.image_save_progressive ?? false;
3235 - const imageQuality = attachment.image_quality;
3236 - const fallbackQuality = settings.imageQuality ?? DEFAULT_OUTPUT_QUALITY;
3237 - const defaultQuality = typeof imageQuality?.default === "number" ? imageQuality.default / 100 : fallbackQuality;
3238 - const qualityForSize = (sizeName) => {
3239 - const sized = imageQuality?.sizes?.[sizeName];
3240 - if (typeof sized === "number") {
3241 - return sized / 100;
3242 - }
3243 - return defaultQuality;
3244 - };
1513 + const { imageOutputFormats } = settings;
1514 + const sourceType = item.sourceFile.type;
1515 + const outputMimeType = imageOutputFormats?.[sourceType];
3245 1516 let thumbnailTranscodeOperation = null;
3246 - if (!isUltraHdr && outputMimeType) {
1517 + if (outputMimeType && outputMimeType !== sourceType) {
3247 1518 thumbnailTranscodeOperation = await getTranscodeImageOperation(
3248 - thumbnailSource,
1519 + item.sourceFile,
3249 1520 outputMimeType,
3250 - interlaced,
3251 - defaultQuality
1521 + settings
3252 1522 );
3253 1523 }
3254 - const dimensionGroups = /* @__PURE__ */ new Map();
3255 - for (const name of sizesToGenerate) {
1524 + for (const name of attachment.missing_image_sizes) {
3256 1525 const imageSize = allImageSizes[name];
3257 1526 if (!imageSize) {
3258 1527 console.warn(
3259 1528 `Image size "${name}" not found in configuration`
@@ -3259,38 +1528,23 @@
3259 1528 `Image size "${name}" not found in configuration`
3260 1529 );
3261 1530 continue;
3262 1531 }
3263 - const key = `${imageSize.width}x${imageSize.height}x${imageSize.crop}`;
3264 - const group = dimensionGroups.get(key);
3265 - if (group) {
3266 - group.push(name);
3267 - } else {
3268 - dimensionGroups.set(key, [name]);
3269 - }
3270 - }
3271 - for (const [, names] of dimensionGroups) {
3272 - const imageSize = allImageSizes[names[0]];
3273 - const sizeQuality = qualityForSize(names[0]);
3274 1532 const thumbnailOperations = [
3275 - [
3276 - OperationType.ResizeCrop,
3277 - { resize: imageSize, quality: sizeQuality }
3278 - ]
1533 + [OperationType.ResizeCrop, { resize: imageSize }]
3279 1534 ];
3280 - if (!isUltraHdr && thumbnailTranscodeOperation) {
3281 - thumbnailOperations.push([
3282 - thumbnailTranscodeOperation[0],
3283 - {
3284 - ...thumbnailTranscodeOperation[1],
3285 - outputQuality: sizeQuality
3286 - }
3287 - ]);
1535 + if (thumbnailTranscodeOperation) {
1536 + thumbnailOperations.push(thumbnailTranscodeOperation);
3288 1537 }
3289 1538 thumbnailOperations.push(OperationType.Upload);
3290 - const imageSizeParam = names.length === 1 ? names[0] : names;
3291 1539 dispatch.addSideloadItem({
3292 1540 file,
1541 + onChange: ([updatedAttachment]) => {
1542 + if ((0, import_blob.isBlobURL)(updatedAttachment.url)) {
1543 + return;
1544 + }
1545 + item.onChange?.([updatedAttachment]);
1546 + },
3293 1547 batchId,
3294 1548 parentId: item.id,
3295 1549 additionalData: {
3296 1550 // Sideloading does not use the parent post ID but the
@@ -3295,53 +1549,54 @@
3295 1549 additionalData: {
3296 1550 // Sideloading does not use the parent post ID but the
3297 1551 // attachment ID as the image sizes need to be added to it.
3298 1552 post: attachment.id,
3299 - image_size: imageSizeParam,
1553 + image_size: name,
3300 1554 convert_format: false
3301 1555 },
3302 1556 operations: thumbnailOperations
3303 1557 });
3304 1558 }
3305 - {
3306 - const { bigImageSizeThreshold } = settings;
3307 - if (bigImageSizeThreshold && attachment.id) {
3308 - const bitmap = await createImageBitmap(thumbnailSource);
3309 - const needsScaling = bitmap.width > bigImageSizeThreshold || bitmap.height > bigImageSizeThreshold;
3310 - bitmap.close();
3311 - if (needsScaling) {
3312 - const sourceForScaled = attachment.filename ? renameFile(thumbnailSource, attachment.filename) : thumbnailSource;
3313 - const scaledOperations = [
3314 - [
3315 - OperationType.ResizeCrop,
3316 - {
3317 - resize: {
3318 - width: bigImageSizeThreshold,
3319 - height: bigImageSizeThreshold
3320 - },
3321 - isThresholdResize: true,
3322 - quality: defaultQuality
3323 - }
3324 - ]
3325 - ];
3326 - if (!isUltraHdr && thumbnailTranscodeOperation) {
3327 - scaledOperations.push(
3328 - thumbnailTranscodeOperation
3329 - );
3330 - }
3331 - scaledOperations.push(OperationType.Upload);
3332 - dispatch.addSideloadItem({
3333 - file: sourceForScaled,
3334 - batchId,
3335 - parentId: item.id,
3336 - additionalData: {
3337 - post: attachment.id,
3338 - image_size: "scaled",
3339 - convert_format: false
3340 - },
3341 - operations: scaledOperations
3342 - });
1559 + const { bigImageSizeThreshold } = settings;
1560 + if (bigImageSizeThreshold && attachment.id) {
1561 + const bitmap = await createImageBitmap(item.sourceFile);
1562 + const needsScaling = bitmap.width > bigImageSizeThreshold || bitmap.height > bigImageSizeThreshold;
1563 + bitmap.close();
1564 + if (needsScaling) {
1565 + const sourceForScaled = attachment.filename ? renameFile(item.sourceFile, attachment.filename) : item.sourceFile;
1566 + const scaledOperations = [
1567 + [
1568 + OperationType.ResizeCrop,
1569 + {
1570 + resize: {
1571 + width: bigImageSizeThreshold,
1572 + height: bigImageSizeThreshold
1573 + },
1574 + isThresholdResize: true
1575 + }
1576 + ]
1577 + ];
1578 + if (thumbnailTranscodeOperation) {
1579 + scaledOperations.push(thumbnailTranscodeOperation);
3343 1580 }
1581 + scaledOperations.push(OperationType.Upload);
1582 + dispatch.addSideloadItem({
1583 + file: sourceForScaled,
1584 + onChange: ([updatedAttachment]) => {
1585 + if ((0, import_blob.isBlobURL)(updatedAttachment.url)) {
1586 + return;
1587 + }
1588 + item.onChange?.([updatedAttachment]);
1589 + },
1590 + batchId,
1591 + parentId: item.id,
1592 + additionalData: {
1593 + post: attachment.id,
1594 + image_size: "scaled",
1595 + convert_format: false
1596 + },
1597 + operations: scaledOperations
1598 + });
3344 1599 }
3345 1600 }
3346 1601 }
3347 1602 dispatch.finishOperation(id, {});
@@ -3346,33 +1601,8 @@
3346 1601 }
3347 1602 dispatch.finishOperation(id, {});
3348 1603 };
3349 1604 }
3350 - function finalizeItem(id) {
3351 - return async ({ select: select2, dispatch }) => {
3352 - const item = select2.getItem(id);
3353 - if (!item) {
3354 - return;
3355 - }
3356 - const attachment = item.attachment;
3357 - const { mediaFinalize } = select2.getSettings();
3358 - const updates = {};
3359 - if (attachment?.id && mediaFinalize) {
3360 - try {
3361 - const updatedAttachment = await mediaFinalize(
3362 - attachment.id,
3363 - item.subSizes || []
3364 - );
3365 - if (updatedAttachment) {
3366 - updates.attachment = updatedAttachment;
3367 - }
3368 - } catch (error) {
3369 - console.warn("Media finalization failed:", error);
3370 - }
3371 - }
3372 - dispatch.finishOperation(id, updates);
3373 - };
3374 - }
3375 1605 function revokeBlobUrls(id) {
3376 1606 return async ({ select: select2, dispatch }) => {
3377 1607 const blobUrls = select2.getBlobUrls(id);
3378 1608 for (const blobUrl of blobUrls) {
@@ -3474,103 +1704,103 @@
3474 1704 return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
3475 1705 });
3476 1706 var provider_default = MediaUploadProvider;
3477 1707
3478 - // packages/upload-media/build-module/error-messages.mjs
3479 - var import_i18n7 = __toESM(require_i18n(), 1);
3480 - function getErrorMessage(code, fileName) {
3481 - const messages = {
3482 - [ErrorCode.EMPTY_FILE]: {
3483 - title: (0, import_i18n7.__)("Empty file"),
3484 - description: (0, import_i18n7.sprintf)(
3485 - /* translators: %s: file name */
3486 - (0, import_i18n7.__)('"%s" is empty.'),
3487 - fileName
3488 - ),
3489 - action: (0, import_i18n7.__)("Please choose a different file.")
3490 - },
3491 - [ErrorCode.SIZE_ABOVE_LIMIT]: {
3492 - title: (0, import_i18n7.__)("File too large"),
3493 - description: (0, import_i18n7.sprintf)(
3494 - /* translators: %s: file name */
3495 - (0, import_i18n7.__)('"%s" exceeds the maximum upload size.'),
3496 - fileName
3497 - ),
3498 - action: (0, import_i18n7.__)("Please reduce the file size and try again.")
3499 - },
3500 - [ErrorCode.MIME_TYPE_NOT_SUPPORTED]: {
3501 - title: (0, import_i18n7.__)("Unsupported file type"),
3502 - description: (0, import_i18n7.sprintf)(
3503 - /* translators: %s: file name */
3504 - (0, import_i18n7.__)('"%s" is not a supported file type.'),
3505 - fileName
3506 - ),
3507 - action: (0, import_i18n7.__)("Please upload a different file format.")
3508 - },
3509 - [ErrorCode.MIME_TYPE_NOT_ALLOWED_FOR_USER]: {
3510 - title: (0, import_i18n7.__)("File type not allowed"),
3511 - description: (0, import_i18n7.sprintf)(
3512 - /* translators: %s: file name */
3513 - (0, import_i18n7.__)('You are not allowed to upload "%s".'),
3514 - fileName
3515 - ),
3516 - action: (0, import_i18n7.__)("Please contact your site administrator.")
3517 - },
3518 - [ErrorCode.HEIC_DECODE_ERROR]: {
3519 - title: (0, import_i18n7.__)("HEIC decode failed"),
3520 - description: (0, import_i18n7.sprintf)(
3521 - /* translators: %s: file name */
3522 - (0, import_i18n7.__)('Failed to decode HEIC file "%s".'),
3523 - fileName
3524 - ),
3525 - action: (0, import_i18n7.__)("Try converting the image to JPEG or PNG first.")
3526 - },
3527 - [ErrorCode.IMAGE_TRANSCODING_ERROR]: {
3528 - title: (0, import_i18n7.__)("Image processing failed"),
3529 - description: (0, import_i18n7.sprintf)(
3530 - /* translators: %s: file name */
3531 - (0, import_i18n7.__)('Failed to process "%s".'),
3532 - fileName
3533 - ),
3534 - action: (0, import_i18n7.__)("The image may be corrupted. Try a different file.")
3535 - },
3536 - [ErrorCode.IMAGE_ROTATION_ERROR]: {
3537 - title: (0, import_i18n7.__)("Image rotation failed"),
3538 - description: (0, import_i18n7.sprintf)(
3539 - /* translators: %s: file name */
3540 - (0, import_i18n7.__)('Failed to rotate "%s".'),
3541 - fileName
3542 - ),
3543 - action: (0, import_i18n7.__)("The image may be corrupted. Try a different file.")
3544 - },
3545 - [ErrorCode.MEDIA_TRANSCODING_ERROR]: {
3546 - title: (0, import_i18n7.__)("Media processing failed"),
3547 - description: (0, import_i18n7.sprintf)(
3548 - /* translators: %s: file name */
3549 - (0, import_i18n7.__)('Failed to convert "%s" to the target format.'),
3550 - fileName
3551 - ),
3552 - action: (0, import_i18n7.__)("The file may be corrupted. Try a different file.")
3553 - },
3554 - [ErrorCode.GENERAL]: {
3555 - title: (0, import_i18n7.__)("Upload failed"),
3556 - description: (0, import_i18n7.sprintf)(
3557 - /* translators: %s: file name */
3558 - (0, import_i18n7.__)('Failed to upload "%s".'),
3559 - fileName
3560 - ),
3561 - action: (0, import_i18n7.__)("Please try again.")
1708 + // packages/upload-media/build-module/feature-detection.mjs
1709 + var cachedResult = null;
1710 + function detectClientSideMediaSupport() {
1711 + if (cachedResult !== null) {
1712 + return cachedResult;
1713 + }
1714 + if (typeof WebAssembly === "undefined") {
1715 + cachedResult = {
1716 + supported: false,
1717 + reason: "WebAssembly is not supported in this browser."
1718 + };
1719 + return cachedResult;
1720 + }
1721 + if (typeof SharedArrayBuffer === "undefined") {
1722 + cachedResult = {
1723 + supported: false,
1724 + reason: "SharedArrayBuffer is not available. This may be due to missing cross-origin isolation headers."
1725 + };
1726 + return cachedResult;
1727 + }
1728 + if (typeof Worker === "undefined") {
1729 + cachedResult = {
1730 + supported: false,
1731 + reason: "Web Workers are not supported in this browser."
1732 + };
1733 + return cachedResult;
1734 + }
1735 + if (typeof window !== "undefined" && window.HTMLIFrameElement && !("credentialless" in window.HTMLIFrameElement.prototype)) {
1736 + cachedResult = {
1737 + supported: false,
1738 + reason: "Browser does not support credentialless iframes. Cross-origin isolation would break third-party embeds"
1739 + };
1740 + return cachedResult;
1741 + }
1742 + if (typeof navigator !== "undefined" && "deviceMemory" in navigator && navigator.deviceMemory <= 2) {
1743 + cachedResult = {
1744 + supported: false,
1745 + reason: "Device has insufficient memory for client-side media processing."
1746 + };
1747 + return cachedResult;
1748 + }
1749 + if (typeof navigator !== "undefined" && "hardwareConcurrency" in navigator && navigator.hardwareConcurrency < 4) {
1750 + cachedResult = {
1751 + supported: false,
1752 + reason: "Device has insufficient CPU cores for client-side media processing."
1753 + };
1754 + return cachedResult;
1755 + }
1756 + if (typeof navigator !== "undefined") {
1757 + const connection = navigator.connection;
1758 + if (connection) {
1759 + if (connection.saveData) {
1760 + cachedResult = {
1761 + supported: false,
1762 + reason: "Data saver mode is enabled."
1763 + };
1764 + return cachedResult;
1765 + }
1766 + if (connection.effectiveType === "slow-2g" || connection.effectiveType === "2g" || connection.effectiveType === "3g") {
1767 + cachedResult = {
1768 + supported: false,
1769 + reason: "Network connection is too slow for client-side media processing."
1770 + };
1771 + return cachedResult;
1772 + }
3562 1773 }
3563 - };
3564 - return messages[code] || {
3565 - title: (0, import_i18n7.__)("Upload failed"),
3566 - description: (0, import_i18n7.sprintf)(
3567 - /* translators: %s: file name */
3568 - (0, import_i18n7.__)('Failed to upload "%s".'),
3569 - fileName
3570 - ),
3571 - action: (0, import_i18n7.__)("Please try again.")
3572 - };
1774 + }
1775 + if (typeof window !== "undefined") {
1776 + try {
1777 + const testBlob = new Blob([""], {
1778 + type: "application/javascript"
1779 + });
1780 + const testUrl = URL.createObjectURL(testBlob);
1781 + try {
1782 + const testWorker = new Worker(testUrl);
1783 + testWorker.terminate();
1784 + } finally {
1785 + URL.revokeObjectURL(testUrl);
1786 + }
1787 + } catch {
1788 + cachedResult = {
1789 + supported: false,
1790 + reason: "The site's Content Security Policy (CSP) does not allow blob: workers. The worker-src directive must include blob: to enable client-side media processing."
1791 + };
1792 + return cachedResult;
1793 + }
1794 + }
1795 + cachedResult = { supported: true };
1796 + return cachedResult;
1797 + }
1798 + function isClientSideMediaSupported() {
1799 + return detectClientSideMediaSupport().supported;
1800 + }
1801 + function clearFeatureDetectionCache() {
1802 + cachedResult = null;
3573 1803 }
3574 1804 return __toCommonJS(index_exports);
3575 1805 })();
3576 1806 //# sourceMappingURL=index.js.map