PluginProbe
Gutenberg / 23.7.2
Gutenberg v23.7.2
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 7.4.0 All 402 releases
gutenberg / build / scripts / upload-media / index.js

index.js in Gutenberg 23.7.2, at build/scripts/upload-media/index.js

3,577 lines 110.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use strict";
2 var wp;
3 (wp ||= {}).uploadMedia = (() => {
4 var __create = Object.create;
5 var __defProp = Object.defineProperty;
6 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7 var __getOwnPropNames = Object.getOwnPropertyNames;
8 var __getProtoOf = Object.getPrototypeOf;
9 var __hasOwnProp = Object.prototype.hasOwnProperty;
10 var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
11 get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
12 }) : x)(function(x) {
13 if (typeof require !== "undefined") return require.apply(this, arguments);
14 throw Error('Dynamic require of "' + x + '" is not supported');
15 });
16 var __commonJS = (cb, mod) => function __require2() {
17 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
18 };
19 var __export = (target, all) => {
20 for (var name in all)
21 __defProp(target, name, { get: all[name], enumerable: true });
22 };
23 var __copyProps = (to, from, except, desc) => {
24 if (from && typeof from === "object" || typeof from === "function") {
25 for (let key of __getOwnPropNames(from))
26 if (!__hasOwnProp.call(to, key) && key !== except)
27 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
28 }
29 return to;
30 };
31 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
32 // If the importer is in node compatibility mode or this is not an ESM
33 // file that has been converted to a CommonJS file using a Babel-
34 // compatible transform (i.e. "__esModule" has not been set), then set
35 // "default" to the CommonJS "module.exports" for node compatibility.
36 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
37 mod
38 ));
39 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
40
41 // package-external:@wordpress/data
42 var require_data = __commonJS({
43 "package-external:@wordpress/data"(exports, module) {
44 module.exports = window.wp.data;
45 }
46 });
47
48 // package-external:@wordpress/i18n
49 var require_i18n = __commonJS({
50 "package-external:@wordpress/i18n"(exports, module) {
51 module.exports = window.wp.i18n;
52 }
53 });
54
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 // package-external:@wordpress/blob
63 var require_blob = __commonJS({
64 "package-external:@wordpress/blob"(exports, module) {
65 module.exports = window.wp.blob;
66 }
67 });
68
69 // package-external:@wordpress/private-apis
70 var require_private_apis = __commonJS({
71 "package-external:@wordpress/private-apis"(exports, module) {
72 module.exports = window.wp.privateApis;
73 }
74 });
75
76 // package-external:@wordpress/element
77 var require_element = __commonJS({
78 "package-external:@wordpress/element"(exports, module) {
79 module.exports = window.wp.element;
80 }
81 });
82
83 // package-external:@wordpress/compose
84 var require_compose = __commonJS({
85 "package-external:@wordpress/compose"(exports, module) {
86 module.exports = window.wp.compose;
87 }
88 });
89
90 // vendor-external:react/jsx-runtime
91 var require_jsx_runtime = __commonJS({
92 "vendor-external:react/jsx-runtime"(exports, module) {
93 module.exports = window.ReactJSXRuntime;
94 }
95 });
96
97 // packages/upload-media/build-module/index.mjs
98 var index_exports = {};
99 __export(index_exports, {
100 ErrorCode: () => ErrorCode,
101 MediaUploadProvider: () => provider_default,
102 UploadError: () => UploadError,
103 clearFeatureDetectionCache: () => clearFeatureDetectionCache,
104 detectClientSideMediaSupport: () => detectClientSideMediaSupport,
105 getErrorMessage: () => getErrorMessage,
106 isClientSideMediaSupported: () => isClientSideMediaSupported,
107 isHeicCanvasSupported: () => isHeicCanvasSupported,
108 store: () => store
109 });
110
111 // packages/upload-media/build-module/store/index.mjs
112 var import_data = __toESM(require_data(), 1);
113
114 // packages/upload-media/build-module/store/types.mjs
115 var Type = /* @__PURE__ */ ((Type2) => {
116 Type2["Unknown"] = "REDUX_UNKNOWN";
117 Type2["Add"] = "ADD_ITEM";
118 Type2["Prepare"] = "PREPARE_ITEM";
119 Type2["Cancel"] = "CANCEL_ITEM";
120 Type2["Remove"] = "REMOVE_ITEM";
121 Type2["RetryItem"] = "RETRY_ITEM";
122 Type2["ScheduleRetry"] = "SCHEDULE_RETRY";
123 Type2["PauseItem"] = "PAUSE_ITEM";
124 Type2["ResumeItem"] = "RESUME_ITEM";
125 Type2["PauseQueue"] = "PAUSE_QUEUE";
126 Type2["ResumeQueue"] = "RESUME_QUEUE";
127 Type2["OperationStart"] = "OPERATION_START";
128 Type2["OperationFinish"] = "OPERATION_FINISH";
129 Type2["AddOperations"] = "ADD_OPERATIONS";
130 Type2["CacheBlobUrl"] = "CACHE_BLOB_URL";
131 Type2["RevokeBlobUrls"] = "REVOKE_BLOB_URLS";
132 Type2["UpdateProgress"] = "UPDATE_PROGRESS";
133 Type2["AccumulateSubSize"] = "ACCUMULATE_SUB_SIZE";
134 Type2["UpdateSettings"] = "UPDATE_SETTINGS";
135 return Type2;
136 })(Type || {});
137 var ItemStatus = /* @__PURE__ */ ((ItemStatus2) => {
138 ItemStatus2["Queued"] = "QUEUED";
139 ItemStatus2["Processing"] = "PROCESSING";
140 ItemStatus2["Paused"] = "PAUSED";
141 ItemStatus2["PendingRetry"] = "PENDING_RETRY";
142 ItemStatus2["Uploaded"] = "UPLOADED";
143 ItemStatus2["Error"] = "ERROR";
144 return ItemStatus2;
145 })(ItemStatus || {});
146 var OperationType = /* @__PURE__ */ ((OperationType2) => {
147 OperationType2["Prepare"] = "PREPARE";
148 OperationType2["Upload"] = "UPLOAD";
149 OperationType2["ResizeCrop"] = "RESIZE_CROP";
150 OperationType2["Rotate"] = "ROTATE";
151 OperationType2["TranscodeImage"] = "TRANSCODE_IMAGE";
152 OperationType2["TranscodeGif"] = "TRANSCODE_GIF";
153 OperationType2["ThumbnailGeneration"] = "THUMBNAIL_GENERATION";
154 OperationType2["Finalize"] = "FINALIZE";
155 OperationType2["DetectUltraHdr"] = "DETECT_ULTRAHDR";
156 return OperationType2;
157 })(OperationType || {});
158
159 // packages/upload-media/build-module/store/constants.mjs
160 var STORE_NAME = "core/upload-media";
161 var DEFAULT_MAX_CONCURRENT_UPLOADS = 5;
162 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 var CLIENT_SIDE_SUPPORTED_MIME_TYPES = [
171 "image/jpeg",
172 "image/png",
173 "image/gif",
174 "image/webp",
175 "image/avif"
176 ];
177 var HEIC_MIME_TYPES = [
178 "image/heic",
179 "image/heif"
180 ];
181
182 // packages/upload-media/build-module/store/reducer.mjs
183 var noop = () => {
184 };
185 var DEFAULT_STATE = {
186 queue: [],
187 queueStatus: "active",
188 blobUrls: {},
189 settings: {
190 mediaUpload: noop,
191 maxConcurrentUploads: DEFAULT_MAX_CONCURRENT_UPLOADS,
192 maxConcurrentImageProcessing: DEFAULT_MAX_CONCURRENT_IMAGE_PROCESSING,
193 retry: { ...DEFAULT_RETRY_SETTINGS }
194 }
195 };
196 function reducer(state = DEFAULT_STATE, action = { type: Type.Unknown }) {
197 switch (action.type) {
198 case Type.PauseQueue: {
199 return {
200 ...state,
201 queueStatus: "paused"
202 };
203 }
204 case Type.ResumeQueue: {
205 return {
206 ...state,
207 queueStatus: "active"
208 };
209 }
210 case Type.PauseItem:
211 return {
212 ...state,
213 queue: state.queue.map(
214 (item) => item.id === action.id ? {
215 ...item,
216 status: ItemStatus.Paused
217 } : item
218 )
219 };
220 case Type.ResumeItem:
221 return {
222 ...state,
223 queue: state.queue.map(
224 (item) => item.id === action.id ? {
225 ...item,
226 status: ItemStatus.Processing
227 } : item
228 )
229 };
230 case Type.Add:
231 return {
232 ...state,
233 queue: [...state.queue, action.item]
234 };
235 case Type.Cancel:
236 return {
237 ...state,
238 queue: state.queue.map(
239 (item) => item.id === action.id ? {
240 ...item,
241 error: action.error
242 } : item
243 )
244 };
245 case Type.RetryItem:
246 return {
247 ...state,
248 queue: state.queue.map(
249 (item) => item.id === action.id ? {
250 ...item,
251 status: ItemStatus.Processing,
252 error: void 0,
253 retryCount: (item.retryCount ?? 0) + 1,
254 abortController: new AbortController()
255 } : item
256 )
257 };
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 case Type.Remove:
272 return {
273 ...state,
274 queue: state.queue.filter((item) => item.id !== action.id)
275 };
276 case Type.OperationStart: {
277 return {
278 ...state,
279 queue: state.queue.map(
280 (item) => item.id === action.id ? {
281 ...item,
282 currentOperation: action.operation
283 } : item
284 )
285 };
286 }
287 case Type.AddOperations:
288 return {
289 ...state,
290 queue: state.queue.map((item) => {
291 if (item.id !== action.id) {
292 return item;
293 }
294 return {
295 ...item,
296 operations: [
297 ...item.operations || [],
298 ...action.operations
299 ]
300 };
301 })
302 };
303 case Type.OperationFinish:
304 return {
305 ...state,
306 queue: state.queue.map((item) => {
307 if (item.id !== action.id) {
308 return item;
309 }
310 const operations = item.operations ? item.operations.slice(1) : [];
311 const attachment = item.attachment || action.item.attachment ? {
312 ...item.attachment,
313 ...action.item.attachment
314 } : void 0;
315 return {
316 ...item,
317 currentOperation: void 0,
318 operations,
319 ...action.item,
320 attachment,
321 additionalData: {
322 ...item.additionalData,
323 ...action.item.additionalData
324 }
325 };
326 })
327 };
328 case Type.CacheBlobUrl: {
329 const blobUrls = state.blobUrls[action.id] || [];
330 return {
331 ...state,
332 blobUrls: {
333 ...state.blobUrls,
334 [action.id]: [...blobUrls, action.blobUrl]
335 }
336 };
337 }
338 case Type.RevokeBlobUrls: {
339 const newBlobUrls = { ...state.blobUrls };
340 delete newBlobUrls[action.id];
341 return {
342 ...state,
343 blobUrls: newBlobUrls
344 };
345 }
346 case Type.UpdateProgress:
347 return {
348 ...state,
349 queue: state.queue.map(
350 (item) => item.id === action.id ? {
351 ...item,
352 progress: action.progress
353 } : item
354 )
355 };
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 case Type.UpdateSettings: {
370 return {
371 ...state,
372 settings: {
373 ...state.settings,
374 ...action.settings
375 }
376 };
377 }
378 }
379 return state;
380 }
381 var reducer_default = reducer;
382
383 // packages/upload-media/build-module/store/selectors.mjs
384 var selectors_exports = {};
385 __export(selectors_exports, {
386 getItems: () => getItems,
387 getSettings: () => getSettings,
388 isUploading: () => isUploading,
389 isUploadingById: () => isUploadingById,
390 isUploadingByUrl: () => isUploadingByUrl
391 });
392 function getItems(state) {
393 return state.queue;
394 }
395 function isUploading(state) {
396 return state.queue.length >= 1;
397 }
398 function isUploadingByUrl(state, url) {
399 return state.queue.some(
400 (item) => item.attachment?.url === url || item.sourceUrl === url
401 );
402 }
403 function isUploadingById(state, attachmentId) {
404 return state.queue.some(
405 (item) => item.attachment?.id === attachmentId || item.sourceAttachmentId === attachmentId
406 );
407 }
408 function getSettings(state) {
409 return state.settings;
410 }
411
412 // packages/upload-media/build-module/store/private-selectors.mjs
413 var private_selectors_exports = {};
414 __export(private_selectors_exports, {
415 getActiveImageProcessingCount: () => getActiveImageProcessingCount,
416 getActiveUploadCount: () => getActiveUploadCount,
417 getActiveVideoProcessingCount: () => getActiveVideoProcessingCount,
418 getAllItems: () => getAllItems,
419 getBlobUrls: () => getBlobUrls,
420 getFailedItems: () => getFailedItems,
421 getItem: () => getItem,
422 getItemProgress: () => getItemProgress,
423 getPendingImageProcessing: () => getPendingImageProcessing,
424 getPendingUploads: () => getPendingUploads,
425 getPendingVideoProcessing: () => getPendingVideoProcessing,
426 hasPendingItemsByParentId: () => hasPendingItemsByParentId,
427 isBatchUploaded: () => isBatchUploaded,
428 isPaused: () => isPaused
429 });
430 function getAllItems(state) {
431 return state.queue;
432 }
433 function getItem(state, id) {
434 return state.queue.find((item) => item.id === id);
435 }
436 function isBatchUploaded(state, batchId) {
437 const batchItems = state.queue.filter(
438 (item) => batchId === item.batchId
439 );
440 return batchItems.length === 0;
441 }
442 function isPaused(state) {
443 return state.queueStatus === "paused";
444 }
445 function getBlobUrls(state, id) {
446 return state.blobUrls[id] || [];
447 }
448 function getActiveUploadCount(state) {
449 return state.queue.filter(
450 (item) => item.currentOperation === OperationType.Upload
451 ).length;
452 }
453 function getPendingUploads(state) {
454 return state.queue.filter((item) => {
455 const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
456 return nextOperation === OperationType.Upload && item.currentOperation !== OperationType.Upload;
457 });
458 }
459 function getActiveImageProcessingCount(state) {
460 return state.queue.filter(
461 (item) => item.currentOperation === OperationType.ResizeCrop || item.currentOperation === OperationType.Rotate
462 ).length;
463 }
464 function getActiveVideoProcessingCount(state) {
465 return state.queue.filter(
466 (item) => item.currentOperation === OperationType.TranscodeGif
467 ).length;
468 }
469 function getPendingImageProcessing(state) {
470 return state.queue.filter((item) => {
471 const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
472 return (nextOperation === OperationType.ResizeCrop || nextOperation === OperationType.Rotate) && item.currentOperation !== OperationType.ResizeCrop && item.currentOperation !== OperationType.Rotate;
473 });
474 }
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 function getFailedItems(state) {
482 return state.queue.filter((item) => item.error !== void 0);
483 }
484 function hasPendingItemsByParentId(state, parentId) {
485 return state.queue.some((item) => item.parentId === parentId);
486 }
487 function getItemProgress(state, id) {
488 const item = state.queue.find((i) => i.id === id);
489 return item?.progress;
490 }
491
492 // packages/upload-media/build-module/store/actions.mjs
493 var actions_exports = {};
494 __export(actions_exports, {
495 addItems: () => addItems,
496 cancelItem: () => cancelItem,
497 executeRetry: () => executeRetry,
498 retryItem: () => retryItem,
499 scheduleRetry: () => scheduleRetry
500 });
501
502 // node_modules/uuid/dist/stringify.js
503 var byteToHex = [];
504 for (let i = 0; i < 256; ++i) {
505 byteToHex.push((i + 256).toString(16).slice(1));
506 }
507 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();
509 }
510
511 // node_modules/uuid/dist/rng.js
512 var rnds8 = new Uint8Array(16);
513 function rng() {
514 return crypto.getRandomValues(rnds8);
515 }
516
517 // node_modules/uuid/dist/v4.js
518 function v4(options, buf, offset) {
519 if (!buf && !options && crypto.randomUUID) {
520 return crypto.randomUUID();
521 }
522 return _v4(options, buf, offset);
523 }
524 function _v4(options, buf, offset) {
525 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 }
530 rnds[6] = rnds[6] & 15 | 64;
531 rnds[8] = rnds[8] & 63 | 128;
532 if (buf) {
533 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 for (let i = 0; i < 16; ++i) {
538 buf[offset + i] = rnds[i];
539 }
540 return buf;
541 }
542 return unsafeStringify(rnds);
543 }
544 var v4_default = v4;
545
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 // packages/upload-media/build-module/image-file.mjs
589 var ImageFile = class extends File {
590 width = 0;
591 height = 0;
592 originalWidth = 0;
593 originalHeight = 0;
594 get wasResized() {
595 return (this.originalWidth || 0) > this.width || (this.originalHeight || 0) > this.height;
596 }
597 constructor(file, width, height, originalWidth, originalHeight) {
598 super([file], file.name, {
599 type: file.type,
600 lastModified: file.lastModified
601 });
602 this.width = width;
603 this.height = height;
604 this.originalWidth = originalWidth;
605 this.originalHeight = originalHeight;
606 }
607 };
608
609 // packages/upload-media/build-module/utils.mjs
610 var import_url = __toESM(require_url(), 1);
611 var import_i18n = __toESM(require_i18n(), 1);
612 function convertBlobToFile(fileOrBlob) {
613 if (fileOrBlob instanceof File) {
614 return fileOrBlob;
615 }
616 if ("name" in fileOrBlob && typeof fileOrBlob.name === "string") {
617 return new File([fileOrBlob], fileOrBlob.name, {
618 type: fileOrBlob.type,
619 lastModified: fileOrBlob.lastModified
620 });
621 }
622 const ext = fileOrBlob.type.split("/")[1];
623 const mediaType = "application/pdf" === fileOrBlob.type ? "document" : fileOrBlob.type.split("/")[0];
624 return new File([fileOrBlob], `${mediaType}.${ext}`, {
625 type: fileOrBlob.type
626 });
627 }
628 function renameFile(file, name) {
629 return new File([file], name, {
630 type: file.type,
631 lastModified: file.lastModified
632 });
633 }
634 function cloneFile(file) {
635 return renameFile(file, file.name);
636 }
637 function getFileBasename(name) {
638 return name.includes(".") ? name.split(".").slice(0, -1).join(".") : name;
639 }
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
657 // packages/upload-media/build-module/store/utils/index.mjs
658 var vipsModulePromise;
659 var vipsModule;
660 function loadVipsModule() {
661 if (!vipsModulePromise) {
662 vipsModulePromise = import("@wordpress/vips/worker").then(
663 (mod) => {
664 vipsModule = mod;
665 return mod;
666 }
667 );
668 }
669 return vipsModulePromise;
670 }
671 async function vipsConvertImageFormat(id, file, type, options = {}) {
672 const { vipsConvertImageFormat: convertImageFormat } = await loadVipsModule();
673 const buffer = await convertImageFormat(
674 id,
675 await file.arrayBuffer(),
676 file.type,
677 type,
678 options
679 );
680 const ext = type.split("/")[1];
681 const fileName = `${getFileBasename(file.name)}.${ext}`;
682 return new File([new Blob([buffer])], fileName, {
683 type
684 });
685 }
686 async function vipsHasTransparency(url) {
687 const { vipsHasTransparency: hasTransparency } = await loadVipsModule();
688 const response = await fetch(url);
689 if (!response.ok) {
690 throw new Error(`Failed to fetch image: ${response.status}`);
691 }
692 return hasTransparency(await response.arrayBuffer());
693 }
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;
708 if (signal?.aborted) {
709 throw new Error("Operation aborted");
710 }
711 const { vipsResizeImage: resizeImage } = await loadVipsModule();
712 const { buffer, width, height, originalWidth, originalHeight } = await resizeImage(id, await file.arrayBuffer(), file.type, resize, {
713 smartCrop,
714 quality,
715 stripMeta,
716 maxBitdepth
717 });
718 let fileName = file.name;
719 const wasResized = originalWidth > width || originalHeight > height;
720 if (wasResized) {
721 const basename = getFileBasename(file.name);
722 if (scaledSuffix) {
723 fileName = file.name.replace(basename, `${basename}-scaled`);
724 } else if (addSuffix) {
725 fileName = file.name.replace(
726 basename,
727 `${basename}-${width}x${height}`
728 );
729 }
730 }
731 const resultFile = new ImageFile(
732 new File(
733 [new Blob([buffer], { type: file.type })],
734 fileName,
735 {
736 type: file.type
737 }
738 ),
739 width,
740 height,
741 originalWidth,
742 originalHeight
743 );
744 return resultFile;
745 }
746 async function vipsRotateImage(id, file, orientation, signal) {
747 if (signal?.aborted) {
748 throw new Error("Operation aborted");
749 }
750 if (orientation === 1) {
751 return file;
752 }
753 const { vipsRotateImage: rotateImage } = await loadVipsModule();
754 const { buffer, width, height } = await rotateImage(
755 id,
756 await file.arrayBuffer(),
757 file.type,
758 orientation
759 );
760 const basename = getFileBasename(file.name);
761 const fileName = file.name.replace(basename, `${basename}-rotated`);
762 const resultFile = new ImageFile(
763 new File(
764 [new Blob([buffer], { type: file.type })],
765 fileName,
766 {
767 type: file.type
768 }
769 ),
770 width,
771 height
772 );
773 return resultFile;
774 }
775 async function vipsCancelOperations(id) {
776 if (!vipsModule) {
777 return false;
778 }
779 return vipsModule.vipsCancelOperations(id);
780 }
781 function terminateVipsWorker() {
782 if (vipsModule) {
783 vipsModule.terminateVipsWorker();
784 }
785 }
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
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 }
892
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 // 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 var UploadError = class extends Error {
950 code;
951 file;
952 constructor({ code, message, file, cause }) {
953 super(message, { cause });
954 Object.setPrototypeOf(this, new.target.prototype);
955 this.code = code;
956 this.file = file;
957 }
958 };
959
960 // packages/upload-media/build-module/validate-mime-type.mjs
961 var import_i18n2 = __toESM(require_i18n(), 1);
962 function validateMimeType(file, allowedTypes) {
963 if (!allowedTypes) {
964 return;
965 }
966 const isAllowedType = allowedTypes.some((allowedType) => {
967 if (allowedType.includes("/")) {
968 return allowedType === file.type;
969 }
970 return file.type.startsWith(`${allowedType}/`);
971 });
972 if (file.type && !isAllowedType) {
973 throw new UploadError({
974 code: ErrorCode.MIME_TYPE_NOT_SUPPORTED,
975 message: (0, import_i18n2.sprintf)(
976 // translators: %s: file name.
977 (0, import_i18n2.__)("%s: Sorry, this file type is not supported here."),
978 file.name
979 ),
980 file
981 });
982 }
983 }
984
985 // packages/upload-media/build-module/validate-mime-type-for-user.mjs
986 var import_i18n3 = __toESM(require_i18n(), 1);
987
988 // packages/upload-media/build-module/get-mime-types-array.mjs
989 function getMimeTypesArray(wpMimeTypesObject) {
990 if (!wpMimeTypesObject) {
991 return null;
992 }
993 return Object.entries(wpMimeTypesObject).flatMap(
994 ([extensionsString, mime]) => {
995 const [type] = mime.split("/");
996 const extensions = extensionsString.split("|");
997 return [
998 mime,
999 ...extensions.map(
1000 (extension) => `${type}/${extension}`
1001 )
1002 ];
1003 }
1004 );
1005 }
1006
1007 // packages/upload-media/build-module/validate-mime-type-for-user.mjs
1008 function validateMimeTypeForUser(file, wpAllowedMimeTypes) {
1009 const allowedMimeTypesForUser = getMimeTypesArray(wpAllowedMimeTypes);
1010 if (!allowedMimeTypesForUser) {
1011 return;
1012 }
1013 const isAllowedMimeTypeForUser = allowedMimeTypesForUser.includes(
1014 file.type
1015 );
1016 if (file.type && !isAllowedMimeTypeForUser) {
1017 throw new UploadError({
1018 code: ErrorCode.MIME_TYPE_NOT_ALLOWED_FOR_USER,
1019 message: (0, import_i18n3.sprintf)(
1020 // translators: %s: file name.
1021 (0, import_i18n3.__)(
1022 "%s: Sorry, you are not allowed to upload this file type."
1023 ),
1024 file.name
1025 ),
1026 file
1027 });
1028 }
1029 }
1030
1031 // packages/upload-media/build-module/validate-file-size.mjs
1032 var import_i18n4 = __toESM(require_i18n(), 1);
1033 function validateFileSize(file, maxUploadFileSize) {
1034 if (file.size <= 0) {
1035 throw new UploadError({
1036 code: ErrorCode.EMPTY_FILE,
1037 message: (0, import_i18n4.sprintf)(
1038 // translators: %s: file name.
1039 (0, import_i18n4.__)("%s: This file is empty."),
1040 file.name
1041 ),
1042 file
1043 });
1044 }
1045 if (maxUploadFileSize && file.size > maxUploadFileSize) {
1046 throw new UploadError({
1047 code: ErrorCode.SIZE_ABOVE_LIMIT,
1048 message: (0, import_i18n4.sprintf)(
1049 // translators: %s: file name.
1050 (0, import_i18n4.__)(
1051 "%s: This file exceeds the maximum upload size for this site."
1052 ),
1053 file.name
1054 ),
1055 file
1056 });
1057 }
1058 }
1059
1060 // packages/upload-media/build-module/store/actions.mjs
1061 function addItems({
1062 files,
1063 onChange,
1064 onSuccess,
1065 onError,
1066 onBatchSuccess,
1067 additionalData,
1068 allowedTypes
1069 }) {
1070 return async ({ select: select2, dispatch }) => {
1071 const batchId = v4_default();
1072 for (const file of files) {
1073 try {
1074 validateMimeType(file, allowedTypes);
1075 validateMimeTypeForUser(
1076 file,
1077 select2.getSettings().allowedMimeTypes
1078 );
1079 } catch (error) {
1080 onError?.(error);
1081 continue;
1082 }
1083 try {
1084 validateFileSize(
1085 file,
1086 select2.getSettings().maxUploadFileSize
1087 );
1088 } catch (error) {
1089 onError?.(error);
1090 continue;
1091 }
1092 dispatch.addItem({
1093 file,
1094 batchId,
1095 onChange,
1096 onSuccess,
1097 onBatchSuccess,
1098 onError,
1099 additionalData
1100 });
1101 }
1102 };
1103 }
1104 function cancelItem(id, error, silent = false) {
1105 return async ({ select: select2, dispatch }) => {
1106 const item = select2.getItem(id);
1107 if (!item) {
1108 return;
1109 }
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 item.abortController?.abort();
1124 vipsCancelOperations(id).catch(() => {
1125 });
1126 cancelGifToVideoOperations(id).catch(() => {
1127 });
1128 if (!silent) {
1129 const { onError } = item;
1130 onError?.(error ?? new Error("Upload cancelled"));
1131 if (!onError && error && !item.parentId) {
1132 console.error("Upload cancelled", error);
1133 }
1134 } else {
1135 debug(
1136 `Item cancelled: ${item.file.name} (item ${id}): ${error instanceof Error ? error.message : error}`
1137 );
1138 }
1139 const { currentOperation, parentId, batchId } = item;
1140 dispatch({
1141 type: Type.Cancel,
1142 id,
1143 error
1144 });
1145 dispatch.removeItem(id);
1146 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}`);
1198 item.onBatchSuccess?.();
1199 }
1200 };
1201 }
1202 function retryItem(id) {
1203 return async ({ select: select2, dispatch }) => {
1204 const item = select2.getItem(id);
1205 if (!item) {
1206 return;
1207 }
1208 if (!item.error) {
1209 return;
1210 }
1211 dispatch({
1212 type: Type.RetryItem,
1213 id
1214 });
1215 dispatch.processItem(id);
1216 };
1217 }
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
1268 // packages/upload-media/build-module/store/private-actions.mjs
1269 var private_actions_exports = {};
1270 __export(private_actions_exports, {
1271 addItem: () => addItem,
1272 addSideloadItem: () => addSideloadItem,
1273 detectUltraHdr: () => detectUltraHdr,
1274 finalizeItem: () => finalizeItem,
1275 finishOperation: () => finishOperation,
1276 generateThumbnails: () => generateThumbnails,
1277 getTranscodeImageOperation: () => getTranscodeImageOperation,
1278 pauseItem: () => pauseItem,
1279 pauseQueue: () => pauseQueue,
1280 prepareItem: () => prepareItem,
1281 processItem: () => processItem,
1282 removeItem: () => removeItem,
1283 resizeCropItem: () => resizeCropItem,
1284 resumeQueue: () => resumeQueue,
1285 revokeBlobUrls: () => revokeBlobUrls,
1286 rotateItem: () => rotateItem,
1287 sideloadItem: () => sideloadItem,
1288 transcodeGifItem: () => transcodeGifItem,
1289 transcodeImageItem: () => transcodeImageItem,
1290 updateItemProgress: () => updateItemProgress,
1291 updateSettings: () => updateSettings,
1292 uploadItem: () => uploadItem
1293 });
1294 var import_blob = __toESM(require_blob(), 1);
1295 var import_i18n6 = __toESM(require_i18n(), 1);
1296
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 // packages/upload-media/build-module/stub-file.mjs
2298 var StubFile = class extends File {
2299 constructor(fileName = "stub-file") {
2300 super([], fileName);
2301 }
2302 };
2303
2304 // packages/upload-media/build-module/store/private-actions.mjs
2305 var DEFAULT_OUTPUT_QUALITY = 0.82;
2306 var ultraHdrItems = /* @__PURE__ */ new Set();
2307 function addItem({
2308 file: fileOrBlob,
2309 batchId,
2310 onChange,
2311 onSuccess,
2312 onBatchSuccess,
2313 onError,
2314 additionalData = {},
2315 sourceUrl,
2316 sourceAttachmentId,
2317 abortController,
2318 operations
2319 }) {
2320 return async ({ dispatch }) => {
2321 const itemId = v4_default();
2322 const file = convertBlobToFile(fileOrBlob);
2323 let blobUrl;
2324 if (!(file instanceof StubFile)) {
2325 blobUrl = (0, import_blob.createBlobURL)(file);
2326 dispatch({
2327 type: Type.CacheBlobUrl,
2328 id: itemId,
2329 blobUrl
2330 });
2331 }
2332 dispatch({
2333 type: Type.Add,
2334 item: {
2335 id: itemId,
2336 batchId,
2337 status: ItemStatus.Processing,
2338 sourceFile: cloneFile(file),
2339 file,
2340 attachment: {
2341 url: blobUrl
2342 },
2343 additionalData: {
2344 generate_sub_sizes: false,
2345 ...additionalData
2346 },
2347 onChange,
2348 onSuccess,
2349 onBatchSuccess,
2350 onError,
2351 sourceUrl,
2352 sourceAttachmentId,
2353 abortController: abortController || new AbortController(),
2354 operations: Array.isArray(operations) ? operations : [OperationType.Prepare]
2355 }
2356 });
2357 dispatch.processItem(itemId);
2358 };
2359 }
2360 function addSideloadItem({
2361 file,
2362 onChange,
2363 additionalData,
2364 operations,
2365 batchId,
2366 parentId
2367 }) {
2368 return ({ dispatch }) => {
2369 const itemId = v4_default();
2370 dispatch({
2371 type: Type.Add,
2372 item: {
2373 id: itemId,
2374 batchId,
2375 status: ItemStatus.Processing,
2376 sourceFile: cloneFile(file),
2377 file,
2378 onChange,
2379 additionalData: {
2380 ...additionalData
2381 },
2382 parentId,
2383 operations: Array.isArray(operations) ? operations : [OperationType.Prepare],
2384 abortController: new AbortController()
2385 }
2386 });
2387 dispatch.processItem(itemId);
2388 };
2389 }
2390 function processItem(id) {
2391 return async ({ select: select2, dispatch }) => {
2392 if (select2.isPaused()) {
2393 return;
2394 }
2395 const item = select2.getItem(id);
2396 if (!item) {
2397 return;
2398 }
2399 const {
2400 attachment,
2401 onChange,
2402 onSuccess,
2403 onBatchSuccess,
2404 batchId,
2405 parentId
2406 } = item;
2407 const operation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
2408 const operationArgs = Array.isArray(item.operations?.[0]) ? item.operations[0][1] : void 0;
2409 if (operation === OperationType.Upload) {
2410 const settings = select2.getSettings();
2411 const activeCount = select2.getActiveUploadCount();
2412 if (activeCount >= settings.maxConcurrentUploads) {
2413 return;
2414 }
2415 }
2416 if (operation === OperationType.ResizeCrop || operation === OperationType.Rotate) {
2417 const settings = select2.getSettings();
2418 const activeCount = select2.getActiveImageProcessingCount();
2419 if (activeCount >= settings.maxConcurrentImageProcessing) {
2420 return;
2421 }
2422 }
2423 if (operation === OperationType.TranscodeGif) {
2424 const activeCount = select2.getActiveVideoProcessingCount();
2425 if (activeCount >= 1) {
2426 return;
2427 }
2428 }
2429 if (attachment) {
2430 const isHeicUrl = attachment.url && /\.hei[cf]$/i.test(attachment.url);
2431 if (!isHeicUrl) {
2432 onChange?.([attachment]);
2433 }
2434 }
2435 if (!operation) {
2436 if (parentId || !parentId && !select2.hasPendingItemsByParentId(id)) {
2437 if (attachment) {
2438 onSuccess?.([attachment]);
2439 }
2440 dispatch.removeItem(id);
2441 dispatch.revokeBlobUrls(id);
2442 if (batchId && select2.isBatchUploaded(batchId)) {
2443 onBatchSuccess?.();
2444 }
2445 }
2446 if (parentId && batchId && select2.isBatchUploaded(batchId)) {
2447 const parentItem = select2.getItem(parentId);
2448 if (!parentItem) {
2449 return;
2450 }
2451 if (parentItem.operations && parentItem.operations.length > 0) {
2452 dispatch.processItem(parentId);
2453 return;
2454 }
2455 if (attachment) {
2456 parentItem.onSuccess?.([attachment]);
2457 }
2458 dispatch.removeItem(parentId);
2459 dispatch.revokeBlobUrls(parentId);
2460 if (parentItem.batchId && select2.isBatchUploaded(parentItem.batchId)) {
2461 parentItem.onBatchSuccess?.();
2462 }
2463 }
2464 return;
2465 }
2466 if (operation === OperationType.Finalize && select2.hasPendingItemsByParentId(id)) {
2467 return;
2468 }
2469 dispatch({
2470 type: Type.OperationStart,
2471 id,
2472 operation
2473 });
2474 debug(
2475 `Starting operation ${operation} for ${item.file.name} (item ${item.id})`
2476 );
2477 switch (operation) {
2478 case OperationType.Prepare:
2479 dispatch.prepareItem(item.id);
2480 break;
2481 case OperationType.ResizeCrop:
2482 dispatch.resizeCropItem(
2483 item.id,
2484 operationArgs
2485 );
2486 break;
2487 case OperationType.Rotate:
2488 dispatch.rotateItem(
2489 item.id,
2490 operationArgs
2491 );
2492 break;
2493 case OperationType.TranscodeImage:
2494 dispatch.transcodeImageItem(
2495 item.id,
2496 operationArgs
2497 );
2498 break;
2499 case OperationType.TranscodeGif:
2500 dispatch.transcodeGifItem(
2501 item.id,
2502 operationArgs
2503 );
2504 break;
2505 case OperationType.Upload:
2506 if (item.parentId) {
2507 dispatch.sideloadItem(id);
2508 } else {
2509 dispatch.uploadItem(id);
2510 }
2511 break;
2512 case OperationType.ThumbnailGeneration:
2513 dispatch.generateThumbnails(id);
2514 break;
2515 case OperationType.Finalize:
2516 dispatch.finalizeItem(id);
2517 break;
2518 case OperationType.DetectUltraHdr:
2519 dispatch.detectUltraHdr(id);
2520 break;
2521 }
2522 };
2523 }
2524 function pauseQueue() {
2525 return {
2526 type: Type.PauseQueue
2527 };
2528 }
2529 function resumeQueue() {
2530 return async ({ select: select2, dispatch }) => {
2531 dispatch({
2532 type: Type.ResumeQueue
2533 });
2534 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 }
2540 }
2541 };
2542 }
2543 function pauseItem(id) {
2544 return async ({ dispatch }) => {
2545 dispatch({
2546 type: Type.PauseItem,
2547 id
2548 });
2549 };
2550 }
2551 function removeItem(id) {
2552 return async ({ select: select2, dispatch }) => {
2553 const item = select2.getItem(id);
2554 if (!item) {
2555 return;
2556 }
2557 ultraHdrItems.delete(id);
2558 clearRetryTimer(id);
2559 dispatch({
2560 type: Type.Remove,
2561 id
2562 });
2563 if (select2.getAllItems().length === 0) {
2564 terminateVipsWorker();
2565 terminateVideoConversionWorker();
2566 }
2567 };
2568 }
2569 function finishOperation(id, updates) {
2570 return async ({ select: select2, dispatch }) => {
2571 const item = select2.getItem(id);
2572 const previousOperation = item?.currentOperation;
2573 dispatch({
2574 type: Type.OperationFinish,
2575 id,
2576 item: updates
2577 });
2578 dispatch.processItem(id);
2579 if (previousOperation === OperationType.Upload) {
2580 const pendingUploads = select2.getPendingUploads();
2581 for (const pendingItem of pendingUploads) {
2582 dispatch.processItem(pendingItem.id);
2583 }
2584 }
2585 if (previousOperation === OperationType.ResizeCrop || previousOperation === OperationType.Rotate) {
2586 const pendingItems = select2.getPendingImageProcessing();
2587 for (const pendingItem of pendingItems) {
2588 dispatch.processItem(pendingItem.id);
2589 }
2590 }
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 };
2601 }
2602 var VALID_IMAGE_FORMATS = ["jpeg", "webp", "avif", "png", "gif"];
2603 function isValidImageFormat(format) {
2604 return VALID_IMAGE_FORMATS.includes(format);
2605 }
2606 async function getTranscodeImageOperation(file, outputMimeType, interlaced = false, quality = DEFAULT_OUTPUT_QUALITY) {
2607 if (file.type === "image/png" && outputMimeType === "image/jpeg") {
2608 const blobUrl = (0, import_blob.createBlobURL)(file);
2609 try {
2610 const hasAlpha = await vipsHasTransparency(blobUrl);
2611 if (hasAlpha) {
2612 return null;
2613 }
2614 } catch {
2615 return null;
2616 } finally {
2617 (0, import_blob.revokeBlobURL)(blobUrl);
2618 }
2619 }
2620 const formatPart = outputMimeType.split("/")[1];
2621 if (!isValidImageFormat(formatPart)) {
2622 return null;
2623 }
2624 return [
2625 OperationType.TranscodeImage,
2626 {
2627 outputFormat: formatPart,
2628 outputQuality: quality,
2629 interlaced
2630 }
2631 ];
2632 }
2633 function prepareItem(id) {
2634 return async ({ select: select2, dispatch }) => {
2635 const item = select2.getItem(id);
2636 if (!item) {
2637 return;
2638 }
2639 const { file } = item;
2640 const operations = [];
2641 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 const isImage = file.type.startsWith("image/");
2679 const isVipsSupported = CLIENT_SIDE_SUPPORTED_MIME_TYPES.includes(
2680 file.type
2681 );
2682 const isHeic = HEIC_MIME_TYPES.includes(file.type);
2683 let tooLargeForClient = false;
2684 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(
2702 file,
2703 settings.imageQuality ?? DEFAULT_OUTPUT_QUALITY
2704 );
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;
2715 }
2716 operations.push(
2717 OperationType.Upload,
2718 OperationType.ThumbnailGeneration,
2719 OperationType.Finalize
2720 );
2721 } else {
2722 operations.push(OperationType.Upload);
2723 }
2724 dispatch({
2725 type: Type.AddOperations,
2726 id,
2727 operations
2728 });
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 }
2758 dispatch.finishOperation(id, updates);
2759 };
2760 }
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 function uploadItem(id) {
2780 return async ({ select: select2, dispatch }) => {
2781 const item = select2.getItem(id);
2782 if (!item) {
2783 return;
2784 }
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 select2.getSettings().mediaUpload({
2804 filesList: [item.file],
2805 additionalData: item.additionalData,
2806 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 onFileChange: ([attachment]) => {
2813 if (attachment && !(0, import_blob.isBlobURL)(attachment.url)) {
2814 finishUpload(attachment);
2815 }
2816 },
2817 onSuccess: ([attachment]) => {
2818 finishUpload(attachment);
2819 },
2820 onError: (error) => {
2821 dispatch.cancelItem(id, error);
2822 }
2823 });
2824 };
2825 }
2826 function sideloadItem(id) {
2827 return async ({ select: select2, dispatch }) => {
2828 const item = select2.getItem(id);
2829 if (!item) {
2830 return;
2831 }
2832 const { post, ...additionalData } = item.additionalData;
2833 const mediaSideload = select2.getSettings().mediaSideload;
2834 if (!mediaSideload) {
2835 dispatch.finishOperation(id, {});
2836 return;
2837 }
2838 const startTime = performance.now();
2839 mediaSideload({
2840 file: item.file,
2841 attachmentId: post,
2842 additionalData,
2843 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, {});
2862 },
2863 onError: (error) => {
2864 dispatch.cancelItem(id, error);
2865 }
2866 });
2867 };
2868 }
2869 function resizeCropItem(id, args) {
2870 return async ({ select: select2, dispatch }) => {
2871 const item = select2.getItem(id);
2872 if (!item) {
2873 return;
2874 }
2875 if (!args?.resize) {
2876 dispatch.finishOperation(id, {
2877 file: item.file
2878 });
2879 return;
2880 }
2881 const startTime = performance.now();
2882 const addSuffix = Boolean(item.parentId);
2883 const scaledSuffix = Boolean(args.isThresholdResize);
2884 const { imageStripMeta, imageMaxBitDepth } = select2.getSettings();
2885 try {
2886 const file = await vipsResizeImage(
2887 item.id,
2888 item.file,
2889 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 }
2899 );
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 const blobUrl = (0, import_blob.createBlobURL)(file);
2910 dispatch({
2911 type: Type.CacheBlobUrl,
2912 id,
2913 blobUrl
2914 });
2915 dispatch.finishOperation(id, {
2916 file,
2917 attachment: {
2918 url: blobUrl
2919 }
2920 });
2921 } catch (error) {
2922 dispatch.cancelItem(
2923 id,
2924 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 ),
2929 file: item.file,
2930 cause: error instanceof Error ? error : void 0
2931 })
2932 );
2933 }
2934 };
2935 }
2936 function rotateItem(id, args) {
2937 return async ({ select: select2, dispatch }) => {
2938 const item = select2.getItem(id);
2939 if (!item) {
2940 return;
2941 }
2942 if (!args?.orientation || args.orientation === 1) {
2943 dispatch.finishOperation(id, {
2944 file: item.file
2945 });
2946 return;
2947 }
2948 const startTime = performance.now();
2949 try {
2950 const file = await vipsRotateImage(
2951 item.id,
2952 item.file,
2953 args.orientation,
2954 item.abortController?.signal
2955 );
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 const blobUrl = (0, import_blob.createBlobURL)(file);
2966 dispatch({
2967 type: Type.CacheBlobUrl,
2968 id,
2969 blobUrl
2970 });
2971 dispatch.finishOperation(id, {
2972 file,
2973 attachment: {
2974 url: blobUrl
2975 }
2976 });
2977 } catch (error) {
2978 dispatch.cancelItem(
2979 id,
2980 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 ),
2985 file: item.file,
2986 cause: error instanceof Error ? error : void 0
2987 })
2988 );
2989 }
2990 };
2991 }
2992 function transcodeImageItem(id, args) {
2993 return async ({ select: select2, dispatch }) => {
2994 const item = select2.getItem(id);
2995 if (!item) {
2996 return;
2997 }
2998 if (!args?.outputFormat) {
2999 dispatch.finishOperation(id, {
3000 file: item.file
3001 });
3002 return;
3003 }
3004 const startTime = performance.now();
3005 const outputMimeType = `image/${args.outputFormat}`;
3006 const quality = args.outputQuality ?? DEFAULT_OUTPUT_QUALITY;
3007 const interlaced = args.interlaced ?? false;
3008 const { imageStripMeta, imageMaxBitDepth } = select2.getSettings();
3009 try {
3010 const file = await vipsConvertImageFormat(
3011 item.id,
3012 item.file,
3013 outputMimeType,
3014 {
3015 quality,
3016 interlaced,
3017 stripMeta: imageStripMeta,
3018 maxBitdepth: imageMaxBitDepth
3019 }
3020 );
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 const blobUrl = (0, import_blob.createBlobURL)(file);
3031 dispatch({
3032 type: Type.CacheBlobUrl,
3033 id,
3034 blobUrl
3035 });
3036 dispatch.finishOperation(id, {
3037 file,
3038 attachment: {
3039 url: blobUrl
3040 }
3041 });
3042 } catch (error) {
3043 dispatch.cancelItem(
3044 id,
3045 new UploadError({
3046 code: ErrorCode.MEDIA_TRANSCODING_ERROR,
3047 message: "Image could not be transcoded to the target format",
3048 file: item.file,
3049 cause: error instanceof Error ? error : void 0
3050 })
3051 );
3052 }
3053 };
3054 }
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 function generateThumbnails(id) {
3139 return async ({ select: select2, dispatch }) => {
3140 const item = select2.getItem(id);
3141 if (!item) {
3142 return;
3143 }
3144 if (!item.attachment) {
3145 dispatch.finishOperation(id, {});
3146 return;
3147 }
3148 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) {
3213 dispatch.addSideloadItem({
3214 file: rotatedSource,
3215 batchId: v4_default(),
3216 parentId: item.id,
3217 additionalData: {
3218 post: attachment.id,
3219 image_size: "original",
3220 convert_format: false
3221 },
3222 operations: [OperationType.Upload]
3223 });
3224 }
3225 }
3226 if (!item.parentId && attachment.missing_image_sizes && attachment.missing_image_sizes.length > 0) {
3227 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 };
3245 let thumbnailTranscodeOperation = null;
3246 if (!isUltraHdr && outputMimeType) {
3247 thumbnailTranscodeOperation = await getTranscodeImageOperation(
3248 thumbnailSource,
3249 outputMimeType,
3250 interlaced,
3251 defaultQuality
3252 );
3253 }
3254 const dimensionGroups = /* @__PURE__ */ new Map();
3255 for (const name of sizesToGenerate) {
3256 const imageSize = allImageSizes[name];
3257 if (!imageSize) {
3258 console.warn(
3259 `Image size "${name}" not found in configuration`
3260 );
3261 continue;
3262 }
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 const thumbnailOperations = [
3275 [
3276 OperationType.ResizeCrop,
3277 { resize: imageSize, quality: sizeQuality }
3278 ]
3279 ];
3280 if (!isUltraHdr && thumbnailTranscodeOperation) {
3281 thumbnailOperations.push([
3282 thumbnailTranscodeOperation[0],
3283 {
3284 ...thumbnailTranscodeOperation[1],
3285 outputQuality: sizeQuality
3286 }
3287 ]);
3288 }
3289 thumbnailOperations.push(OperationType.Upload);
3290 const imageSizeParam = names.length === 1 ? names[0] : names;
3291 dispatch.addSideloadItem({
3292 file,
3293 batchId,
3294 parentId: item.id,
3295 additionalData: {
3296 // Sideloading does not use the parent post ID but the
3297 // attachment ID as the image sizes need to be added to it.
3298 post: attachment.id,
3299 image_size: imageSizeParam,
3300 convert_format: false
3301 },
3302 operations: thumbnailOperations
3303 });
3304 }
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 });
3343 }
3344 }
3345 }
3346 }
3347 dispatch.finishOperation(id, {});
3348 };
3349 }
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 function revokeBlobUrls(id) {
3376 return async ({ select: select2, dispatch }) => {
3377 const blobUrls = select2.getBlobUrls(id);
3378 for (const blobUrl of blobUrls) {
3379 (0, import_blob.revokeBlobURL)(blobUrl);
3380 }
3381 dispatch({
3382 type: Type.RevokeBlobUrls,
3383 id
3384 });
3385 };
3386 }
3387 function updateItemProgress(id, progress) {
3388 return async ({ dispatch }) => {
3389 dispatch({
3390 type: Type.UpdateProgress,
3391 id,
3392 progress
3393 });
3394 };
3395 }
3396 function updateSettings(settings) {
3397 return {
3398 type: Type.UpdateSettings,
3399 settings
3400 };
3401 }
3402
3403 // packages/upload-media/build-module/lock-unlock.mjs
3404 var import_private_apis = __toESM(require_private_apis(), 1);
3405 var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)(
3406 "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.",
3407 "@wordpress/upload-media"
3408 );
3409
3410 // packages/upload-media/build-module/store/index.mjs
3411 var storeConfig = {
3412 reducer: reducer_default,
3413 selectors: selectors_exports,
3414 actions: actions_exports
3415 };
3416 var store = (0, import_data.createReduxStore)(STORE_NAME, {
3417 reducer: reducer_default,
3418 selectors: selectors_exports,
3419 actions: actions_exports
3420 });
3421 if (!(0, import_data.select)(store)) {
3422 (0, import_data.register)(store);
3423 }
3424 unlock(store).registerPrivateActions(private_actions_exports);
3425 unlock(store).registerPrivateSelectors(private_selectors_exports);
3426
3427 // packages/upload-media/build-module/components/provider/index.mjs
3428 var import_element2 = __toESM(require_element(), 1);
3429 var import_data3 = __toESM(require_data(), 1);
3430
3431 // packages/upload-media/build-module/components/provider/with-registry-provider.mjs
3432 var import_element = __toESM(require_element(), 1);
3433 var import_data2 = __toESM(require_data(), 1);
3434 var import_compose = __toESM(require_compose(), 1);
3435 var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
3436 function getSubRegistry(subRegistries, registry, useSubRegistry) {
3437 if (!useSubRegistry) {
3438 return registry;
3439 }
3440 let subRegistry = subRegistries.get(registry);
3441 if (!subRegistry) {
3442 subRegistry = (0, import_data2.createRegistry)({}, registry);
3443 subRegistry.registerStore(STORE_NAME, storeConfig);
3444 subRegistries.set(registry, subRegistry);
3445 }
3446 return subRegistry;
3447 }
3448 var withRegistryProvider = (0, import_compose.createHigherOrderComponent)(
3449 (WrappedComponent) => ({ useSubRegistry = true, ...props }) => {
3450 const registry = (0, import_data2.useRegistry)();
3451 const [subRegistries] = (0, import_element.useState)(() => /* @__PURE__ */ new WeakMap());
3452 const subRegistry = getSubRegistry(
3453 subRegistries,
3454 registry,
3455 useSubRegistry
3456 );
3457 if (subRegistry === registry) {
3458 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WrappedComponent, { registry, ...props });
3459 }
3460 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_data2.RegistryProvider, { value: subRegistry, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WrappedComponent, { registry: subRegistry, ...props }) });
3461 },
3462 "withRegistryProvider"
3463 );
3464 var with_registry_provider_default = withRegistryProvider;
3465
3466 // packages/upload-media/build-module/components/provider/index.mjs
3467 var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
3468 var MediaUploadProvider = with_registry_provider_default((props) => {
3469 const { children, settings } = props;
3470 const { updateSettings: updateSettings2 } = unlock((0, import_data3.useDispatch)(store));
3471 (0, import_element2.useEffect)(() => {
3472 updateSettings2(settings);
3473 }, [settings, updateSettings2]);
3474 return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
3475 });
3476 var provider_default = MediaUploadProvider;
3477
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.")
3562 }
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 };
3573 }
3574 return __toCommonJS(index_exports);
3575 })();
3576 //# sourceMappingURL=index.js.map
3577