[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/dist/ -> upload-media.js (source)

   1  (function() {
   2  "use strict";
   3  var wp;
   4  (wp ||= {}).uploadMedia = (() => {
   5    var __create = Object.create;
   6    var __defProp = Object.defineProperty;
   7    var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
   8    var __getOwnPropNames = Object.getOwnPropertyNames;
   9    var __getProtoOf = Object.getPrototypeOf;
  10    var __hasOwnProp = Object.prototype.hasOwnProperty;
  11    var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
  12      get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
  13    }) : x)(function(x) {
  14      if (typeof require !== "undefined") return require.apply(this, arguments);
  15      throw Error('Dynamic require of "' + x + '" is not supported');
  16    });
  17    var __commonJS = (cb, mod) => function __require2() {
  18      return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
  19    };
  20    var __export = (target, all) => {
  21      for (var name in all)
  22        __defProp(target, name, { get: all[name], enumerable: true });
  23    };
  24    var __copyProps = (to, from, except, desc) => {
  25      if (from && typeof from === "object" || typeof from === "function") {
  26        for (let key of __getOwnPropNames(from))
  27          if (!__hasOwnProp.call(to, key) && key !== except)
  28            __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  29      }
  30      return to;
  31    };
  32    var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  33      // If the importer is in node compatibility mode or this is not an ESM
  34      // file that has been converted to a CommonJS file using a Babel-
  35      // compatible transform (i.e. "__esModule" has not been set), then set
  36      // "default" to the CommonJS "module.exports" for node compatibility.
  37      isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  38      mod
  39    ));
  40    var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  41  
  42    // package-external:@wordpress/data
  43    var require_data = __commonJS({
  44      "package-external:@wordpress/data"(exports, module) {
  45        module.exports = window.wp.data;
  46      }
  47    });
  48  
  49    // package-external:@wordpress/i18n
  50    var require_i18n = __commonJS({
  51      "package-external:@wordpress/i18n"(exports, module) {
  52        module.exports = window.wp.i18n;
  53      }
  54    });
  55  
  56    // package-external:@wordpress/url
  57    var require_url = __commonJS({
  58      "package-external:@wordpress/url"(exports, module) {
  59        module.exports = window.wp.url;
  60      }
  61    });
  62  
  63    // package-external:@wordpress/blob
  64    var require_blob = __commonJS({
  65      "package-external:@wordpress/blob"(exports, module) {
  66        module.exports = window.wp.blob;
  67      }
  68    });
  69  
  70    // package-external:@wordpress/private-apis
  71    var require_private_apis = __commonJS({
  72      "package-external:@wordpress/private-apis"(exports, module) {
  73        module.exports = window.wp.privateApis;
  74      }
  75    });
  76  
  77    // package-external:@wordpress/element
  78    var require_element = __commonJS({
  79      "package-external:@wordpress/element"(exports, module) {
  80        module.exports = window.wp.element;
  81      }
  82    });
  83  
  84    // package-external:@wordpress/compose
  85    var require_compose = __commonJS({
  86      "package-external:@wordpress/compose"(exports, module) {
  87        module.exports = window.wp.compose;
  88      }
  89    });
  90  
  91    // vendor-external:react/jsx-runtime
  92    var require_jsx_runtime = __commonJS({
  93      "vendor-external:react/jsx-runtime"(exports, module) {
  94        module.exports = window.ReactJSXRuntime;
  95      }
  96    });
  97  
  98    // packages/upload-media/build-module/index.mjs
  99    var index_exports = {};
 100    __export(index_exports, {
 101      ErrorCode: () => ErrorCode,
 102      MediaUploadProvider: () => provider_default,
 103      UploadError: () => UploadError,
 104      clearFeatureDetectionCache: () => clearFeatureDetectionCache,
 105      detectClientSideMediaSupport: () => detectClientSideMediaSupport,
 106      getErrorMessage: () => getErrorMessage,
 107      getHeicConversionAdvice: () => getHeicConversionAdvice,
 108      getHeicUnsupportedMessage: () => getHeicUnsupportedMessage,
 109      isClientSideMediaSupported: () => isClientSideMediaSupported,
 110      isHeicCanvasSupported: () => isHeicCanvasSupported,
 111      isHeicFile: () => isHeicFile,
 112      store: () => store
 113    });
 114  
 115    // packages/upload-media/build-module/store/index.mjs
 116    var import_data = __toESM(require_data(), 1);
 117  
 118    // packages/upload-media/build-module/store/types.mjs
 119    var Type = /* @__PURE__ */ ((Type2) => {
 120      Type2["Unknown"] = "REDUX_UNKNOWN";
 121      Type2["Add"] = "ADD_ITEM";
 122      Type2["Prepare"] = "PREPARE_ITEM";
 123      Type2["Cancel"] = "CANCEL_ITEM";
 124      Type2["Remove"] = "REMOVE_ITEM";
 125      Type2["RetryItem"] = "RETRY_ITEM";
 126      Type2["ScheduleRetry"] = "SCHEDULE_RETRY";
 127      Type2["PauseItem"] = "PAUSE_ITEM";
 128      Type2["ResumeItem"] = "RESUME_ITEM";
 129      Type2["PauseQueue"] = "PAUSE_QUEUE";
 130      Type2["ResumeQueue"] = "RESUME_QUEUE";
 131      Type2["OperationStart"] = "OPERATION_START";
 132      Type2["OperationFinish"] = "OPERATION_FINISH";
 133      Type2["AddOperations"] = "ADD_OPERATIONS";
 134      Type2["CacheBlobUrl"] = "CACHE_BLOB_URL";
 135      Type2["RevokeBlobUrls"] = "REVOKE_BLOB_URLS";
 136      Type2["UpdateProgress"] = "UPDATE_PROGRESS";
 137      Type2["AccumulateSubSize"] = "ACCUMULATE_SUB_SIZE";
 138      Type2["UpdateSettings"] = "UPDATE_SETTINGS";
 139      return Type2;
 140    })(Type || {});
 141    var ItemStatus = /* @__PURE__ */ ((ItemStatus2) => {
 142      ItemStatus2["Queued"] = "QUEUED";
 143      ItemStatus2["Processing"] = "PROCESSING";
 144      ItemStatus2["Paused"] = "PAUSED";
 145      ItemStatus2["PendingRetry"] = "PENDING_RETRY";
 146      ItemStatus2["Uploaded"] = "UPLOADED";
 147      ItemStatus2["Error"] = "ERROR";
 148      return ItemStatus2;
 149    })(ItemStatus || {});
 150    var OperationType = /* @__PURE__ */ ((OperationType2) => {
 151      OperationType2["Prepare"] = "PREPARE";
 152      OperationType2["Upload"] = "UPLOAD";
 153      OperationType2["ResizeCrop"] = "RESIZE_CROP";
 154      OperationType2["Rotate"] = "ROTATE";
 155      OperationType2["TranscodeImage"] = "TRANSCODE_IMAGE";
 156      OperationType2["TranscodeGif"] = "TRANSCODE_GIF";
 157      OperationType2["ThumbnailGeneration"] = "THUMBNAIL_GENERATION";
 158      OperationType2["Finalize"] = "FINALIZE";
 159      OperationType2["DetectUltraHdr"] = "DETECT_ULTRAHDR";
 160      return OperationType2;
 161    })(OperationType || {});
 162  
 163    // packages/upload-media/build-module/store/constants.mjs
 164    var STORE_NAME = "core/upload-media";
 165    var DEFAULT_MAX_CONCURRENT_UPLOADS = 5;
 166    var DEFAULT_MAX_CONCURRENT_IMAGE_PROCESSING = 2;
 167    var DEFAULT_RETRY_SETTINGS = {
 168      maxRetryAttempts: 3,
 169      initialRetryDelayMs: 1e3,
 170      maxRetryDelayMs: 3e4,
 171      backoffMultiplier: 2,
 172      retryJitter: 0.1
 173    };
 174    var CLIENT_SIDE_SUPPORTED_MIME_TYPES = [
 175      "image/jpeg",
 176      "image/png",
 177      "image/gif",
 178      "image/webp",
 179      "image/avif"
 180    ];
 181    var HEIC_MIME_TYPES = [
 182      "image/heic",
 183      "image/heif"
 184    ];
 185  
 186    // packages/upload-media/build-module/store/reducer.mjs
 187    var noop = () => {
 188    };
 189    var DEFAULT_STATE = {
 190      queue: [],
 191      queueStatus: "active",
 192      blobUrls: {},
 193      settings: {
 194        mediaUpload: noop,
 195        maxConcurrentUploads: DEFAULT_MAX_CONCURRENT_UPLOADS,
 196        maxConcurrentImageProcessing: DEFAULT_MAX_CONCURRENT_IMAGE_PROCESSING,
 197        retry: { ...DEFAULT_RETRY_SETTINGS }
 198      },
 199      failureCount: 0
 200    };
 201    function reducer(state = DEFAULT_STATE, action = { type: Type.Unknown }) {
 202      switch (action.type) {
 203        case Type.PauseQueue: {
 204          return {
 205            ...state,
 206            queueStatus: "paused"
 207          };
 208        }
 209        case Type.ResumeQueue: {
 210          return {
 211            ...state,
 212            queueStatus: "active"
 213          };
 214        }
 215        case Type.PauseItem:
 216          return {
 217            ...state,
 218            queue: state.queue.map(
 219              (item) => item.id === action.id ? {
 220                ...item,
 221                status: ItemStatus.Paused
 222              } : item
 223            )
 224          };
 225        case Type.ResumeItem:
 226          return {
 227            ...state,
 228            queue: state.queue.map(
 229              (item) => item.id === action.id ? {
 230                ...item,
 231                status: ItemStatus.Processing
 232              } : item
 233            )
 234          };
 235        case Type.Add:
 236          return {
 237            ...state,
 238            queue: [...state.queue, action.item]
 239          };
 240        case Type.Cancel: {
 241          const cancelled = state.queue.find(
 242            (item) => item.id === action.id
 243          );
 244          return {
 245            ...state,
 246            failureCount: cancelled && !cancelled.parentId ? state.failureCount + 1 : state.failureCount,
 247            queue: state.queue.map(
 248              (item) => item.id === action.id ? {
 249                ...item,
 250                error: action.error
 251              } : item
 252            )
 253          };
 254        }
 255        case Type.RetryItem:
 256          return {
 257            ...state,
 258            queue: state.queue.map(
 259              (item) => item.id === action.id ? {
 260                ...item,
 261                status: ItemStatus.Processing,
 262                error: void 0,
 263                retryCount: (item.retryCount ?? 0) + 1,
 264                abortController: new AbortController(),
 265                /*
 266                 * The failed operation is still recorded on
 267                 * the item: nothing finishes it when it
 268                 * fails, and while the item waits out the
 269                 * backoff that is what keeps it out of the
 270                 * concurrency pools. Clear it now that the
 271                 * item is about to run again, so processItem
 272                 * does not mistake it for an operation still
 273                 * in flight and skip the retry.
 274                 */
 275                currentOperation: void 0
 276              } : item
 277            )
 278          };
 279        case Type.ScheduleRetry:
 280          return {
 281            ...state,
 282            queue: state.queue.map(
 283              (item) => item.id === action.id ? {
 284                ...item,
 285                status: ItemStatus.PendingRetry,
 286                error: action.error,
 287                retryCount: action.retryCount,
 288                nextRetryTimestamp: action.nextRetryTimestamp
 289              } : item
 290            )
 291          };
 292        case Type.Remove:
 293          return {
 294            ...state,
 295            queue: state.queue.filter((item) => item.id !== action.id)
 296          };
 297        case Type.OperationStart: {
 298          return {
 299            ...state,
 300            queue: state.queue.map(
 301              (item) => item.id === action.id ? {
 302                ...item,
 303                currentOperation: action.operation
 304              } : item
 305            )
 306          };
 307        }
 308        case Type.AddOperations:
 309          return {
 310            ...state,
 311            queue: state.queue.map((item) => {
 312              if (item.id !== action.id) {
 313                return item;
 314              }
 315              return {
 316                ...item,
 317                operations: [
 318                  ...item.operations || [],
 319                  ...action.operations
 320                ]
 321              };
 322            })
 323          };
 324        case Type.OperationFinish:
 325          return {
 326            ...state,
 327            queue: state.queue.map((item) => {
 328              if (item.id !== action.id) {
 329                return item;
 330              }
 331              const operations = item.operations ? item.operations.slice(1) : [];
 332              const attachment = item.attachment || action.item.attachment ? {
 333                ...item.attachment,
 334                ...action.item.attachment
 335              } : void 0;
 336              return {
 337                ...item,
 338                currentOperation: void 0,
 339                operations,
 340                ...action.item,
 341                attachment,
 342                additionalData: {
 343                  ...item.additionalData,
 344                  ...action.item.additionalData
 345                }
 346              };
 347            })
 348          };
 349        case Type.CacheBlobUrl: {
 350          const blobUrls = state.blobUrls[action.id] || [];
 351          return {
 352            ...state,
 353            blobUrls: {
 354              ...state.blobUrls,
 355              [action.id]: [...blobUrls, action.blobUrl]
 356            }
 357          };
 358        }
 359        case Type.RevokeBlobUrls: {
 360          const newBlobUrls = { ...state.blobUrls };
 361          delete newBlobUrls[action.id];
 362          return {
 363            ...state,
 364            blobUrls: newBlobUrls
 365          };
 366        }
 367        case Type.UpdateProgress:
 368          return {
 369            ...state,
 370            queue: state.queue.map(
 371              (item) => item.id === action.id ? {
 372                ...item,
 373                progress: action.progress
 374              } : item
 375            )
 376          };
 377        case Type.AccumulateSubSize:
 378          return {
 379            ...state,
 380            queue: state.queue.map(
 381              (item) => item.id === action.id ? {
 382                ...item,
 383                subSizes: [
 384                  ...item.subSizes || [],
 385                  action.subSize
 386                ]
 387              } : item
 388            )
 389          };
 390        case Type.UpdateSettings: {
 391          return {
 392            ...state,
 393            settings: {
 394              ...state.settings,
 395              ...action.settings
 396            }
 397          };
 398        }
 399      }
 400      return state;
 401    }
 402    var reducer_default = reducer;
 403  
 404    // packages/upload-media/build-module/store/selectors.mjs
 405    var selectors_exports = {};
 406    __export(selectors_exports, {
 407      getItems: () => getItems,
 408      getSettings: () => getSettings,
 409      isUploading: () => isUploading,
 410      isUploadingById: () => isUploadingById,
 411      isUploadingByUrl: () => isUploadingByUrl
 412    });
 413    function getItems(state) {
 414      return state.queue;
 415    }
 416    function isUploading(state) {
 417      return state.queue.length >= 1;
 418    }
 419    function isUploadingByUrl(state, url) {
 420      return state.queue.some(
 421        (item) => item.attachment?.url === url || item.sourceUrl === url
 422      );
 423    }
 424    function isUploadingById(state, attachmentId) {
 425      return state.queue.some(
 426        (item) => item.attachment?.id === attachmentId || item.sourceAttachmentId === attachmentId
 427      );
 428    }
 429    function getSettings(state) {
 430      return state.settings;
 431    }
 432  
 433    // packages/upload-media/build-module/store/private-selectors.mjs
 434    var private_selectors_exports = {};
 435    __export(private_selectors_exports, {
 436      getActiveImageProcessingCount: () => getActiveImageProcessingCount,
 437      getActiveUploadCount: () => getActiveUploadCount,
 438      getActiveVideoProcessingCount: () => getActiveVideoProcessingCount,
 439      getAllItems: () => getAllItems,
 440      getBlobUrls: () => getBlobUrls,
 441      getFailedItems: () => getFailedItems,
 442      getFailureCount: () => getFailureCount,
 443      getItem: () => getItem,
 444      getItemProgress: () => getItemProgress,
 445      getPendingImageProcessing: () => getPendingImageProcessing,
 446      getPendingUploads: () => getPendingUploads,
 447      getPendingVideoProcessing: () => getPendingVideoProcessing,
 448      hasPendingItemsByParentId: () => hasPendingItemsByParentId,
 449      isBatchUploaded: () => isBatchUploaded,
 450      isPaused: () => isPaused
 451    });
 452    function getAllItems(state) {
 453      return state.queue;
 454    }
 455    function getFailureCount(state) {
 456      return state.failureCount;
 457    }
 458    function getItem(state, id) {
 459      return state.queue.find((item) => item.id === id);
 460    }
 461    function isBatchUploaded(state, batchId) {
 462      const batchItems = state.queue.filter(
 463        (item) => batchId === item.batchId
 464      );
 465      return batchItems.length === 0;
 466    }
 467    function isPaused(state) {
 468      return state.queueStatus === "paused";
 469    }
 470    function getBlobUrls(state, id) {
 471      return state.blobUrls[id] || [];
 472    }
 473    function getActiveUploadCount(state) {
 474      return state.queue.filter(
 475        (item) => item.currentOperation === OperationType.Upload
 476      ).length;
 477    }
 478    function getPendingUploads(state) {
 479      return state.queue.filter((item) => {
 480        const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
 481        return nextOperation === OperationType.Upload && item.currentOperation !== OperationType.Upload;
 482      });
 483    }
 484    function getActiveImageProcessingCount(state) {
 485      return state.queue.filter(
 486        (item) => item.currentOperation === OperationType.ResizeCrop || item.currentOperation === OperationType.Rotate
 487      ).length;
 488    }
 489    function getActiveVideoProcessingCount(state) {
 490      return state.queue.filter(
 491        (item) => item.currentOperation === OperationType.TranscodeGif
 492      ).length;
 493    }
 494    function getPendingImageProcessing(state) {
 495      return state.queue.filter((item) => {
 496        const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
 497        return (nextOperation === OperationType.ResizeCrop || nextOperation === OperationType.Rotate) && item.currentOperation !== OperationType.ResizeCrop && item.currentOperation !== OperationType.Rotate;
 498      });
 499    }
 500    function getPendingVideoProcessing(state) {
 501      return state.queue.filter((item) => {
 502        const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
 503        return nextOperation === OperationType.TranscodeGif && item.currentOperation !== OperationType.TranscodeGif;
 504      });
 505    }
 506    function getFailedItems(state) {
 507      return state.queue.filter((item) => item.error !== void 0);
 508    }
 509    function hasPendingItemsByParentId(state, parentId) {
 510      return state.queue.some((item) => item.parentId === parentId);
 511    }
 512    function getItemProgress(state, id) {
 513      const item = state.queue.find((i) => i.id === id);
 514      return item?.progress;
 515    }
 516  
 517    // packages/upload-media/build-module/store/actions.mjs
 518    var actions_exports = {};
 519    __export(actions_exports, {
 520      addItems: () => addItems,
 521      cancelItem: () => cancelItem,
 522      executeRetry: () => executeRetry,
 523      retryItem: () => retryItem,
 524      scheduleRetry: () => scheduleRetry
 525    });
 526  
 527    // node_modules/uuid/dist/stringify.js
 528    var byteToHex = [];
 529    for (let i = 0; i < 256; ++i) {
 530      byteToHex.push((i + 256).toString(16).slice(1));
 531    }
 532    function unsafeStringify(arr, offset = 0) {
 533      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();
 534    }
 535  
 536    // node_modules/uuid/dist/rng.js
 537    var rnds8 = new Uint8Array(16);
 538    function rng() {
 539      return crypto.getRandomValues(rnds8);
 540    }
 541  
 542    // node_modules/uuid/dist/v4.js
 543    function v4(options, buf, offset) {
 544      if (!buf && !options && crypto.randomUUID) {
 545        return crypto.randomUUID();
 546      }
 547      return _v4(options, buf, offset);
 548    }
 549    function _v4(options, buf, offset) {
 550      options = options || {};
 551      const rnds = options.random ?? options.rng?.() ?? rng();
 552      if (rnds.length < 16) {
 553        throw new Error("Random bytes length must be >= 16");
 554      }
 555      rnds[6] = rnds[6] & 15 | 64;
 556      rnds[8] = rnds[8] & 63 | 128;
 557      if (buf) {
 558        offset = offset || 0;
 559        if (offset < 0 || offset + 16 > buf.length) {
 560          throw new RangeError(`UUID byte range $offset}:$offset + 15} is out of buffer bounds`);
 561        }
 562        for (let i = 0; i < 16; ++i) {
 563          buf[offset + i] = rnds[i];
 564        }
 565        return buf;
 566      }
 567      return unsafeStringify(rnds);
 568    }
 569    var v4_default = v4;
 570  
 571    // packages/upload-media/build-module/store/actions.mjs
 572    var import_i18n5 = __toESM(require_i18n(), 1);
 573  
 574    // packages/upload-media/build-module/store/utils/retry.mjs
 575    function calculateRetryDelay(options) {
 576      const { attempt, initialDelay, maxDelay, multiplier, jitter } = options;
 577      const exponentialDelay = initialDelay * Math.pow(multiplier, attempt - 1);
 578      const cappedDelay = Math.min(exponentialDelay, maxDelay);
 579      const jitterFactor = 1 + (Math.random() * 2 - 1) * jitter;
 580      return Math.floor(cappedDelay * jitterFactor);
 581    }
 582    var RETRYABLE_MESSAGE_PATTERNS = [
 583      /network/i,
 584      /timeout/i,
 585      /ECONNRESET/i,
 586      /fetch failed/i,
 587      /connection/i,
 588      /socket/i,
 589      /ETIMEDOUT/i,
 590      /ENOTFOUND/i,
 591      /Could not get a valid response/i,
 592      /Failed to fetch/i,
 593      /Load failed/i
 594    ];
 595    function shouldRetryError(error, retryCount, maxRetries) {
 596      if (retryCount >= maxRetries) {
 597        return false;
 598      }
 599      const message = typeof error === "string" ? error : error?.message || "";
 600      return RETRYABLE_MESSAGE_PATTERNS.some(
 601        (pattern) => pattern.test(message)
 602      );
 603    }
 604    var retryTimers = /* @__PURE__ */ new Map();
 605    function clearRetryTimer(id) {
 606      const pendingTimer = retryTimers.get(id);
 607      if (pendingTimer !== void 0) {
 608        clearTimeout(pendingTimer);
 609        retryTimers.delete(id);
 610      }
 611    }
 612  
 613    // packages/upload-media/build-module/image-file.mjs
 614    var ImageFile = class extends File {
 615      width = 0;
 616      height = 0;
 617      originalWidth = 0;
 618      originalHeight = 0;
 619      get wasResized() {
 620        return (this.originalWidth || 0) > this.width || (this.originalHeight || 0) > this.height;
 621      }
 622      constructor(file, width, height, originalWidth, originalHeight) {
 623        super([file], file.name, {
 624          type: file.type,
 625          lastModified: file.lastModified
 626        });
 627        this.width = width;
 628        this.height = height;
 629        this.originalWidth = originalWidth;
 630        this.originalHeight = originalHeight;
 631      }
 632    };
 633  
 634    // packages/upload-media/build-module/utils.mjs
 635    var import_url = __toESM(require_url(), 1);
 636    var import_i18n = __toESM(require_i18n(), 1);
 637    function convertBlobToFile(fileOrBlob) {
 638      if (fileOrBlob instanceof File) {
 639        return fileOrBlob;
 640      }
 641      if ("name" in fileOrBlob && typeof fileOrBlob.name === "string") {
 642        return new File([fileOrBlob], fileOrBlob.name, {
 643          type: fileOrBlob.type,
 644          lastModified: fileOrBlob.lastModified
 645        });
 646      }
 647      const ext = fileOrBlob.type.split("/")[1];
 648      const mediaType = "application/pdf" === fileOrBlob.type ? "document" : fileOrBlob.type.split("/")[0];
 649      return new File([fileOrBlob], `$mediaType}.$ext}`, {
 650        type: fileOrBlob.type
 651      });
 652    }
 653    function renameFile(file, name) {
 654      return new File([file], name, {
 655        type: file.type,
 656        lastModified: file.lastModified
 657      });
 658    }
 659    function cloneFile(file) {
 660      return renameFile(file, file.name);
 661    }
 662    function getFileBasename(name) {
 663      return name.includes(".") ? name.split(".").slice(0, -1).join(".") : name;
 664    }
 665    function isAnimatedGif(buffer) {
 666      const view = new Uint8Array(buffer);
 667      if (view.length < 4 || view[0] !== 71 || view[1] !== 73 || view[2] !== 70 || view[3] !== 56) {
 668        return false;
 669      }
 670      let frameCount = 0;
 671      for (let i = 0; i < view.length - 2; i++) {
 672        if (view[i] === 0 && view[i + 1] === 33 && view[i + 2] === 249) {
 673          frameCount++;
 674          if (frameCount > 1) {
 675            return true;
 676          }
 677        }
 678      }
 679      return false;
 680    }
 681    var FILE_TYPE_BOX_BYTES = 64;
 682    var HEIC_BRANDS = [
 683      "heic",
 684      "heix",
 685      "heim",
 686      "heis",
 687      "hevc",
 688      "hevx",
 689      "hevm",
 690      "hevs",
 691      "mif1",
 692      "msf1"
 693    ];
 694    var AVIF_BRANDS = ["avif", "avis"];
 695    function isHeicBuffer(buffer) {
 696      const view = new Uint8Array(buffer);
 697      const readBrand = (offset) => String.fromCharCode(...view.subarray(offset, offset + 4));
 698      if (view.length < 12 || readBrand(4) !== "ftyp") {
 699        return false;
 700      }
 701      const boxEnd = Math.min(
 702        view.length,
 703        new DataView(buffer).getUint32(0)
 704      );
 705      const brands = [readBrand(8)];
 706      for (let offset = 16; offset + 4 <= boxEnd; offset += 4) {
 707        brands.push(readBrand(offset));
 708      }
 709      if (brands.some((brand) => AVIF_BRANDS.includes(brand))) {
 710        return false;
 711      }
 712      return brands.some((brand) => HEIC_BRANDS.includes(brand));
 713    }
 714    async function isHeicFile(file) {
 715      if (HEIC_MIME_TYPES.includes(file.type)) {
 716        return true;
 717      }
 718      if (file.type && !file.type.startsWith("image/")) {
 719        return false;
 720      }
 721      try {
 722        return isHeicBuffer(
 723          await file.slice(0, FILE_TYPE_BOX_BYTES).arrayBuffer()
 724        );
 725      } catch {
 726        return false;
 727      }
 728    }
 729  
 730    // packages/upload-media/build-module/store/utils/index.mjs
 731    var vipsModulePromise;
 732    var vipsModule;
 733    function loadVipsModule() {
 734      if (!vipsModulePromise) {
 735        vipsModulePromise = import("@wordpress/vips/worker").then(
 736          (mod) => {
 737            vipsModule = mod;
 738            return mod;
 739          }
 740        );
 741      }
 742      return vipsModulePromise;
 743    }
 744    async function vipsConvertImageFormat(id, file, type, options = {}) {
 745      const { vipsConvertImageFormat: convertImageFormat } = await loadVipsModule();
 746      const buffer = await convertImageFormat(
 747        id,
 748        await file.arrayBuffer(),
 749        file.type,
 750        type,
 751        options
 752      );
 753      const ext = type.split("/")[1];
 754      const fileName = `$getFileBasename(file.name)}.$ext}`;
 755      return new File([new Blob([buffer])], fileName, {
 756        type
 757      });
 758    }
 759    async function vipsHasTransparency(url) {
 760      const { vipsHasTransparency: hasTransparency } = await loadVipsModule();
 761      const response = await fetch(url);
 762      if (!response.ok) {
 763        throw new Error(`Failed to fetch image: $response.status}`);
 764      }
 765      return hasTransparency(await response.arrayBuffer());
 766    }
 767    async function vipsGetUltraHdrInfo(buffer) {
 768      const { vipsGetUltraHdrInfo: getUltraHdrInfo } = await loadVipsModule();
 769      return getUltraHdrInfo(buffer);
 770    }
 771    async function vipsResizeImage(id, file, resize, options = {}) {
 772      const {
 773        smartCrop = false,
 774        addSuffix = false,
 775        signal,
 776        scaledSuffix,
 777        quality,
 778        stripMeta,
 779        maxBitdepth
 780      } = options;
 781      if (signal?.aborted) {
 782        throw new Error("Operation aborted");
 783      }
 784      const { vipsResizeImage: resizeImage } = await loadVipsModule();
 785      const { buffer, width, height, originalWidth, originalHeight } = await resizeImage(id, await file.arrayBuffer(), file.type, resize, {
 786        smartCrop,
 787        quality,
 788        stripMeta,
 789        maxBitdepth
 790      });
 791      let fileName = file.name;
 792      const wasResized = originalWidth > width || originalHeight > height;
 793      if (wasResized) {
 794        const basename = getFileBasename(file.name);
 795        if (scaledSuffix) {
 796          fileName = file.name.replace(basename, `$basename}-scaled`);
 797        } else if (addSuffix) {
 798          fileName = file.name.replace(
 799            basename,
 800            `$basename}-$width}x$height}`
 801          );
 802        }
 803      }
 804      const resultFile = new ImageFile(
 805        new File(
 806          [new Blob([buffer], { type: file.type })],
 807          fileName,
 808          {
 809            type: file.type
 810          }
 811        ),
 812        width,
 813        height,
 814        originalWidth,
 815        originalHeight
 816      );
 817      return resultFile;
 818    }
 819    async function vipsRotateImage(id, file, orientation, signal) {
 820      if (signal?.aborted) {
 821        throw new Error("Operation aborted");
 822      }
 823      if (orientation === 1) {
 824        return file;
 825      }
 826      const { vipsRotateImage: rotateImage } = await loadVipsModule();
 827      const { buffer, width, height } = await rotateImage(
 828        id,
 829        await file.arrayBuffer(),
 830        file.type,
 831        orientation
 832      );
 833      const basename = getFileBasename(file.name);
 834      const fileName = file.name.replace(basename, `$basename}-rotated`);
 835      const resultFile = new ImageFile(
 836        new File(
 837          [new Blob([buffer], { type: file.type })],
 838          fileName,
 839          {
 840            type: file.type
 841          }
 842        ),
 843        width,
 844        height
 845      );
 846      return resultFile;
 847    }
 848    async function vipsCancelOperations(id) {
 849      if (!vipsModule) {
 850        return false;
 851      }
 852      return vipsModule.vipsCancelOperations(id);
 853    }
 854    function terminateVipsWorker() {
 855      if (vipsModule) {
 856        vipsModule.terminateVipsWorker();
 857      }
 858    }
 859    var completedVipsOperations = 0;
 860    var MAX_VIPS_OPS_BEFORE_RECYCLE = 50;
 861    function maybeRecycleVipsWorker(activeImageProcessingCount) {
 862      completedVipsOperations++;
 863      if (completedVipsOperations >= MAX_VIPS_OPS_BEFORE_RECYCLE && activeImageProcessingCount === 0) {
 864        terminateVipsWorker();
 865        completedVipsOperations = 0;
 866      }
 867    }
 868  
 869    // packages/upload-media/build-module/store/utils/video-conversion.mjs
 870    var UNSUPPORTED_ERROR_PREFIX = "Unsupported";
 871    var SIZE_LIMIT_ERROR_PREFIX = `$UNSUPPORTED_ERROR_PREFIX}: GIF exceeds maximum conversion size`;
 872    var CONVERSION_TIMEOUT_ERROR_PREFIX = "GIF to video conversion timed out";
 873    var DEFAULT_CONVERSION_TIMEOUT = 3e4;
 874    function isUnsupportedConversionError(error) {
 875      return error instanceof Error && error.message.startsWith(UNSUPPORTED_ERROR_PREFIX);
 876    }
 877    function isSizeLimitConversionError(error) {
 878      return error instanceof Error && error.message.startsWith(SIZE_LIMIT_ERROR_PREFIX);
 879    }
 880    function isConversionTimeoutError(error) {
 881      return error instanceof Error && error.message.startsWith(CONVERSION_TIMEOUT_ERROR_PREFIX);
 882    }
 883    var videoConversionModulePromise;
 884    var videoConversionModule;
 885    function loadVideoConversionModule() {
 886      if (!videoConversionModulePromise) {
 887        videoConversionModulePromise = import("@wordpress/video-conversion/worker").then((mod) => {
 888          videoConversionModule = mod;
 889          return mod;
 890        }).catch((error) => {
 891          videoConversionModulePromise = void 0;
 892          throw error;
 893        });
 894      }
 895      return videoConversionModulePromise;
 896    }
 897    async function convertGifToVideo(id, file, outputMimeType, {
 898      maxDimensions,
 899      timeout = DEFAULT_CONVERSION_TIMEOUT,
 900      maxTotalPixels
 901    } = {}) {
 902      const mod = await loadVideoConversionModule();
 903      const conversion = mod.convertGifToVideo(
 904        id,
 905        file,
 906        outputMimeType,
 907        maxDimensions,
 908        maxTotalPixels
 909      );
 910      let buffer;
 911      if (timeout > 0) {
 912        let timer;
 913        try {
 914          buffer = await Promise.race([
 915            conversion,
 916            new Promise((_, reject) => {
 917              timer = setTimeout(() => {
 918                reject(
 919                  new Error(
 920                    `$CONVERSION_TIMEOUT_ERROR_PREFIX} after $timeout}ms`
 921                  )
 922                );
 923              }, timeout);
 924            })
 925          ]);
 926        } catch (error) {
 927          if (isConversionTimeoutError(error)) {
 928            conversion.catch(() => {
 929            });
 930            mod.cancelGifToVideoOperations(id).catch(() => {
 931            });
 932          }
 933          throw error;
 934        } finally {
 935          clearTimeout(timer);
 936        }
 937      } else {
 938        buffer = await conversion;
 939      }
 940      const ext = outputMimeType === "video/webm" ? "webm" : "mp4";
 941      const fileName = `$getFileBasename(file.name)}.$ext}`;
 942      return new File(
 943        [new Blob([buffer], { type: outputMimeType })],
 944        fileName,
 945        { type: outputMimeType }
 946      );
 947    }
 948    async function cancelGifToVideoOperations(id) {
 949      const mod = videoConversionModule ?? (videoConversionModulePromise ? await videoConversionModulePromise.catch(() => void 0) : void 0);
 950      if (!mod) {
 951        return false;
 952      }
 953      return mod.cancelGifToVideoOperations(id);
 954    }
 955    function terminateVideoConversionWorker() {
 956      if (videoConversionModule) {
 957        videoConversionModule.terminateVideoConversionWorker();
 958        return;
 959      }
 960      if (videoConversionModulePromise) {
 961        void videoConversionModulePromise.then((mod) => mod.terminateVideoConversionWorker()).catch(() => {
 962        });
 963      }
 964    }
 965  
 966    // packages/upload-media/build-module/store/utils/debug-logger.mjs
 967    function isDebugEnabled() {
 968      return true;
 969    }
 970    function debug(message, ...args) {
 971      if (!isDebugEnabled()) {
 972        return;
 973      }
 974      console.debug(`[upload-media] $message}`, ...args);
 975    }
 976    function measure(options) {
 977      if (!isDebugEnabled()) {
 978        return;
 979      }
 980      const {
 981        measureName,
 982        startTime,
 983        endTime = performance.now(),
 984        tooltipText,
 985        properties
 986      } = options;
 987      const detail = {
 988        devtools: {
 989          dataType: "track-entry",
 990          track: "Upload Media",
 991          tooltipText,
 992          properties: properties?.map(([key, value]) => ({
 993            key,
 994            value
 995          }))
 996        }
 997      };
 998      try {
 999        performance.measure(measureName, {
1000          start: startTime,
1001          end: endTime,
1002          detail
1003        });
1004      } catch {
1005      }
1006    }
1007  
1008    // packages/upload-media/build-module/upload-error.mjs
1009    var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
1010      ErrorCode2["EMPTY_FILE"] = "EMPTY_FILE";
1011      ErrorCode2["SIZE_ABOVE_LIMIT"] = "SIZE_ABOVE_LIMIT";
1012      ErrorCode2["MIME_TYPE_NOT_SUPPORTED"] = "MIME_TYPE_NOT_SUPPORTED";
1013      ErrorCode2["MIME_TYPE_NOT_ALLOWED_FOR_USER"] = "MIME_TYPE_NOT_ALLOWED_FOR_USER";
1014      ErrorCode2["HEIC_DECODE_ERROR"] = "HEIC_DECODE_ERROR";
1015      ErrorCode2["IMAGE_TRANSCODING_ERROR"] = "IMAGE_TRANSCODING_ERROR";
1016      ErrorCode2["IMAGE_ROTATION_ERROR"] = "IMAGE_ROTATION_ERROR";
1017      ErrorCode2["MEDIA_TRANSCODING_ERROR"] = "MEDIA_TRANSCODING_ERROR";
1018      ErrorCode2["GIF_TRANSCODING_ERROR"] = "GIF_TRANSCODING_ERROR";
1019      ErrorCode2["MEDIA_FINALIZE_ERROR"] = "MEDIA_FINALIZE_ERROR";
1020      ErrorCode2["GENERAL"] = "GENERAL";
1021      return ErrorCode2;
1022    })(ErrorCode || {});
1023    var UploadError = class extends Error {
1024      code;
1025      file;
1026      constructor({ code, message, file, cause }) {
1027        super(message, { cause });
1028        Object.setPrototypeOf(this, new.target.prototype);
1029        this.code = code;
1030        this.file = file;
1031      }
1032    };
1033  
1034    // packages/upload-media/build-module/validate-mime-type.mjs
1035    var import_i18n2 = __toESM(require_i18n(), 1);
1036    function validateMimeType(file, allowedTypes) {
1037      if (!allowedTypes) {
1038        return;
1039      }
1040      const isAllowedType = allowedTypes.some((allowedType) => {
1041        if (allowedType.includes("/")) {
1042          return allowedType === file.type;
1043        }
1044        return file.type.startsWith(`$allowedType}/`);
1045      });
1046      if (file.type && !isAllowedType) {
1047        throw new UploadError({
1048          code: ErrorCode.MIME_TYPE_NOT_SUPPORTED,
1049          message: (0, import_i18n2.sprintf)(
1050            // translators: %s: file name.
1051            (0, import_i18n2.__)("%s: Sorry, this file type is not supported here."),
1052            file.name
1053          ),
1054          file
1055        });
1056      }
1057    }
1058  
1059    // packages/upload-media/build-module/validate-mime-type-for-user.mjs
1060    var import_i18n3 = __toESM(require_i18n(), 1);
1061  
1062    // packages/upload-media/build-module/get-mime-types-array.mjs
1063    function getMimeTypesArray(wpMimeTypesObject) {
1064      if (!wpMimeTypesObject) {
1065        return null;
1066      }
1067      return Object.entries(wpMimeTypesObject).flatMap(
1068        ([extensionsString, mime]) => {
1069          const [type] = mime.split("/");
1070          const extensions = extensionsString.split("|");
1071          return [
1072            mime,
1073            ...extensions.map(
1074              (extension) => `$type}/$extension}`
1075            )
1076          ];
1077        }
1078      );
1079    }
1080  
1081    // packages/upload-media/build-module/validate-mime-type-for-user.mjs
1082    function validateMimeTypeForUser(file, wpAllowedMimeTypes) {
1083      const allowedMimeTypesForUser = getMimeTypesArray(wpAllowedMimeTypes);
1084      if (!allowedMimeTypesForUser) {
1085        return;
1086      }
1087      const isAllowedMimeTypeForUser = allowedMimeTypesForUser.includes(
1088        file.type
1089      );
1090      if (file.type && !isAllowedMimeTypeForUser) {
1091        throw new UploadError({
1092          code: ErrorCode.MIME_TYPE_NOT_ALLOWED_FOR_USER,
1093          message: (0, import_i18n3.sprintf)(
1094            // translators: %s: file name.
1095            (0, import_i18n3.__)(
1096              "%s: Sorry, you are not allowed to upload this file type."
1097            ),
1098            file.name
1099          ),
1100          file
1101        });
1102      }
1103    }
1104  
1105    // packages/upload-media/build-module/validate-file-size.mjs
1106    var import_i18n4 = __toESM(require_i18n(), 1);
1107    function validateFileSize(file, maxUploadFileSize) {
1108      if (file.size <= 0) {
1109        throw new UploadError({
1110          code: ErrorCode.EMPTY_FILE,
1111          message: (0, import_i18n4.sprintf)(
1112            // translators: %s: file name.
1113            (0, import_i18n4.__)("%s: This file is empty."),
1114            file.name
1115          ),
1116          file
1117        });
1118      }
1119      if (maxUploadFileSize && file.size > maxUploadFileSize) {
1120        throw new UploadError({
1121          code: ErrorCode.SIZE_ABOVE_LIMIT,
1122          message: (0, import_i18n4.sprintf)(
1123            // translators: %s: file name.
1124            (0, import_i18n4.__)(
1125              "%s: This file exceeds the maximum upload size for this site."
1126            ),
1127            file.name
1128          ),
1129          file
1130        });
1131      }
1132    }
1133  
1134    // packages/upload-media/build-module/store/actions.mjs
1135    function addItems({
1136      files,
1137      onChange,
1138      onSuccess,
1139      onError,
1140      onBatchSuccess,
1141      additionalData,
1142      allowedTypes
1143    }) {
1144      return async ({ select: select2, dispatch }) => {
1145        const batchId = v4_default();
1146        for (const file of files) {
1147          try {
1148            validateMimeType(file, allowedTypes);
1149            validateMimeTypeForUser(
1150              file,
1151              select2.getSettings().allowedMimeTypes
1152            );
1153          } catch (error) {
1154            onError?.(error);
1155            continue;
1156          }
1157          try {
1158            validateFileSize(
1159              file,
1160              select2.getSettings().maxUploadFileSize
1161            );
1162          } catch (error) {
1163            onError?.(error);
1164            continue;
1165          }
1166          dispatch.addItem({
1167            file,
1168            batchId,
1169            onChange,
1170            onSuccess,
1171            onBatchSuccess,
1172            onError,
1173            additionalData
1174          });
1175        }
1176      };
1177    }
1178    function cancelItem(id, error, silent = false) {
1179      return async ({ select: select2, dispatch }) => {
1180        const item = select2.getItem(id);
1181        if (!item) {
1182          return;
1183        }
1184        clearRetryTimer(id);
1185        if (!silent && error && !item.parentId && !item.attachment?.id) {
1186          const settings = select2.getSettings();
1187          const retrySettings = settings.retry;
1188          if (retrySettings) {
1189            const retryCount = item.retryCount ?? 0;
1190            const maxRetries = retrySettings.maxRetryAttempts;
1191            if (shouldRetryError(error, retryCount, maxRetries)) {
1192              dispatch.scheduleRetry(id, error);
1193              return;
1194            }
1195          }
1196        }
1197        item.abortController?.abort();
1198        vipsCancelOperations(id).catch(() => {
1199        });
1200        cancelGifToVideoOperations(id).catch(() => {
1201        });
1202        if (!silent) {
1203          const { onError } = item;
1204          onError?.(error ?? new Error("Upload cancelled"));
1205          if (!onError && error && !item.parentId) {
1206            console.error("Upload cancelled", error);
1207          }
1208        } else {
1209          debug(
1210            `Item cancelled: $item.file.name} (item $id}): $error instanceof Error ? error.message : error}`
1211          );
1212        }
1213        const { currentOperation, parentId, batchId } = item;
1214        dispatch({
1215          type: Type.Cancel,
1216          id,
1217          error
1218        });
1219        dispatch.removeItem(id);
1220        dispatch.revokeBlobUrls(id);
1221        if (currentOperation === OperationType.ResizeCrop || currentOperation === OperationType.Rotate) {
1222          for (const pending of select2.getPendingImageProcessing()) {
1223            dispatch.processItem(pending.id);
1224          }
1225        }
1226        if (currentOperation === OperationType.Upload) {
1227          for (const pending of select2.getPendingUploads()) {
1228            dispatch.processItem(pending.id);
1229          }
1230        }
1231        if (currentOperation === OperationType.TranscodeGif) {
1232          for (const pending of select2.getPendingVideoProcessing()) {
1233            dispatch.processItem(pending.id);
1234          }
1235        }
1236        if (currentOperation === OperationType.ResizeCrop || currentOperation === OperationType.Rotate || currentOperation === OperationType.TranscodeImage) {
1237          maybeRecycleVipsWorker(select2.getActiveImageProcessingCount());
1238        }
1239        if (parentId) {
1240          const parentItem = select2.getItem(parentId);
1241          if (parentItem) {
1242            const isOptionalCompanion = item.additionalData?.image_size === "animated_video" || item.additionalData?.image_size === "animated_video_poster";
1243            if (select2.hasPendingItemsByParentId(parentId)) {
1244              if (parentItem.operations && parentItem.operations.length > 0) {
1245                dispatch.processItem(parentId);
1246              }
1247            } else if (parentItem.subSizes && parentItem.subSizes.length > 0 || isOptionalCompanion) {
1248              if (parentItem.operations && parentItem.operations.length > 0) {
1249                dispatch.processItem(parentId);
1250              }
1251            } else {
1252              const parentAttachmentId = parentItem.attachment?.id;
1253              const { mediaDelete } = select2.getSettings();
1254              if (parentAttachmentId && mediaDelete) {
1255                mediaDelete(parentAttachmentId).catch(() => {
1256                });
1257              }
1258              await dispatch.cancelItem(
1259                parentId,
1260                new UploadError({
1261                  code: error instanceof UploadError && error.code || ErrorCode.GENERAL,
1262                  message: error?.message || (0, import_i18n5.__)("The image could not be uploaded."),
1263                  file: parentItem.file,
1264                  cause: error instanceof Error ? error : void 0
1265                })
1266              );
1267            }
1268          }
1269        }
1270        if (batchId && select2.isBatchUploaded(batchId)) {
1271          debug(`Batch completed: $batchId}`);
1272          item.onBatchSuccess?.();
1273        }
1274      };
1275    }
1276    function retryItem(id) {
1277      return async ({ select: select2, dispatch }) => {
1278        const item = select2.getItem(id);
1279        if (!item) {
1280          return;
1281        }
1282        if (!item.error) {
1283          return;
1284        }
1285        dispatch({
1286          type: Type.RetryItem,
1287          id
1288        });
1289        dispatch.processItem(id);
1290      };
1291    }
1292    function scheduleRetry(id, error) {
1293      return async ({ select: select2, dispatch }) => {
1294        const item = select2.getItem(id);
1295        if (!item) {
1296          return;
1297        }
1298        const settings = select2.getSettings();
1299        const retrySettings = settings.retry;
1300        if (!retrySettings) {
1301          return;
1302        }
1303        const currentRetryCount = item.retryCount ?? 0;
1304        const delay = calculateRetryDelay({
1305          attempt: currentRetryCount + 1,
1306          initialDelay: retrySettings.initialRetryDelayMs,
1307          maxDelay: retrySettings.maxRetryDelayMs,
1308          multiplier: retrySettings.backoffMultiplier,
1309          jitter: retrySettings.retryJitter
1310        });
1311        const timerId = setTimeout(() => {
1312          retryTimers.delete(id);
1313          dispatch.executeRetry(id);
1314        }, delay);
1315        retryTimers.set(id, timerId);
1316        dispatch({
1317          type: Type.ScheduleRetry,
1318          id,
1319          error,
1320          retryCount: currentRetryCount,
1321          nextRetryTimestamp: Date.now() + delay
1322        });
1323      };
1324    }
1325    function executeRetry(id) {
1326      return async ({ select: select2, dispatch }) => {
1327        const item = select2.getItem(id);
1328        if (!item || item.status !== ItemStatus.PendingRetry) {
1329          return;
1330        }
1331        if (select2.isPaused()) {
1332          return;
1333        }
1334        dispatch({
1335          type: Type.RetryItem,
1336          id
1337        });
1338        dispatch.processItem(id);
1339      };
1340    }
1341  
1342    // packages/upload-media/build-module/store/private-actions.mjs
1343    var private_actions_exports = {};
1344    __export(private_actions_exports, {
1345      addItem: () => addItem,
1346      addSideloadItem: () => addSideloadItem,
1347      detectUltraHdr: () => detectUltraHdr,
1348      finalizeItem: () => finalizeItem,
1349      finishOperation: () => finishOperation,
1350      generateThumbnails: () => generateThumbnails,
1351      getTranscodeImageOperation: () => getTranscodeImageOperation,
1352      pauseItem: () => pauseItem,
1353      pauseQueue: () => pauseQueue,
1354      prepareItem: () => prepareItem,
1355      processItem: () => processItem,
1356      removeItem: () => removeItem,
1357      resizeCropItem: () => resizeCropItem,
1358      resumeQueue: () => resumeQueue,
1359      revokeBlobUrls: () => revokeBlobUrls,
1360      rotateItem: () => rotateItem,
1361      sideloadItem: () => sideloadItem,
1362      transcodeGifItem: () => transcodeGifItem,
1363      transcodeImageItem: () => transcodeImageItem,
1364      updateItemProgress: () => updateItemProgress,
1365      updateSettings: () => updateSettings,
1366      uploadItem: () => uploadItem
1367    });
1368    var import_blob = __toESM(require_blob(), 1);
1369    var import_i18n7 = __toESM(require_i18n(), 1);
1370  
1371    // packages/upload-media/build-module/heic-parser.mjs
1372    var Reader = class {
1373      view;
1374      buffer;
1375      pos;
1376      constructor(buffer, offset = 0) {
1377        this.buffer = buffer;
1378        this.view = new DataView(buffer);
1379        this.pos = offset;
1380      }
1381      u8() {
1382        const v = this.view.getUint8(this.pos);
1383        this.pos += 1;
1384        return v;
1385      }
1386      u16() {
1387        const v = this.view.getUint16(this.pos);
1388        this.pos += 2;
1389        return v;
1390      }
1391      u32() {
1392        const v = this.view.getUint32(this.pos);
1393        this.pos += 4;
1394        return v;
1395      }
1396      u64() {
1397        const hi = this.view.getUint32(this.pos);
1398        const lo = this.view.getUint32(this.pos + 4);
1399        this.pos += 8;
1400        return hi * 4294967296 + lo;
1401      }
1402      /**
1403       * Read a variable-width unsigned integer (0, 4 or 8 bytes).
1404       *
1405       * @param size Byte width to read (0, 4, or 8).
1406       */
1407      uN(size) {
1408        if (size === 0) {
1409          return 0;
1410        }
1411        if (size === 4) {
1412          return this.u32();
1413        }
1414        if (size === 8) {
1415          return this.u64();
1416        }
1417        throw new Error(`Unsupported uint size: $size}`);
1418      }
1419      str(len) {
1420        let s = "";
1421        for (let i = 0; i < len; i++) {
1422          s += String.fromCharCode(this.view.getUint8(this.pos + i));
1423        }
1424        this.pos += len;
1425        return s;
1426      }
1427      bytes(len) {
1428        const b = new Uint8Array(this.buffer, this.pos, len);
1429        this.pos += len;
1430        return new Uint8Array(b);
1431      }
1432    };
1433    function readBox(r) {
1434      if (r.pos + 8 > r.view.byteLength) {
1435        return null;
1436      }
1437      const offset = r.pos;
1438      let size = r.u32();
1439      const type = r.str(4);
1440      let headerSize = 8;
1441      if (size === 1) {
1442        size = r.u64();
1443        headerSize = 16;
1444      } else if (size === 0) {
1445        size = r.view.byteLength - offset;
1446      }
1447      return { type, offset, size, headerSize };
1448    }
1449    function findBoxes(r, start, end) {
1450      const boxes = [];
1451      r.pos = start;
1452      while (r.pos < end) {
1453        const box = readBox(r);
1454        if (!box || box.size < 8) {
1455          break;
1456        }
1457        boxes.push(box);
1458        r.pos = box.offset + box.size;
1459      }
1460      return boxes;
1461    }
1462    function findBox(r, start, end, type) {
1463      r.pos = start;
1464      while (r.pos < end) {
1465        const box = readBox(r);
1466        if (!box || box.size < 8) {
1467          break;
1468        }
1469        if (box.type === type) {
1470          return box;
1471        }
1472        r.pos = box.offset + box.size;
1473      }
1474      return void 0;
1475    }
1476    function parsePitm(r, box) {
1477      r.pos = box.offset + box.headerSize;
1478      const version = r.u8();
1479      r.pos += 3;
1480      return version === 0 ? r.u16() : r.u32();
1481    }
1482    function parseIloc(r, box) {
1483      r.pos = box.offset + box.headerSize;
1484      const version = r.u8();
1485      r.pos += 3;
1486      const byte1 = r.u8();
1487      const offsetSize = byte1 >> 4 & 15;
1488      const lengthSize = byte1 & 15;
1489      const byte2 = r.u8();
1490      const baseOffsetSize = byte2 >> 4 & 15;
1491      const indexSize = version >= 1 ? byte2 & 15 : 0;
1492      const itemCount = version < 2 ? r.u16() : r.u32();
1493      const items = /* @__PURE__ */ new Map();
1494      for (let i = 0; i < itemCount; i++) {
1495        const itemId = version < 2 ? r.u16() : r.u32();
1496        let constructionMethod = 0;
1497        if (version === 1 || version === 2) {
1498          const cm = r.u16();
1499          constructionMethod = cm & 15;
1500        }
1501        r.u16();
1502        const baseOffset = r.uN(baseOffsetSize);
1503        const extentCount = r.u16();
1504        const extents = [];
1505        for (let j = 0; j < extentCount; j++) {
1506          if (version >= 1) {
1507            r.uN(indexSize);
1508          }
1509          const extOffset = r.uN(offsetSize);
1510          const extLength = r.uN(lengthSize);
1511          extents.push({
1512            offset: baseOffset + extOffset,
1513            length: extLength
1514          });
1515        }
1516        items.set(itemId, { constructionMethod, extents });
1517      }
1518      return items;
1519    }
1520    function parseIpma(r, box) {
1521      r.pos = box.offset + box.headerSize;
1522      const vf = r.u32();
1523      const version = vf >>> 24;
1524      const flags = vf & 16777215;
1525      const largeIndex = (flags & 1) !== 0;
1526      const entryCount = r.u32();
1527      const associations = /* @__PURE__ */ new Map();
1528      for (let i = 0; i < entryCount; i++) {
1529        const itemId = version < 1 ? r.u16() : r.u32();
1530        const assocCount = r.u8();
1531        const indices = [];
1532        for (let j = 0; j < assocCount; j++) {
1533          if (largeIndex) {
1534            indices.push(r.u16() & 32767);
1535          } else {
1536            indices.push(r.u8() & 127);
1537          }
1538        }
1539        associations.set(itemId, indices);
1540      }
1541      return associations;
1542    }
1543    function parseIspe(r, box) {
1544      r.pos = box.offset + box.headerSize + 4;
1545      return { width: r.u32(), height: r.u32() };
1546    }
1547    function parseIrot(r, box) {
1548      r.pos = box.offset + box.headerSize;
1549      return (r.u8() & 3) * 90;
1550    }
1551    function parseIinf(r, box) {
1552      r.pos = box.offset + box.headerSize;
1553      const version = r.u8();
1554      r.pos += 3;
1555      const entryCount = version === 0 ? r.u16() : r.u32();
1556      const itemTypes = /* @__PURE__ */ new Map();
1557      const entriesStart = r.pos;
1558      const boxEnd = box.offset + box.size;
1559      const infeBoxes = findBoxes(r, entriesStart, boxEnd);
1560      for (let i = 0; i < Math.min(entryCount, infeBoxes.length); i++) {
1561        const infe = infeBoxes[i];
1562        if (infe.type !== "infe") {
1563          continue;
1564        }
1565        r.pos = infe.offset + infe.headerSize;
1566        const infeVersion = r.u8();
1567        r.pos += 3;
1568        if (infeVersion >= 2) {
1569          const itemId = infeVersion === 2 ? r.u16() : r.u32();
1570          r.u16();
1571          const itemType = r.str(4);
1572          itemTypes.set(itemId, itemType);
1573        }
1574      }
1575      return itemTypes;
1576    }
1577    function parseIref(r, box, refType) {
1578      r.pos = box.offset + box.headerSize;
1579      const version = r.u8();
1580      r.pos += 3;
1581      const refs = /* @__PURE__ */ new Map();
1582      const boxEnd = box.offset + box.size;
1583      while (r.pos < boxEnd) {
1584        const refBox = readBox(r);
1585        if (!refBox || refBox.size < 8) {
1586          break;
1587        }
1588        r.pos = refBox.offset + refBox.headerSize;
1589        const fromId = version === 0 ? r.u16() : r.u32();
1590        const refCount = r.u16();
1591        const toIds = [];
1592        for (let i = 0; i < refCount; i++) {
1593          toIds.push(version === 0 ? r.u16() : r.u32());
1594        }
1595        if (refBox.type === refType) {
1596          refs.set(fromId, toIds);
1597        }
1598        r.pos = refBox.offset + refBox.size;
1599      }
1600      return refs;
1601    }
1602    function reverseBits32(n) {
1603      n = n >>> 1 & 1431655765 | (n & 1431655765) << 1;
1604      n = n >>> 2 & 858993459 | (n & 858993459) << 2;
1605      n = n >>> 4 & 252645135 | (n & 252645135) << 4;
1606      n = n >>> 8 & 16711935 | (n & 16711935) << 8;
1607      n = n >>> 16 | n << 16;
1608      return n >>> 0;
1609    }
1610    function buildCodecString(r, recordOffset) {
1611      r.pos = recordOffset;
1612      r.u8();
1613      const byte1 = r.u8();
1614      const profileSpace = byte1 >> 6 & 3;
1615      const tierFlag = byte1 >> 5 & 1;
1616      const profileIdc = byte1 & 31;
1617      const compatFlags = r.u32();
1618      const constraintBytes = r.bytes(6);
1619      const levelIdc = r.u8();
1620      const spacePrefix = profileSpace > 0 ? String.fromCharCode(64 + profileSpace) : "";
1621      const compatHex = reverseBits32(compatFlags).toString(16).toUpperCase();
1622      const tierChar = tierFlag ? "H" : "L";
1623      let lastNonZero = -1;
1624      for (let i = 5; i >= 0; i--) {
1625        if (constraintBytes[i] !== 0) {
1626          lastNonZero = i;
1627          break;
1628        }
1629      }
1630      let constraintStr = "";
1631      if (lastNonZero >= 0) {
1632        const parts = [];
1633        for (let i = 0; i <= lastNonZero; i++) {
1634          parts.push(constraintBytes[i].toString(16).toUpperCase());
1635        }
1636        constraintStr = "." + parts.join(".");
1637      }
1638      return `hvc1.$spacePrefix}$profileIdc}.$compatHex}.$tierChar}$levelIdc}$constraintStr}`;
1639    }
1640    function readItemData(buffer, loc, idatOffset) {
1641      const baseOffset = loc.constructionMethod === 1 ? idatOffset : 0;
1642      for (const ext of loc.extents) {
1643        if (baseOffset + ext.offset + ext.length > buffer.byteLength) {
1644          throw new Error(
1645            "HEIC item data extends past the end of the file"
1646          );
1647        }
1648      }
1649      if (loc.extents.length === 1) {
1650        const ext = loc.extents[0];
1651        const start = baseOffset + ext.offset;
1652        return new Uint8Array(buffer.slice(start, start + ext.length));
1653      }
1654      let totalLength = 0;
1655      for (const ext of loc.extents) {
1656        totalLength += ext.length;
1657      }
1658      const data = new Uint8Array(totalLength);
1659      let pos = 0;
1660      for (const ext of loc.extents) {
1661        const start = baseOffset + ext.offset;
1662        data.set(
1663          new Uint8Array(buffer.slice(start, start + ext.length)),
1664          pos
1665        );
1666        pos += ext.length;
1667      }
1668      return data;
1669    }
1670    function findHvcProperties(propIndices, properties) {
1671      let hvcCBox;
1672      let ispeBox;
1673      let irotBox;
1674      for (const idx of propIndices) {
1675        if (idx < 1 || idx > properties.length) {
1676          continue;
1677        }
1678        const prop = properties[idx - 1];
1679        if (prop.type === "hvcC" && !hvcCBox) {
1680          hvcCBox = prop;
1681        }
1682        if (prop.type === "ispe" && !ispeBox) {
1683          ispeBox = prop;
1684        }
1685        if (prop.type === "irot" && !irotBox) {
1686          irotBox = prop;
1687        }
1688      }
1689      if (!hvcCBox) {
1690        throw new Error("No HEVC configuration (hvcC) found");
1691      }
1692      if (!ispeBox) {
1693        throw new Error("No image dimensions (ispe) found");
1694      }
1695      return { hvcCBox, ispeBox, irotBox };
1696    }
1697    function parseHeic(buffer) {
1698      const r = new Reader(buffer);
1699      const fileEnd = buffer.byteLength;
1700      const metaBox = findBox(r, 0, fileEnd, "meta");
1701      if (!metaBox) {
1702        throw new Error("No meta box found in HEIC file");
1703      }
1704      const metaChildStart = metaBox.offset + metaBox.headerSize + 4;
1705      const metaEnd = metaBox.offset + metaBox.size;
1706      const children = findBoxes(r, metaChildStart, metaEnd);
1707      const pitmBox = children.find((b) => b.type === "pitm");
1708      const ilocBox = children.find((b) => b.type === "iloc");
1709      const iprpBox = children.find((b) => b.type === "iprp");
1710      const iinfBox = children.find((b) => b.type === "iinf");
1711      const irefBox = children.find((b) => b.type === "iref");
1712      const idatBox = children.find((b) => b.type === "idat");
1713      const idatOffset = idatBox ? idatBox.offset + idatBox.headerSize : 0;
1714      if (!pitmBox || !ilocBox || !iprpBox) {
1715        throw new Error("Missing required boxes (pitm, iloc, iprp) in HEIC");
1716      }
1717      const primaryId = parsePitm(r, pitmBox);
1718      const locations = parseIloc(r, ilocBox);
1719      const iprpStart = iprpBox.offset + iprpBox.headerSize;
1720      const iprpEnd = iprpBox.offset + iprpBox.size;
1721      const iprpChildren = findBoxes(r, iprpStart, iprpEnd);
1722      const ipcoBox = iprpChildren.find((b) => b.type === "ipco");
1723      const ipmaBox = iprpChildren.find((b) => b.type === "ipma");
1724      if (!ipcoBox || !ipmaBox) {
1725        throw new Error("Missing ipco or ipma in HEIC properties");
1726      }
1727      const allAssoc = parseIpma(r, ipmaBox);
1728      const ipcoStart = ipcoBox.offset + ipcoBox.headerSize;
1729      const ipcoEnd = ipcoBox.offset + ipcoBox.size;
1730      const properties = findBoxes(r, ipcoStart, ipcoEnd);
1731      let primaryItemType = "hvc1";
1732      if (iinfBox) {
1733        const itemTypes = parseIinf(r, iinfBox);
1734        const t = itemTypes.get(primaryId);
1735        if (t) {
1736          primaryItemType = t;
1737        }
1738      }
1739      if (primaryItemType === "grid") {
1740        return parseGridImage(
1741          r,
1742          buffer,
1743          primaryId,
1744          locations,
1745          allAssoc,
1746          properties,
1747          irefBox,
1748          idatOffset
1749        );
1750      }
1751      const primaryLoc = locations.get(primaryId);
1752      if (!primaryLoc || primaryLoc.extents.length === 0) {
1753        throw new Error(`No location data for primary item $primaryId}`);
1754      }
1755      const primaryPropIndices = allAssoc.get(primaryId);
1756      if (!primaryPropIndices || primaryPropIndices.length === 0) {
1757        throw new Error("No property associations for primary item");
1758      }
1759      const { hvcCBox, ispeBox, irotBox } = findHvcProperties(
1760        primaryPropIndices,
1761        properties
1762      );
1763      const hvcCDataStart = hvcCBox.offset + hvcCBox.headerSize;
1764      const hvcCDataSize = hvcCBox.size - hvcCBox.headerSize;
1765      const description = new Uint8Array(
1766        buffer.slice(hvcCDataStart, hvcCDataStart + hvcCDataSize)
1767      );
1768      const codecString = buildCodecString(r, hvcCDataStart);
1769      const { width, height } = parseIspe(r, ispeBox);
1770      const rotation = irotBox ? parseIrot(r, irotBox) : 0;
1771      return {
1772        codecString,
1773        description,
1774        tiles: [
1775          {
1776            data: readItemData(buffer, primaryLoc, idatOffset),
1777            x: 0,
1778            y: 0
1779          }
1780        ],
1781        tileWidth: width,
1782        tileHeight: height,
1783        outputWidth: width,
1784        outputHeight: height,
1785        rotation,
1786        exifOrientation: rotation === 0 ? getUnappliedExifOrientation(buffer) : 1
1787      };
1788    }
1789    function parseGridImage(r, buffer, gridItemId, locations, allAssoc, properties, irefBox, idatOffset) {
1790      const gridLoc = locations.get(gridItemId);
1791      if (!gridLoc || gridLoc.extents.length === 0) {
1792        throw new Error("No location data for grid item");
1793      }
1794      const gridData = readItemData(buffer, gridLoc, idatOffset);
1795      const largeFields = gridData.length > 1 && (gridData[1] & 1) !== 0;
1796      const minGridSize = largeFields ? 12 : 8;
1797      if (gridData.length < minGridSize) {
1798        throw new Error(
1799          `Grid descriptor too short: $gridData.length} bytes`
1800        );
1801      }
1802      const rows = gridData[2] + 1;
1803      const columns = gridData[3] + 1;
1804      const gv = new DataView(gridData.buffer, gridData.byteOffset);
1805      let outputWidth;
1806      let outputHeight;
1807      if (largeFields) {
1808        outputWidth = gv.getUint32(4);
1809        outputHeight = gv.getUint32(8);
1810      } else {
1811        outputWidth = gv.getUint16(4);
1812        outputHeight = gv.getUint16(6);
1813      }
1814      if (!irefBox) {
1815        throw new Error("Grid image requires iref box");
1816      }
1817      const dimgRefs = parseIref(r, irefBox, "dimg");
1818      const tileItemIds = dimgRefs.get(gridItemId);
1819      if (!tileItemIds || tileItemIds.length === 0) {
1820        throw new Error("No tile references found for grid item");
1821      }
1822      const expectedTiles = rows * columns;
1823      if (tileItemIds.length < expectedTiles) {
1824        throw new Error(
1825          `Grid expects $expectedTiles} tiles but found $tileItemIds.length}`
1826        );
1827      }
1828      const firstTileProps = allAssoc.get(tileItemIds[0]);
1829      if (!firstTileProps || firstTileProps.length === 0) {
1830        throw new Error("No property associations for tile item");
1831      }
1832      const { hvcCBox, ispeBox } = findHvcProperties(
1833        firstTileProps,
1834        properties
1835      );
1836      const gridProps = allAssoc.get(gridItemId) || [];
1837      let irotBox;
1838      for (const idx of gridProps) {
1839        if (idx >= 1 && idx <= properties.length) {
1840          const prop = properties[idx - 1];
1841          if (prop.type === "irot") {
1842            irotBox = prop;
1843            break;
1844          }
1845        }
1846      }
1847      const hvcCDataStart = hvcCBox.offset + hvcCBox.headerSize;
1848      const hvcCDataSize = hvcCBox.size - hvcCBox.headerSize;
1849      const description = new Uint8Array(
1850        buffer.slice(hvcCDataStart, hvcCDataStart + hvcCDataSize)
1851      );
1852      const codecString = buildCodecString(r, hvcCDataStart);
1853      const { width: tileWidth, height: tileHeight } = parseIspe(r, ispeBox);
1854      const tiles = [];
1855      for (let row = 0; row < rows; row++) {
1856        for (let col = 0; col < columns; col++) {
1857          const tileIdx = row * columns + col;
1858          const tileId = tileItemIds[tileIdx];
1859          const tileLoc = locations.get(tileId);
1860          if (!tileLoc || tileLoc.extents.length === 0) {
1861            throw new Error(`No location data for tile item $tileId}`);
1862          }
1863          tiles.push({
1864            data: readItemData(buffer, tileLoc, idatOffset),
1865            x: col * tileWidth,
1866            y: row * tileHeight
1867          });
1868        }
1869      }
1870      const rotation = irotBox ? parseIrot(r, irotBox) : 0;
1871      return {
1872        codecString,
1873        description,
1874        tiles,
1875        tileWidth,
1876        tileHeight,
1877        outputWidth,
1878        outputHeight,
1879        rotation,
1880        exifOrientation: rotation === 0 ? getUnappliedExifOrientation(buffer) : 1
1881      };
1882    }
1883    function readTiffOrientation(payload) {
1884      if (payload.length < 8) {
1885        return 1;
1886      }
1887      const view = new DataView(
1888        payload.buffer,
1889        payload.byteOffset,
1890        payload.byteLength
1891      );
1892      let tiffStart = 0;
1893      const firstWord = view.getUint16(0);
1894      if (firstWord !== 18761 && firstWord !== 19789) {
1895        tiffStart = view.getUint32(0) + 4;
1896      }
1897      if (tiffStart + 8 > payload.length) {
1898        return 1;
1899      }
1900      const byteOrder = view.getUint16(tiffStart);
1901      let little;
1902      if (byteOrder === 18761) {
1903        little = true;
1904      } else if (byteOrder === 19789) {
1905        little = false;
1906      } else {
1907        return 1;
1908      }
1909      const ifd0 = tiffStart + view.getUint32(tiffStart + 4, little);
1910      if (ifd0 + 2 > payload.length) {
1911        return 1;
1912      }
1913      const entryCount = view.getUint16(ifd0, little);
1914      for (let i = 0; i < entryCount; i++) {
1915        const entry = ifd0 + 2 + i * 12;
1916        if (entry + 12 > payload.length) {
1917          break;
1918        }
1919        if (view.getUint16(entry, little) === 274) {
1920          const value = view.getUint16(entry + 8, little);
1921          return value >= 1 && value <= 8 ? value : 1;
1922        }
1923      }
1924      return 1;
1925    }
1926    function findMeta(r) {
1927      const metaBox = findBox(r, 0, r.view.byteLength, "meta");
1928      if (!metaBox) {
1929        return null;
1930      }
1931      const start = metaBox.offset + metaBox.headerSize + 4;
1932      const end = metaBox.offset + metaBox.size;
1933      return { box: metaBox, children: findBoxes(r, start, end) };
1934    }
1935    function parseExifOrientation(buffer) {
1936      try {
1937        const r = new Reader(buffer);
1938        const meta = findMeta(r);
1939        if (!meta) {
1940          return 1;
1941        }
1942        const iinfBox = meta.children.find((b) => b.type === "iinf");
1943        const ilocBox = meta.children.find((b) => b.type === "iloc");
1944        if (!iinfBox || !ilocBox) {
1945          return 1;
1946        }
1947        const itemTypes = parseIinf(r, iinfBox);
1948        let exifItemId;
1949        for (const [id, type] of itemTypes) {
1950          if (type === "Exif") {
1951            exifItemId = id;
1952            break;
1953          }
1954        }
1955        if (exifItemId === void 0) {
1956          return 1;
1957        }
1958        const loc = parseIloc(r, ilocBox).get(exifItemId);
1959        if (!loc || loc.extents.length === 0) {
1960          return 1;
1961        }
1962        const idatBox = meta.children.find((b) => b.type === "idat");
1963        const idatOffset = idatBox ? idatBox.offset + idatBox.headerSize : 0;
1964        return readTiffOrientation(readItemData(buffer, loc, idatOffset));
1965      } catch {
1966        return 1;
1967      }
1968    }
1969    function hasNativeTransform(r) {
1970      const meta = findMeta(r);
1971      if (!meta) {
1972        return false;
1973      }
1974      const iprp = meta.children.find((b) => b.type === "iprp");
1975      if (!iprp) {
1976        return false;
1977      }
1978      const ipco = findBox(
1979        r,
1980        iprp.offset + iprp.headerSize,
1981        iprp.offset + iprp.size,
1982        "ipco"
1983      );
1984      if (!ipco) {
1985        return false;
1986      }
1987      const start = ipco.offset + ipco.headerSize;
1988      const end = ipco.offset + ipco.size;
1989      return Boolean(
1990        findBox(r, start, end, "irot") || findBox(r, start, end, "imir")
1991      );
1992    }
1993    function getUnappliedExifOrientation(buffer) {
1994      try {
1995        if (hasNativeTransform(new Reader(buffer))) {
1996          return 1;
1997        }
1998      } catch {
1999        return 1;
2000      }
2001      return parseExifOrientation(buffer);
2002    }
2003  
2004    // packages/upload-media/build-module/heic-support.mjs
2005    var import_i18n6 = __toESM(require_i18n(), 1);
2006    function detectBrowserFamily() {
2007      if (typeof navigator === "undefined") {
2008        return null;
2009      }
2010      const brands = navigator.userAgentData?.brands;
2011      if (brands?.length) {
2012        if (brands.some(({ brand }) => /Chromium/i.test(brand))) {
2013          return "chromium";
2014        }
2015      }
2016      const userAgent = navigator.userAgent || "";
2017      if (/Firefox|FxiOS/i.test(userAgent)) {
2018        return "firefox";
2019      }
2020      if (/Chrome|Chromium|CriOS|Edg|OPR/i.test(userAgent)) {
2021        return "chromium";
2022      }
2023      if (/Safari/i.test(userAgent)) {
2024        return "safari";
2025      }
2026      return null;
2027    }
2028    function detectPlatform() {
2029      if (typeof navigator === "undefined") {
2030        return "other";
2031      }
2032      const platform = navigator.userAgentData?.platform || navigator.userAgent || "";
2033      if (/iPhone|iPad|iPod|iOS/i.test(platform)) {
2034        return "other";
2035      }
2036      if (/macOS|Mac OS X|Macintosh/i.test(platform)) {
2037        return "macos";
2038      }
2039      if (/Windows/i.test(platform)) {
2040        return "windows";
2041      }
2042      if (/Android|CrOS|Chrome OS/i.test(platform)) {
2043        return "other";
2044      }
2045      if (/Linux|X11/i.test(platform)) {
2046        return "linux";
2047      }
2048      return "other";
2049    }
2050    function getBrowserName() {
2051      if (detectBrowserFamily() === "chromium") {
2052        const brands = navigator.userAgentData?.brands ?? [];
2053        const userAgent = navigator.userAgent || "";
2054        if (brands.some(({ brand }) => /Edge/i.test(brand)) || /Edg\//i.test(userAgent)) {
2055          return "Edge";
2056        }
2057        if (brands.some(({ brand }) => /Opera/i.test(brand)) || /OPR\//i.test(userAgent)) {
2058          return "Opera";
2059        }
2060        return "Chrome";
2061      }
2062      switch (detectBrowserFamily()) {
2063        case "firefox":
2064          return "Firefox";
2065        case "safari":
2066          return "Safari";
2067        default:
2068          return null;
2069      }
2070    }
2071    function getHeicConversionAdvice() {
2072      const platform = detectPlatform();
2073      const family = detectBrowserFamily();
2074      if (platform === "macos") {
2075        if (family === "chromium") {
2076          return (0, import_i18n6.__)(
2077            "Safari usually can, or you can upload a JPEG instead."
2078          );
2079        }
2080        if (family !== "safari") {
2081          return (0, import_i18n6.__)(
2082            "Safari or Chrome usually can, or you can upload a JPEG instead."
2083          );
2084        }
2085      }
2086      if (platform === "windows" && family === "firefox") {
2087        return (0, import_i18n6.__)("Chrome or Edge might, or you can upload a JPEG instead.");
2088      }
2089      return (0, import_i18n6.__)("You can upload a JPEG instead.");
2090    }
2091    function getHeicUnsupportedMessage() {
2092      const platform = detectPlatform();
2093      const family = detectBrowserFamily();
2094      const browserName = getBrowserName();
2095      let cause;
2096      if (platform === "linux") {
2097        cause = (0, import_i18n6.__)(
2098          "HEIC photos can't be decoded on Linux, so unfortunately we couldn't convert this one."
2099        );
2100      } else if (family === "firefox") {
2101        cause = (0, import_i18n6.__)(
2102          "Firefox can't read HEIC photos, so we couldn't convert this one."
2103        );
2104      } else if (browserName && platform === "windows") {
2105        cause = (0, import_i18n6.sprintf)(
2106          /* translators: %s: browser name, e.g. "Chrome". */
2107          (0, import_i18n6.__)(
2108            "%s couldn't decode HEIC on this PC, so we couldn't convert this one."
2109          ),
2110          browserName
2111        );
2112      } else if (browserName && platform === "macos") {
2113        cause = (0, import_i18n6.sprintf)(
2114          /* translators: %s: browser name, e.g. "Safari". */
2115          (0, import_i18n6.__)(
2116            "%s couldn't decode HEIC on this Mac, so we couldn't convert this one."
2117          ),
2118          browserName
2119        );
2120      } else if (browserName) {
2121        cause = (0, import_i18n6.sprintf)(
2122          /* translators: %s: browser name, e.g. "Chrome". */
2123          (0, import_i18n6.__)(
2124            "%s couldn't decode HEIC on this device, so we couldn't convert this one."
2125          ),
2126          browserName
2127        );
2128      } else {
2129        cause = (0, import_i18n6.__)(
2130          "This browser can't read HEIC photos, so we couldn't convert this one."
2131        );
2132      }
2133      return `$cause} $getHeicConversionAdvice()}`;
2134    }
2135  
2136    // packages/upload-media/build-module/canvas-utils.mjs
2137    var IMAGE_DECODER_TIMEOUT = 15e3;
2138    var HeicUnsupportedError = class extends Error {
2139    };
2140    async function canvasConvertToJpeg(file, quality = 0.82) {
2141      const baseName = getFileBasename(file.name);
2142      try {
2143        const bitmap = await createImageBitmap(file);
2144        try {
2145          const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
2146          const ctx = canvas.getContext("2d");
2147          if (!ctx) {
2148            throw new Error("Could not get canvas 2d context");
2149          }
2150          ctx.drawImage(bitmap, 0, 0);
2151          const jpegBlob = await canvas.convertToBlob({
2152            type: "image/jpeg",
2153            quality
2154          });
2155          return new File([jpegBlob], `$baseName}.jpg`, {
2156            type: "image/jpeg"
2157          });
2158        } finally {
2159          bitmap.close();
2160        }
2161      } catch {
2162      }
2163      if (typeof ImageDecoder !== "undefined") {
2164        const supported = await ImageDecoder.isTypeSupported(file.type);
2165        if (supported) {
2166          const decoder = new ImageDecoder({
2167            type: file.type,
2168            data: file.stream()
2169          });
2170          let videoFrame;
2171          let timeoutId;
2172          let timedOut = false;
2173          try {
2174            const decoded = await Promise.race([
2175              decoder.decode(),
2176              new Promise((_resolve, reject) => {
2177                timeoutId = setTimeout(() => {
2178                  timedOut = true;
2179                  decoder.close();
2180                  reject(
2181                    new Error("ImageDecoder decode timed out")
2182                  );
2183                }, IMAGE_DECODER_TIMEOUT);
2184              })
2185            ]);
2186            videoFrame = decoded.image;
2187          } catch (error) {
2188            if (!timedOut) {
2189              throw error;
2190            }
2191          } finally {
2192            clearTimeout(timeoutId);
2193            if (!timedOut) {
2194              decoder.close();
2195            }
2196          }
2197          if (videoFrame) {
2198            try {
2199              const canvas = new OffscreenCanvas(
2200                videoFrame.displayWidth,
2201                videoFrame.displayHeight
2202              );
2203              const ctx = canvas.getContext("2d");
2204              if (!ctx) {
2205                throw new Error("Could not get canvas 2d context");
2206              }
2207              ctx.drawImage(videoFrame, 0, 0);
2208              const jpegBlob = await canvas.convertToBlob({
2209                type: "image/jpeg",
2210                quality
2211              });
2212              return new File([jpegBlob], `$baseName}.jpg`, {
2213                type: "image/jpeg"
2214              });
2215            } finally {
2216              videoFrame.close();
2217            }
2218          }
2219        }
2220      }
2221      let heicData;
2222      try {
2223        heicData = parseHeic(await file.arrayBuffer());
2224      } catch (error) {
2225        throw new Error("The HEIC file could not be parsed", {
2226          cause: error
2227        });
2228      }
2229      if (typeof VideoDecoder !== "undefined") {
2230        let supported = false;
2231        try {
2232          const support = await VideoDecoder.isConfigSupported({
2233            codec: heicData.codecString
2234          });
2235          supported = support.supported === true;
2236        } catch {
2237        }
2238        if (supported) {
2239          const canvas = new OffscreenCanvas(
2240            heicData.outputWidth,
2241            heicData.outputHeight
2242          );
2243          const ctx = canvas.getContext("2d");
2244          if (!ctx) {
2245            throw new Error("Could not get canvas 2d context");
2246          }
2247          for (const tile of heicData.tiles) {
2248            const frame = await decodeHevcFrame(
2249              heicData.codecString,
2250              heicData.description,
2251              heicData.tileWidth,
2252              heicData.tileHeight,
2253              tile.data
2254            );
2255            try {
2256              ctx.drawImage(frame, tile.x, tile.y);
2257            } finally {
2258              frame.close();
2259            }
2260          }
2261          const outputCanvas = heicData.rotation !== 0 ? applyRotation(canvas, heicData.rotation) : applyExifOrientation(canvas, heicData.exifOrientation);
2262          const jpegBlob = await outputCanvas.convertToBlob({
2263            type: "image/jpeg",
2264            quality
2265          });
2266          return new File([jpegBlob], `$baseName}.jpg`, {
2267            type: "image/jpeg"
2268          });
2269        }
2270      }
2271      throw new HeicUnsupportedError(getHeicUnsupportedMessage());
2272    }
2273    function applyRotation(source, rotation) {
2274      if (rotation === 0) {
2275        return source;
2276      }
2277      const swap = rotation === 90 || rotation === 270;
2278      const w = swap ? source.height : source.width;
2279      const h = swap ? source.width : source.height;
2280      const rotated = new OffscreenCanvas(w, h);
2281      const ctx = rotated.getContext("2d");
2282      if (!ctx) {
2283        return source;
2284      }
2285      ctx.translate(w / 2, h / 2);
2286      ctx.rotate(-rotation * Math.PI / 180);
2287      ctx.drawImage(source, -source.width / 2, -source.height / 2);
2288      return rotated;
2289    }
2290    function applyExifOrientation(source, orientation) {
2291      if (orientation <= 1 || orientation > 8) {
2292        return source;
2293      }
2294      const { width: sw, height: sh } = source;
2295      const swap = orientation >= 5;
2296      const out = new OffscreenCanvas(swap ? sh : sw, swap ? sw : sh);
2297      const ctx = out.getContext("2d");
2298      if (!ctx) {
2299        return source;
2300      }
2301      switch (orientation) {
2302        case 2:
2303          ctx.transform(-1, 0, 0, 1, sw, 0);
2304          break;
2305        case 3:
2306          ctx.transform(-1, 0, 0, -1, sw, sh);
2307          break;
2308        case 4:
2309          ctx.transform(1, 0, 0, -1, 0, sh);
2310          break;
2311        case 5:
2312          ctx.transform(0, 1, 1, 0, 0, 0);
2313          break;
2314        case 6:
2315          ctx.transform(0, 1, -1, 0, sh, 0);
2316          break;
2317        case 7:
2318          ctx.transform(0, -1, -1, 0, sh, sw);
2319          break;
2320        case 8:
2321          ctx.transform(0, -1, 1, 0, 0, sw);
2322          break;
2323      }
2324      ctx.drawImage(source, 0, 0);
2325      return out;
2326    }
2327    function decodeHevcFrame(codec, description, width, height, data) {
2328      return new Promise((resolve, reject) => {
2329        const decoder = new VideoDecoder({
2330          output: (frame) => {
2331            decoder.close();
2332            resolve(frame);
2333          },
2334          error: (e) => {
2335            if (decoder.state !== "closed") {
2336              decoder.close();
2337            }
2338            reject(e);
2339          }
2340        });
2341        decoder.configure({
2342          codec,
2343          codedWidth: width,
2344          codedHeight: height,
2345          description
2346        });
2347        decoder.decode(
2348          new EncodedVideoChunk({
2349            type: "key",
2350            timestamp: 0,
2351            data
2352          })
2353        );
2354        decoder.flush().catch((e) => {
2355          if (decoder.state !== "closed") {
2356            decoder.close();
2357          }
2358          reject(e);
2359        });
2360      });
2361    }
2362  
2363    // packages/upload-media/build-module/feature-detection.mjs
2364    var cachedResult = null;
2365    function detectClientSideMediaSupport() {
2366      if (cachedResult !== null) {
2367        return cachedResult;
2368      }
2369      if (typeof WebAssembly === "undefined") {
2370        cachedResult = {
2371          supported: false,
2372          reason: "WebAssembly is not supported in this browser."
2373        };
2374        return cachedResult;
2375      }
2376      if (typeof SharedArrayBuffer === "undefined") {
2377        cachedResult = {
2378          supported: false,
2379          reason: "SharedArrayBuffer is not available. This may be due to missing cross-origin isolation headers."
2380        };
2381        return cachedResult;
2382      }
2383      if (typeof Worker === "undefined") {
2384        cachedResult = {
2385          supported: false,
2386          reason: "Web Workers are not supported in this browser."
2387        };
2388        return cachedResult;
2389      }
2390      if (typeof navigator !== "undefined" && "deviceMemory" in navigator && navigator.deviceMemory <= 2) {
2391        cachedResult = {
2392          supported: false,
2393          reason: "Device has insufficient memory for client-side media processing."
2394        };
2395        return cachedResult;
2396      }
2397      if (typeof navigator !== "undefined" && "hardwareConcurrency" in navigator && navigator.hardwareConcurrency < 2) {
2398        cachedResult = {
2399          supported: false,
2400          reason: "Device has insufficient CPU cores for client-side media processing."
2401        };
2402        return cachedResult;
2403      }
2404      if (typeof navigator !== "undefined") {
2405        const connection = navigator.connection;
2406        if (connection) {
2407          if (connection.saveData) {
2408            cachedResult = {
2409              supported: false,
2410              reason: "Data saver mode is enabled."
2411            };
2412            return cachedResult;
2413          }
2414          if (connection.effectiveType === "slow-2g" || connection.effectiveType === "2g") {
2415            cachedResult = {
2416              supported: false,
2417              reason: "Network connection is too slow for client-side media processing."
2418            };
2419            return cachedResult;
2420          }
2421        }
2422      }
2423      if (typeof window !== "undefined") {
2424        try {
2425          const testBlob = new Blob([""], {
2426            type: "application/javascript"
2427          });
2428          const testUrl = URL.createObjectURL(testBlob);
2429          try {
2430            const testWorker = new Worker(testUrl);
2431            testWorker.terminate();
2432          } finally {
2433            URL.revokeObjectURL(testUrl);
2434          }
2435        } catch {
2436          cachedResult = {
2437            supported: false,
2438            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."
2439          };
2440          return cachedResult;
2441        }
2442      }
2443      cachedResult = { supported: true };
2444      return cachedResult;
2445    }
2446    function isClientSideMediaSupported() {
2447      return detectClientSideMediaSupport().supported;
2448    }
2449    function isHeicCanvasSupported() {
2450      return typeof createImageBitmap !== "undefined" && typeof OffscreenCanvas !== "undefined";
2451    }
2452    function clearFeatureDetectionCache() {
2453      cachedResult = null;
2454    }
2455    var BYTES_PER_PIXEL = 4;
2456    var INTERLACED_MEMORY_BUDGET = 0.5 * 1024 * 1024 * 1024;
2457    var BASELINE_MEMORY_BUDGET = 0.9 * 1024 * 1024 * 1024;
2458    function exceedsClientProcessingMemory(dimensions) {
2459      const { width, height, interlaced } = dimensions;
2460      const estimatedBytes = width * height * BYTES_PER_PIXEL;
2461      const budget = interlaced ? INTERLACED_MEMORY_BUDGET : BASELINE_MEMORY_BUDGET;
2462      return estimatedBytes > budget;
2463    }
2464  
2465    // packages/upload-media/build-module/get-image-dimensions.mjs
2466    var MAX_HEADER_BYTES = 512 * 1024;
2467    function parseJpeg(view) {
2468      let offset = 2;
2469      while (offset < view.byteLength) {
2470        if (view.getUint8(offset) !== 255) {
2471          return null;
2472        }
2473        while (offset < view.byteLength && view.getUint8(offset) === 255) {
2474          offset++;
2475        }
2476        if (offset >= view.byteLength) {
2477          return null;
2478        }
2479        const marker = view.getUint8(offset);
2480        offset++;
2481        if (marker === 1 || marker >= 208 && marker <= 217) {
2482          continue;
2483        }
2484        if (marker === 218) {
2485          return null;
2486        }
2487        if (offset + 2 > view.byteLength) {
2488          return null;
2489        }
2490        const segmentLength = view.getUint16(offset);
2491        if (segmentLength < 2) {
2492          return null;
2493        }
2494        const isStartOfFrame = marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204;
2495        if (isStartOfFrame) {
2496          if (offset + 7 > view.byteLength) {
2497            return null;
2498          }
2499          const height = view.getUint16(offset + 3);
2500          const width = view.getUint16(offset + 5);
2501          const interlaced = marker === 194 || marker === 198 || marker === 202 || marker === 206;
2502          return { width, height, interlaced };
2503        }
2504        offset += segmentLength;
2505      }
2506      return null;
2507    }
2508    function parsePng(view) {
2509      if (view.byteLength < 29) {
2510        return null;
2511      }
2512      const isIhdr = view.getUint8(12) === 73 && // I
2513      view.getUint8(13) === 72 && // H
2514      view.getUint8(14) === 68 && // D
2515      view.getUint8(15) === 82;
2516      if (!isIhdr) {
2517        return null;
2518      }
2519      const width = view.getUint32(16);
2520      const height = view.getUint32(20);
2521      const interlaceMethod = view.getUint8(28);
2522      return { width, height, interlaced: interlaceMethod !== 0 };
2523    }
2524    async function getImageDimensions(file) {
2525      try {
2526        const headerBytes = Math.min(file.size, MAX_HEADER_BYTES);
2527        const buffer = await file.slice(0, headerBytes).arrayBuffer();
2528        const view = new DataView(buffer);
2529        if (view.byteLength >= 3 && view.getUint16(0) === 65496) {
2530          return parseJpeg(view);
2531        }
2532        if (view.byteLength >= 8 && view.getUint32(0) === 2303741511 && view.getUint32(4) === 218765834) {
2533          return parsePng(view);
2534        }
2535        return null;
2536      } catch {
2537        return null;
2538      }
2539    }
2540  
2541    // packages/upload-media/build-module/stub-file.mjs
2542    var StubFile = class extends File {
2543      constructor(fileName = "stub-file") {
2544        super([], fileName);
2545      }
2546    };
2547  
2548    // packages/upload-media/build-module/store/private-actions.mjs
2549    var DEFAULT_OUTPUT_QUALITY = 0.82;
2550    var ultraHdrItems = /* @__PURE__ */ new Set();
2551    function addItem({
2552      file: fileOrBlob,
2553      batchId,
2554      onChange,
2555      onSuccess,
2556      onBatchSuccess,
2557      onError,
2558      additionalData = {},
2559      sourceUrl,
2560      sourceAttachmentId,
2561      abortController,
2562      operations
2563    }) {
2564      return async ({ dispatch }) => {
2565        const itemId = v4_default();
2566        const file = convertBlobToFile(fileOrBlob);
2567        let blobUrl;
2568        if (!(file instanceof StubFile)) {
2569          blobUrl = (0, import_blob.createBlobURL)(file);
2570          dispatch({
2571            type: Type.CacheBlobUrl,
2572            id: itemId,
2573            blobUrl
2574          });
2575        }
2576        dispatch({
2577          type: Type.Add,
2578          item: {
2579            id: itemId,
2580            batchId,
2581            status: ItemStatus.Processing,
2582            sourceFile: cloneFile(file),
2583            file,
2584            attachment: {
2585              url: blobUrl
2586            },
2587            additionalData: {
2588              generate_sub_sizes: false,
2589              ...additionalData
2590            },
2591            onChange,
2592            onSuccess,
2593            onBatchSuccess,
2594            onError,
2595            sourceUrl,
2596            sourceAttachmentId,
2597            abortController: abortController || new AbortController(),
2598            operations: Array.isArray(operations) ? operations : [OperationType.Prepare]
2599          }
2600        });
2601        dispatch.processItem(itemId);
2602      };
2603    }
2604    function addSideloadItem({
2605      file,
2606      onChange,
2607      additionalData,
2608      operations,
2609      batchId,
2610      parentId
2611    }) {
2612      return ({ dispatch }) => {
2613        const itemId = v4_default();
2614        dispatch({
2615          type: Type.Add,
2616          item: {
2617            id: itemId,
2618            batchId,
2619            status: ItemStatus.Processing,
2620            sourceFile: cloneFile(file),
2621            file,
2622            onChange,
2623            additionalData: {
2624              ...additionalData
2625            },
2626            parentId,
2627            operations: Array.isArray(operations) ? operations : [OperationType.Prepare],
2628            abortController: new AbortController()
2629          }
2630        });
2631        dispatch.processItem(itemId);
2632      };
2633    }
2634    function processItem(id) {
2635      return async ({ select: select2, dispatch }) => {
2636        if (select2.isPaused()) {
2637          return;
2638        }
2639        const item = select2.getItem(id);
2640        if (!item) {
2641          return;
2642        }
2643        if (item.currentOperation) {
2644          return;
2645        }
2646        const {
2647          attachment,
2648          onChange,
2649          onSuccess,
2650          onBatchSuccess,
2651          batchId,
2652          parentId
2653        } = item;
2654        const operation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
2655        const operationArgs = Array.isArray(item.operations?.[0]) ? item.operations[0][1] : void 0;
2656        if (operation === OperationType.Upload) {
2657          const settings = select2.getSettings();
2658          const activeCount = select2.getActiveUploadCount();
2659          if (activeCount >= settings.maxConcurrentUploads) {
2660            return;
2661          }
2662        }
2663        if (operation === OperationType.ResizeCrop || operation === OperationType.Rotate) {
2664          const settings = select2.getSettings();
2665          const activeCount = select2.getActiveImageProcessingCount();
2666          if (activeCount >= settings.maxConcurrentImageProcessing) {
2667            return;
2668          }
2669        }
2670        if (operation === OperationType.TranscodeGif) {
2671          const activeCount = select2.getActiveVideoProcessingCount();
2672          if (activeCount >= 1) {
2673            return;
2674          }
2675        }
2676        if (attachment) {
2677          const isHeicUrl = attachment.url && /\.hei[cf]$/i.test(attachment.url);
2678          if (!isHeicUrl) {
2679            onChange?.([attachment]);
2680          }
2681        }
2682        if (!operation) {
2683          if (parentId || !parentId && !select2.hasPendingItemsByParentId(id)) {
2684            if (attachment) {
2685              onSuccess?.([attachment]);
2686            }
2687            dispatch.removeItem(id);
2688            dispatch.revokeBlobUrls(id);
2689            if (batchId && select2.isBatchUploaded(batchId)) {
2690              onBatchSuccess?.();
2691            }
2692          }
2693          if (parentId && batchId && select2.isBatchUploaded(batchId)) {
2694            const parentItem = select2.getItem(parentId);
2695            if (!parentItem) {
2696              return;
2697            }
2698            if (parentItem.operations && parentItem.operations.length > 0) {
2699              dispatch.processItem(parentId);
2700              return;
2701            }
2702            if (attachment) {
2703              parentItem.onSuccess?.([attachment]);
2704            }
2705            dispatch.removeItem(parentId);
2706            dispatch.revokeBlobUrls(parentId);
2707            if (parentItem.batchId && select2.isBatchUploaded(parentItem.batchId)) {
2708              parentItem.onBatchSuccess?.();
2709            }
2710          }
2711          return;
2712        }
2713        if (operation === OperationType.Finalize && select2.hasPendingItemsByParentId(id)) {
2714          return;
2715        }
2716        dispatch({
2717          type: Type.OperationStart,
2718          id,
2719          operation
2720        });
2721        debug(
2722          `Starting operation $operation} for $item.file.name} (item $item.id})`
2723        );
2724        switch (operation) {
2725          case OperationType.Prepare:
2726            dispatch.prepareItem(item.id);
2727            break;
2728          case OperationType.ResizeCrop:
2729            dispatch.resizeCropItem(
2730              item.id,
2731              operationArgs
2732            );
2733            break;
2734          case OperationType.Rotate:
2735            dispatch.rotateItem(
2736              item.id,
2737              operationArgs
2738            );
2739            break;
2740          case OperationType.TranscodeImage:
2741            dispatch.transcodeImageItem(
2742              item.id,
2743              operationArgs
2744            );
2745            break;
2746          case OperationType.TranscodeGif:
2747            dispatch.transcodeGifItem(
2748              item.id,
2749              operationArgs
2750            );
2751            break;
2752          case OperationType.Upload:
2753            if (item.parentId) {
2754              dispatch.sideloadItem(id);
2755            } else {
2756              dispatch.uploadItem(id);
2757            }
2758            break;
2759          case OperationType.ThumbnailGeneration:
2760            dispatch.generateThumbnails(id);
2761            break;
2762          case OperationType.Finalize:
2763            dispatch.finalizeItem(id);
2764            break;
2765          case OperationType.DetectUltraHdr:
2766            dispatch.detectUltraHdr(id);
2767            break;
2768        }
2769      };
2770    }
2771    function pauseQueue() {
2772      return {
2773        type: Type.PauseQueue
2774      };
2775    }
2776    function resumeQueue() {
2777      return async ({ select: select2, dispatch }) => {
2778        dispatch({
2779          type: Type.ResumeQueue
2780        });
2781        for (const item of select2.getAllItems()) {
2782          if (item.status === ItemStatus.PendingRetry) {
2783            dispatch.executeRetry(item.id);
2784          } else {
2785            dispatch.processItem(item.id);
2786          }
2787        }
2788      };
2789    }
2790    function pauseItem(id) {
2791      return async ({ dispatch }) => {
2792        dispatch({
2793          type: Type.PauseItem,
2794          id
2795        });
2796      };
2797    }
2798    function removeItem(id) {
2799      return async ({ select: select2, dispatch }) => {
2800        const item = select2.getItem(id);
2801        if (!item) {
2802          return;
2803        }
2804        ultraHdrItems.delete(id);
2805        clearRetryTimer(id);
2806        dispatch({
2807          type: Type.Remove,
2808          id
2809        });
2810        if (select2.getAllItems().length === 0) {
2811          terminateVipsWorker();
2812          terminateVideoConversionWorker();
2813        }
2814      };
2815    }
2816    function finishOperation(id, updates) {
2817      return async ({ select: select2, dispatch }) => {
2818        const item = select2.getItem(id);
2819        const previousOperation = item?.currentOperation;
2820        dispatch({
2821          type: Type.OperationFinish,
2822          id,
2823          item: updates
2824        });
2825        dispatch.processItem(id);
2826        if (previousOperation === OperationType.Upload) {
2827          const pendingUploads = select2.getPendingUploads();
2828          for (const pendingItem of pendingUploads) {
2829            dispatch.processItem(pendingItem.id);
2830          }
2831        }
2832        if (previousOperation === OperationType.ResizeCrop || previousOperation === OperationType.Rotate) {
2833          const pendingItems = select2.getPendingImageProcessing();
2834          for (const pendingItem of pendingItems) {
2835            dispatch.processItem(pendingItem.id);
2836          }
2837        }
2838        if (previousOperation === OperationType.TranscodeGif) {
2839          const pendingItems = select2.getPendingVideoProcessing();
2840          for (const pendingItem of pendingItems) {
2841            dispatch.processItem(pendingItem.id);
2842          }
2843        }
2844        if (previousOperation === OperationType.ResizeCrop || previousOperation === OperationType.Rotate || previousOperation === OperationType.TranscodeImage) {
2845          maybeRecycleVipsWorker(select2.getActiveImageProcessingCount());
2846        }
2847      };
2848    }
2849    var VALID_IMAGE_FORMATS = ["jpeg", "webp", "avif", "png", "gif"];
2850    function isValidImageFormat(format) {
2851      return VALID_IMAGE_FORMATS.includes(format);
2852    }
2853    async function getTranscodeImageOperation(file, outputMimeType, interlaced = false, quality = DEFAULT_OUTPUT_QUALITY) {
2854      if (file.type === "image/png" && outputMimeType === "image/jpeg") {
2855        const blobUrl = (0, import_blob.createBlobURL)(file);
2856        try {
2857          const hasAlpha = await vipsHasTransparency(blobUrl);
2858          if (hasAlpha) {
2859            return null;
2860          }
2861        } catch {
2862          return null;
2863        } finally {
2864          (0, import_blob.revokeBlobURL)(blobUrl);
2865        }
2866      }
2867      const formatPart = outputMimeType.split("/")[1];
2868      if (!isValidImageFormat(formatPart)) {
2869        return null;
2870      }
2871      return [
2872        OperationType.TranscodeImage,
2873        {
2874          outputFormat: formatPart,
2875          outputQuality: quality,
2876          interlaced
2877        }
2878      ];
2879    }
2880    function prepareItem(id) {
2881      return async ({ select: select2, dispatch }) => {
2882        const item = select2.getItem(id);
2883        if (!item) {
2884          return;
2885        }
2886        const { file } = item;
2887        const operations = [];
2888        const settings = select2.getSettings();
2889        if (file.type === "image/gif" && settings.gifConvert !== false && typeof ImageDecoder !== "undefined" && typeof VideoEncoder !== "undefined") {
2890          let isAnimated = false;
2891          try {
2892            isAnimated = isAnimatedGif(await file.arrayBuffer());
2893          } catch {
2894            isAnimated = false;
2895          }
2896          if (isAnimated) {
2897            let hasTransparency = false;
2898            const blobUrl = (0, import_blob.createBlobURL)(file);
2899            try {
2900              hasTransparency = await vipsHasTransparency(blobUrl);
2901            } catch {
2902              hasTransparency = true;
2903            } finally {
2904              (0, import_blob.revokeBlobURL)(blobUrl);
2905            }
2906            if (!hasTransparency) {
2907              operations.push(
2908                OperationType.Upload,
2909                OperationType.ThumbnailGeneration,
2910                OperationType.Finalize
2911              );
2912              dispatch({
2913                type: Type.AddOperations,
2914                id,
2915                operations
2916              });
2917              dispatch.finishOperation(id, {
2918                animatedGifFile: item.file
2919              });
2920              return;
2921            }
2922          }
2923        }
2924        let heicJpeg = null;
2925        const isHeic = await isHeicFile(file);
2926        const isMisnamedHeic = isHeic && !HEIC_MIME_TYPES.includes(file.type);
2927        const isImage = file.type.startsWith("image/") || isHeic;
2928        const isVipsSupported = !isHeic && CLIENT_SIDE_SUPPORTED_MIME_TYPES.includes(file.type);
2929        const heicFile = isMisnamedHeic ? new File([file], `$getFileBasename(file.name)}.heic`, {
2930          type: HEIC_MIME_TYPES[0],
2931          lastModified: file.lastModified
2932        }) : file;
2933        let tooLargeForClient = false;
2934        if (isImage && isVipsSupported) {
2935          const dimensions = await getImageDimensions(file);
2936          if (dimensions && exceedsClientProcessingMemory(dimensions)) {
2937            tooLargeForClient = true;
2938          }
2939        }
2940        if (file.type === "image/jpeg" && !isHeic && !tooLargeForClient) {
2941          operations.push(OperationType.DetectUltraHdr);
2942        }
2943        if (isImage && isVipsSupported && !tooLargeForClient) {
2944          operations.push(
2945            OperationType.Upload,
2946            OperationType.ThumbnailGeneration,
2947            OperationType.Finalize
2948          );
2949        } else if (isImage && isHeic) {
2950          try {
2951            heicJpeg = await canvasConvertToJpeg(
2952              heicFile,
2953              settings.imageQuality ?? DEFAULT_OUTPUT_QUALITY
2954            );
2955          } catch (error) {
2956            const unsupported = error instanceof HeicUnsupportedError;
2957            dispatch.cancelItem(
2958              id,
2959              new UploadError({
2960                code: unsupported ? ErrorCode.HEIC_DECODE_ERROR : ErrorCode.IMAGE_TRANSCODING_ERROR,
2961                message: unsupported ? getHeicUnsupportedMessage() : (0, import_i18n7.__)(
2962                  "This HEIC image could not be converted. Try converting it to JPEG before uploading."
2963                ),
2964                file,
2965                cause: error instanceof Error ? error : void 0
2966              })
2967            );
2968            return;
2969          }
2970          operations.push(
2971            OperationType.Upload,
2972            OperationType.ThumbnailGeneration,
2973            OperationType.Finalize
2974          );
2975        } else {
2976          operations.push(OperationType.Upload);
2977        }
2978        dispatch({
2979          type: Type.AddOperations,
2980          id,
2981          operations
2982        });
2983        let updates;
2984        if (isHeic && heicJpeg) {
2985          const vipsAvailable = isClientSideMediaSupported();
2986          updates = {
2987            file: heicJpeg,
2988            sourceFile: heicJpeg,
2989            originalHeicFile: heicFile,
2990            additionalData: {
2991              ...item.additionalData,
2992              generate_sub_sizes: !vipsAvailable,
2993              convert_format: true
2994            }
2995          };
2996        } else if (!isVipsSupported || !isImage || tooLargeForClient) {
2997          updates = {
2998            additionalData: {
2999              ...item.additionalData,
3000              generate_sub_sizes: true,
3001              convert_format: true
3002            }
3003          };
3004        } else {
3005          updates = {
3006            additionalData: {
3007              ...item.additionalData,
3008              generate_sub_sizes: false
3009            }
3010          };
3011        }
3012        dispatch.finishOperation(id, updates);
3013      };
3014    }
3015    function detectUltraHdr(id) {
3016      return async ({ select: select2, dispatch }) => {
3017        const item = select2.getItem(id);
3018        if (!item) {
3019          return;
3020        }
3021        let info;
3022        try {
3023          const buffer = await item.file.arrayBuffer();
3024          info = await vipsGetUltraHdrInfo(buffer);
3025        } catch {
3026        }
3027        if (info) {
3028          ultraHdrItems.add(id);
3029        }
3030        dispatch.finishOperation(id, {});
3031      };
3032    }
3033    function uploadItem(id) {
3034      return async ({ select: select2, dispatch }) => {
3035        const item = select2.getItem(id);
3036        if (!item) {
3037          return;
3038        }
3039        const startTime = performance.now();
3040        let finished = false;
3041        const finishUpload = (attachment) => {
3042          if (finished) {
3043            return;
3044          }
3045          finished = true;
3046          measure({
3047            measureName: `Upload $item.file.name}`,
3048            startTime,
3049            tooltipText: item.file.name,
3050            properties: [
3051              ["Item ID", item.id],
3052              ["File name", item.file.name]
3053            ]
3054          });
3055          dispatch.finishOperation(id, { attachment });
3056        };
3057        select2.getSettings().mediaUpload({
3058          filesList: [item.file],
3059          additionalData: item.additionalData,
3060          signal: item.abortController?.signal,
3061          // The queue's own items drive upload progress UI and save
3062          // locking; without this, consumers that track uploads themselves
3063          // (e.g. the editor's progress snackbar) would count this file a
3064          // second time.
3065          isTransportOnly: true,
3066          onFileChange: ([attachment]) => {
3067            if (attachment && !(0, import_blob.isBlobURL)(attachment.url)) {
3068              finishUpload(attachment);
3069            }
3070          },
3071          onSuccess: ([attachment]) => {
3072            finishUpload(attachment);
3073          },
3074          onError: (error) => {
3075            dispatch.cancelItem(id, error);
3076          }
3077        });
3078      };
3079    }
3080    function sideloadItem(id) {
3081      return async ({ select: select2, dispatch }) => {
3082        const item = select2.getItem(id);
3083        if (!item) {
3084          return;
3085        }
3086        const { post, ...additionalData } = item.additionalData;
3087        const mediaSideload = select2.getSettings().mediaSideload;
3088        if (!mediaSideload) {
3089          dispatch.finishOperation(id, {});
3090          return;
3091        }
3092        const startTime = performance.now();
3093        mediaSideload({
3094          file: item.file,
3095          attachmentId: post,
3096          additionalData,
3097          signal: item.abortController?.signal,
3098          onSuccess: (subSize) => {
3099            measure({
3100              measureName: `Sideload $item.file.name}`,
3101              startTime,
3102              tooltipText: item.file.name,
3103              properties: [
3104                ["Item ID", item.id],
3105                ["File name", item.file.name]
3106              ]
3107            });
3108            if (item.parentId) {
3109              dispatch({
3110                type: Type.AccumulateSubSize,
3111                id: item.parentId,
3112                subSize
3113              });
3114            }
3115            dispatch.finishOperation(id, {});
3116          },
3117          onError: (error) => {
3118            dispatch.cancelItem(id, error);
3119          }
3120        });
3121      };
3122    }
3123    function resizeCropItem(id, args) {
3124      return async ({ select: select2, dispatch }) => {
3125        const item = select2.getItem(id);
3126        if (!item) {
3127          return;
3128        }
3129        if (!args?.resize) {
3130          dispatch.finishOperation(id, {
3131            file: item.file
3132          });
3133          return;
3134        }
3135        const startTime = performance.now();
3136        const addSuffix = Boolean(item.parentId);
3137        const scaledSuffix = Boolean(args.isThresholdResize);
3138        const { imageStripMeta, imageMaxBitDepth } = select2.getSettings();
3139        try {
3140          const file = await vipsResizeImage(
3141            item.id,
3142            item.file,
3143            args.resize,
3144            {
3145              smartCrop: false,
3146              addSuffix,
3147              signal: item.abortController?.signal,
3148              scaledSuffix,
3149              quality: args.quality,
3150              stripMeta: imageStripMeta,
3151              maxBitdepth: imageMaxBitDepth
3152            }
3153          );
3154          measure({
3155            measureName: `ResizeCrop $item.file.name}`,
3156            startTime,
3157            tooltipText: item.file.name,
3158            properties: [
3159              ["Item ID", item.id],
3160              ["File name", item.file.name]
3161            ]
3162          });
3163          const blobUrl = (0, import_blob.createBlobURL)(file);
3164          dispatch({
3165            type: Type.CacheBlobUrl,
3166            id,
3167            blobUrl
3168          });
3169          dispatch.finishOperation(id, {
3170            file,
3171            attachment: {
3172              url: blobUrl
3173            }
3174          });
3175        } catch (error) {
3176          dispatch.cancelItem(
3177            id,
3178            new UploadError({
3179              code: ErrorCode.IMAGE_TRANSCODING_ERROR,
3180              message: (0, import_i18n7.__)(
3181                "The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading."
3182              ),
3183              file: item.file,
3184              cause: error instanceof Error ? error : void 0
3185            })
3186          );
3187        }
3188      };
3189    }
3190    function rotateItem(id, args) {
3191      return async ({ select: select2, dispatch }) => {
3192        const item = select2.getItem(id);
3193        if (!item) {
3194          return;
3195        }
3196        if (!args?.orientation || args.orientation === 1) {
3197          dispatch.finishOperation(id, {
3198            file: item.file
3199          });
3200          return;
3201        }
3202        const startTime = performance.now();
3203        try {
3204          const file = await vipsRotateImage(
3205            item.id,
3206            item.file,
3207            args.orientation,
3208            item.abortController?.signal
3209          );
3210          measure({
3211            measureName: `Rotate $item.file.name}`,
3212            startTime,
3213            tooltipText: item.file.name,
3214            properties: [
3215              ["Item ID", item.id],
3216              ["File name", item.file.name]
3217            ]
3218          });
3219          const blobUrl = (0, import_blob.createBlobURL)(file);
3220          dispatch({
3221            type: Type.CacheBlobUrl,
3222            id,
3223            blobUrl
3224          });
3225          dispatch.finishOperation(id, {
3226            file,
3227            attachment: {
3228              url: blobUrl
3229            }
3230          });
3231        } catch (error) {
3232          dispatch.cancelItem(
3233            id,
3234            new UploadError({
3235              code: ErrorCode.IMAGE_ROTATION_ERROR,
3236              message: (0, import_i18n7.__)(
3237                "The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading."
3238              ),
3239              file: item.file,
3240              cause: error instanceof Error ? error : void 0
3241            })
3242          );
3243        }
3244      };
3245    }
3246    function transcodeImageItem(id, args) {
3247      return async ({ select: select2, dispatch }) => {
3248        const item = select2.getItem(id);
3249        if (!item) {
3250          return;
3251        }
3252        if (!args?.outputFormat) {
3253          dispatch.finishOperation(id, {
3254            file: item.file
3255          });
3256          return;
3257        }
3258        const startTime = performance.now();
3259        const outputMimeType = `image/$args.outputFormat}`;
3260        const quality = args.outputQuality ?? DEFAULT_OUTPUT_QUALITY;
3261        const interlaced = args.interlaced ?? false;
3262        const { imageStripMeta, imageMaxBitDepth } = select2.getSettings();
3263        try {
3264          const file = await vipsConvertImageFormat(
3265            item.id,
3266            item.file,
3267            outputMimeType,
3268            {
3269              quality,
3270              interlaced,
3271              stripMeta: imageStripMeta,
3272              maxBitdepth: imageMaxBitDepth
3273            }
3274          );
3275          measure({
3276            measureName: `Transcode $item.file.name}`,
3277            startTime,
3278            tooltipText: item.file.name,
3279            properties: [
3280              ["Item ID", item.id],
3281              ["File name", item.file.name]
3282            ]
3283          });
3284          const blobUrl = (0, import_blob.createBlobURL)(file);
3285          dispatch({
3286            type: Type.CacheBlobUrl,
3287            id,
3288            blobUrl
3289          });
3290          dispatch.finishOperation(id, {
3291            file,
3292            attachment: {
3293              url: blobUrl
3294            }
3295          });
3296        } catch (error) {
3297          dispatch.cancelItem(
3298            id,
3299            new UploadError({
3300              code: ErrorCode.MEDIA_TRANSCODING_ERROR,
3301              message: "Image could not be transcoded to the target format",
3302              file: item.file,
3303              cause: error instanceof Error ? error : void 0
3304            })
3305          );
3306        }
3307      };
3308    }
3309    function transcodeGifItem(id, args) {
3310      return async ({ select: select2, dispatch }) => {
3311        const item = select2.getItem(id);
3312        if (!item) {
3313          return;
3314        }
3315        const outputFormat = args?.outputFormat ?? "mp4";
3316        const outputMimeType = `video/$outputFormat}`;
3317        const gifFile = item.file;
3318        try {
3319          const file = await convertGifToVideo(
3320            item.id,
3321            gifFile,
3322            outputMimeType,
3323            {
3324              timeout: args?.timeout,
3325              maxTotalPixels: args?.maxTotalPixels
3326            }
3327          );
3328          dispatch.finishOperation(id, { file });
3329          dispatch.addSideloadItem({
3330            file: gifFile,
3331            batchId: v4_default(),
3332            parentId: item.parentId,
3333            additionalData: {
3334              post: item.additionalData?.post,
3335              image_size: "animated_video_poster",
3336              convert_format: false
3337            },
3338            operations: [
3339              [
3340                OperationType.TranscodeImage,
3341                {
3342                  outputFormat: "jpeg",
3343                  outputQuality: DEFAULT_OUTPUT_QUALITY,
3344                  interlaced: false
3345                }
3346              ],
3347              OperationType.Upload
3348            ]
3349          });
3350        } catch (error) {
3351          if (isUnsupportedConversionError(error)) {
3352            if (isSizeLimitConversionError(error)) {
3353              debug(
3354                `Skipping GIF to video conversion: $error instanceof Error ? error.message : error}`
3355              );
3356            }
3357            dispatch.cancelItem(
3358              id,
3359              new Error("Animated GIF conversion unsupported"),
3360              true
3361            );
3362            return;
3363          }
3364          if (isConversionTimeoutError(error)) {
3365            debug(
3366              `GIF to video conversion timed out; keeping the original GIF only: $error instanceof Error ? error.message : error}`
3367            );
3368            dispatch.cancelItem(
3369              id,
3370              new Error("Animated GIF conversion timed out"),
3371              true
3372            );
3373            return;
3374          }
3375          console.error(
3376            "[video-conversion] GIF to video conversion failed:",
3377            error
3378          );
3379          dispatch.cancelItem(
3380            id,
3381            new UploadError({
3382              code: ErrorCode.GIF_TRANSCODING_ERROR,
3383              message: "Animated GIF could not be converted to video",
3384              file: item.file,
3385              cause: error instanceof Error ? error : void 0
3386            }),
3387            true
3388          );
3389        }
3390      };
3391    }
3392    function generateThumbnails(id) {
3393      return async ({ select: select2, dispatch }) => {
3394        const item = select2.getItem(id);
3395        if (!item) {
3396          return;
3397        }
3398        if (!item.attachment) {
3399          dispatch.finishOperation(id, {});
3400          return;
3401        }
3402        const attachment = item.attachment;
3403        const settings = select2.getSettings();
3404        if (item.originalHeicFile && attachment.id) {
3405          dispatch.addSideloadItem({
3406            file: item.originalHeicFile,
3407            batchId: v4_default(),
3408            parentId: item.id,
3409            additionalData: {
3410              post: attachment.id,
3411              image_size: "source_original",
3412              convert_format: false
3413            },
3414            operations: [OperationType.Upload]
3415          });
3416        }
3417        if (item.animatedGifFile && attachment.id) {
3418          const outputFormat = settings.videoOutputFormat === "video/webm" ? "webm" : "mp4";
3419          dispatch.addSideloadItem({
3420            file: item.animatedGifFile,
3421            batchId: v4_default(),
3422            parentId: item.id,
3423            additionalData: {
3424              post: attachment.id,
3425              image_size: "animated_video",
3426              convert_format: false
3427            },
3428            operations: [
3429              [
3430                OperationType.TranscodeGif,
3431                {
3432                  outputFormat
3433                }
3434              ],
3435              OperationType.Upload
3436            ]
3437          });
3438        }
3439        let exifOrientation = attachment.exif_orientation || 1;
3440        const sourceType = item.sourceFile.type;
3441        const isHeifFamily = sourceType === "image/avif" || sourceType === "image/heif";
3442        let needsClientRotation = false;
3443        if (isHeifFamily) {
3444          exifOrientation = getUnappliedExifOrientation(
3445            await item.sourceFile.arrayBuffer()
3446          );
3447          needsClientRotation = exifOrientation !== 1;
3448        }
3449        let rotatedSource;
3450        {
3451          const needsRotation = exifOrientation !== 1 && !item.file.name.includes("-scaled");
3452          if ((needsRotation || needsClientRotation) && attachment.id) {
3453            try {
3454              rotatedSource = await vipsRotateImage(
3455                item.id,
3456                item.sourceFile,
3457                exifOrientation,
3458                item.abortController?.signal
3459              );
3460            } catch {
3461              console.warn(
3462                "Failed to rotate image, continuing with thumbnails"
3463              );
3464            }
3465          }
3466          if (needsRotation && rotatedSource && attachment.id) {
3467            dispatch.addSideloadItem({
3468              file: rotatedSource,
3469              batchId: v4_default(),
3470              parentId: item.id,
3471              additionalData: {
3472                post: attachment.id,
3473                image_size: "original",
3474                convert_format: false
3475              },
3476              operations: [OperationType.Upload]
3477            });
3478          }
3479        }
3480        if (!item.parentId && attachment.missing_image_sizes && attachment.missing_image_sizes.length > 0) {
3481          const allImageSizes = settings.allImageSizes || {};
3482          const sizesToGenerate = attachment.missing_image_sizes;
3483          const thumbnailSource = needsClientRotation && rotatedSource ? rotatedSource : item.sourceFile;
3484          const file = attachment.filename ? renameFile(thumbnailSource, attachment.filename) : thumbnailSource;
3485          const batchId = v4_default();
3486          const isUltraHdr = ultraHdrItems.has(item.id);
3487          const outputMimeType = attachment.image_output_format;
3488          const interlaced = attachment.image_save_progressive ?? false;
3489          const imageQuality = attachment.image_quality;
3490          const fallbackQuality = settings.imageQuality ?? DEFAULT_OUTPUT_QUALITY;
3491          const defaultQuality = typeof imageQuality?.default === "number" ? imageQuality.default / 100 : fallbackQuality;
3492          const qualityForSize = (sizeName) => {
3493            const sized = imageQuality?.sizes?.[sizeName];
3494            if (typeof sized === "number") {
3495              return sized / 100;
3496            }
3497            return defaultQuality;
3498          };
3499          let thumbnailTranscodeOperation = null;
3500          if (!isUltraHdr && outputMimeType) {
3501            thumbnailTranscodeOperation = await getTranscodeImageOperation(
3502              thumbnailSource,
3503              outputMimeType,
3504              interlaced,
3505              defaultQuality
3506            );
3507          }
3508          const dimensionGroups = /* @__PURE__ */ new Map();
3509          for (const name of sizesToGenerate) {
3510            const imageSize = allImageSizes[name];
3511            if (!imageSize) {
3512              console.warn(
3513                `Image size "$name}" not found in configuration`
3514              );
3515              continue;
3516            }
3517            const key = `$imageSize.width}x$imageSize.height}x$imageSize.crop}`;
3518            const group = dimensionGroups.get(key);
3519            if (group) {
3520              group.push(name);
3521            } else {
3522              dimensionGroups.set(key, [name]);
3523            }
3524          }
3525          for (const [, names] of dimensionGroups) {
3526            const imageSize = allImageSizes[names[0]];
3527            const sizeQuality = qualityForSize(names[0]);
3528            const thumbnailOperations = [
3529              [
3530                OperationType.ResizeCrop,
3531                { resize: imageSize, quality: sizeQuality }
3532              ]
3533            ];
3534            if (!isUltraHdr && thumbnailTranscodeOperation) {
3535              thumbnailOperations.push([
3536                thumbnailTranscodeOperation[0],
3537                {
3538                  ...thumbnailTranscodeOperation[1],
3539                  outputQuality: sizeQuality
3540                }
3541              ]);
3542            }
3543            thumbnailOperations.push(OperationType.Upload);
3544            const imageSizeParam = names.length === 1 ? names[0] : names;
3545            dispatch.addSideloadItem({
3546              file,
3547              batchId,
3548              parentId: item.id,
3549              additionalData: {
3550                // Sideloading does not use the parent post ID but the
3551                // attachment ID as the image sizes need to be added to it.
3552                post: attachment.id,
3553                image_size: imageSizeParam,
3554                convert_format: false
3555              },
3556              operations: thumbnailOperations
3557            });
3558          }
3559          {
3560            const { bigImageSizeThreshold } = settings;
3561            if (bigImageSizeThreshold && attachment.id) {
3562              const bitmap = await createImageBitmap(thumbnailSource);
3563              const needsScaling = bitmap.width > bigImageSizeThreshold || bitmap.height > bigImageSizeThreshold;
3564              bitmap.close();
3565              if (needsScaling) {
3566                const sourceForScaled = attachment.filename ? renameFile(thumbnailSource, attachment.filename) : thumbnailSource;
3567                const scaledOperations = [
3568                  [
3569                    OperationType.ResizeCrop,
3570                    {
3571                      resize: {
3572                        width: bigImageSizeThreshold,
3573                        height: bigImageSizeThreshold
3574                      },
3575                      isThresholdResize: true,
3576                      quality: defaultQuality
3577                    }
3578                  ]
3579                ];
3580                if (!isUltraHdr && thumbnailTranscodeOperation) {
3581                  scaledOperations.push(
3582                    thumbnailTranscodeOperation
3583                  );
3584                }
3585                scaledOperations.push(OperationType.Upload);
3586                dispatch.addSideloadItem({
3587                  file: sourceForScaled,
3588                  batchId,
3589                  parentId: item.id,
3590                  additionalData: {
3591                    post: attachment.id,
3592                    image_size: "scaled",
3593                    convert_format: false
3594                  },
3595                  operations: scaledOperations
3596                });
3597              }
3598            }
3599          }
3600        }
3601        dispatch.finishOperation(id, {});
3602      };
3603    }
3604    function finalizeItem(id) {
3605      return async ({ select: select2, dispatch }) => {
3606        const item = select2.getItem(id);
3607        if (!item) {
3608          return;
3609        }
3610        const attachment = item.attachment;
3611        const { mediaFinalize } = select2.getSettings();
3612        const updates = {};
3613        if (attachment?.id && mediaFinalize) {
3614          try {
3615            const updatedAttachment = await mediaFinalize(
3616              attachment.id,
3617              item.subSizes || []
3618            );
3619            if (updatedAttachment) {
3620              updates.attachment = updatedAttachment;
3621            }
3622          } catch (error) {
3623            console.warn("Media finalization failed:", error);
3624            dispatch.cancelItem(
3625              id,
3626              new UploadError({
3627                code: ErrorCode.MEDIA_FINALIZE_ERROR,
3628                message: (0, import_i18n7.__)("Could not finalize the upload."),
3629                file: item.file
3630              })
3631            );
3632            return;
3633          }
3634        }
3635        dispatch.finishOperation(id, updates);
3636      };
3637    }
3638    function revokeBlobUrls(id) {
3639      return async ({ select: select2, dispatch }) => {
3640        const blobUrls = select2.getBlobUrls(id);
3641        for (const blobUrl of blobUrls) {
3642          (0, import_blob.revokeBlobURL)(blobUrl);
3643        }
3644        dispatch({
3645          type: Type.RevokeBlobUrls,
3646          id
3647        });
3648      };
3649    }
3650    function updateItemProgress(id, progress) {
3651      return async ({ dispatch }) => {
3652        dispatch({
3653          type: Type.UpdateProgress,
3654          id,
3655          progress
3656        });
3657      };
3658    }
3659    function updateSettings(settings) {
3660      return {
3661        type: Type.UpdateSettings,
3662        settings
3663      };
3664    }
3665  
3666    // packages/upload-media/build-module/lock-unlock.mjs
3667    var import_private_apis = __toESM(require_private_apis(), 1);
3668    var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)(
3669      "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.",
3670      "@wordpress/upload-media"
3671    );
3672  
3673    // packages/upload-media/build-module/store/index.mjs
3674    var storeConfig = {
3675      reducer: reducer_default,
3676      selectors: selectors_exports,
3677      actions: actions_exports
3678    };
3679    var store = (0, import_data.createReduxStore)(STORE_NAME, {
3680      reducer: reducer_default,
3681      selectors: selectors_exports,
3682      actions: actions_exports
3683    });
3684    if (!(0, import_data.select)(store)) {
3685      (0, import_data.register)(store);
3686    }
3687    unlock(store).registerPrivateActions(private_actions_exports);
3688    unlock(store).registerPrivateSelectors(private_selectors_exports);
3689  
3690    // packages/upload-media/build-module/components/provider/index.mjs
3691    var import_element2 = __toESM(require_element(), 1);
3692    var import_data3 = __toESM(require_data(), 1);
3693  
3694    // packages/upload-media/build-module/components/provider/with-registry-provider.mjs
3695    var import_element = __toESM(require_element(), 1);
3696    var import_data2 = __toESM(require_data(), 1);
3697    var import_compose = __toESM(require_compose(), 1);
3698    var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
3699    function getSubRegistry(subRegistries, registry, useSubRegistry) {
3700      if (!useSubRegistry) {
3701        return registry;
3702      }
3703      let subRegistry = subRegistries.get(registry);
3704      if (!subRegistry) {
3705        subRegistry = (0, import_data2.createRegistry)({}, registry);
3706        subRegistry.registerStore(STORE_NAME, storeConfig);
3707        subRegistries.set(registry, subRegistry);
3708      }
3709      return subRegistry;
3710    }
3711    var withRegistryProvider = (0, import_compose.createHigherOrderComponent)(
3712      (WrappedComponent) => ({ useSubRegistry = true, ...props }) => {
3713        const registry = (0, import_data2.useRegistry)();
3714        const [subRegistries] = (0, import_element.useState)(() => /* @__PURE__ */ new WeakMap());
3715        const subRegistry = getSubRegistry(
3716          subRegistries,
3717          registry,
3718          useSubRegistry
3719        );
3720        if (subRegistry === registry) {
3721          return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WrappedComponent, { registry, ...props });
3722        }
3723        return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_data2.RegistryProvider, { value: subRegistry, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WrappedComponent, { registry: subRegistry, ...props }) });
3724      },
3725      "withRegistryProvider"
3726    );
3727    var with_registry_provider_default = withRegistryProvider;
3728  
3729    // packages/upload-media/build-module/components/provider/index.mjs
3730    var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
3731    var MediaUploadProvider = with_registry_provider_default((props) => {
3732      const { children, settings } = props;
3733      const { updateSettings: updateSettings2 } = unlock((0, import_data3.useDispatch)(store));
3734      (0, import_element2.useEffect)(() => {
3735        updateSettings2(settings);
3736      }, [settings, updateSettings2]);
3737      return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
3738    });
3739    var provider_default = MediaUploadProvider;
3740  
3741    // packages/upload-media/build-module/error-messages.mjs
3742    var import_i18n8 = __toESM(require_i18n(), 1);
3743    function getErrorMessage(code, fileName) {
3744      const messages = {
3745        [ErrorCode.EMPTY_FILE]: {
3746          title: (0, import_i18n8.__)("Empty file"),
3747          description: (0, import_i18n8.sprintf)(
3748            /* translators: %s: file name */
3749            (0, import_i18n8.__)('"%s" is empty.'),
3750            fileName
3751          ),
3752          action: (0, import_i18n8.__)("Please choose a different file.")
3753        },
3754        [ErrorCode.SIZE_ABOVE_LIMIT]: {
3755          title: (0, import_i18n8.__)("File too large"),
3756          description: (0, import_i18n8.sprintf)(
3757            /* translators: %s: file name */
3758            (0, import_i18n8.__)('"%s" exceeds the maximum upload size.'),
3759            fileName
3760          ),
3761          action: (0, import_i18n8.__)("Please reduce the file size and try again.")
3762        },
3763        [ErrorCode.MIME_TYPE_NOT_SUPPORTED]: {
3764          title: (0, import_i18n8.__)("Unsupported file type"),
3765          description: (0, import_i18n8.sprintf)(
3766            /* translators: %s: file name */
3767            (0, import_i18n8.__)('"%s" is not a supported file type.'),
3768            fileName
3769          ),
3770          action: (0, import_i18n8.__)("Please upload a different file format.")
3771        },
3772        [ErrorCode.MIME_TYPE_NOT_ALLOWED_FOR_USER]: {
3773          title: (0, import_i18n8.__)("File type not allowed"),
3774          description: (0, import_i18n8.sprintf)(
3775            /* translators: %s: file name */
3776            (0, import_i18n8.__)('You are not allowed to upload "%s".'),
3777            fileName
3778          ),
3779          action: (0, import_i18n8.__)("Please contact your site administrator.")
3780        },
3781        [ErrorCode.HEIC_DECODE_ERROR]: {
3782          title: (0, import_i18n8.__)("HEIC decode failed"),
3783          description: (0, import_i18n8.sprintf)(
3784            /* translators: %s: file name */
3785            (0, import_i18n8.__)('Failed to decode HEIC file "%s".'),
3786            fileName
3787          ),
3788          action: getHeicConversionAdvice()
3789        },
3790        [ErrorCode.IMAGE_TRANSCODING_ERROR]: {
3791          title: (0, import_i18n8.__)("Image processing failed"),
3792          description: (0, import_i18n8.sprintf)(
3793            /* translators: %s: file name */
3794            (0, import_i18n8.__)('Failed to process "%s".'),
3795            fileName
3796          ),
3797          action: (0, import_i18n8.__)("The image may be corrupted. Try a different file.")
3798        },
3799        [ErrorCode.IMAGE_ROTATION_ERROR]: {
3800          title: (0, import_i18n8.__)("Image rotation failed"),
3801          description: (0, import_i18n8.sprintf)(
3802            /* translators: %s: file name */
3803            (0, import_i18n8.__)('Failed to rotate "%s".'),
3804            fileName
3805          ),
3806          action: (0, import_i18n8.__)("The image may be corrupted. Try a different file.")
3807        },
3808        [ErrorCode.MEDIA_TRANSCODING_ERROR]: {
3809          title: (0, import_i18n8.__)("Media processing failed"),
3810          description: (0, import_i18n8.sprintf)(
3811            /* translators: %s: file name */
3812            (0, import_i18n8.__)('Failed to convert "%s" to the target format.'),
3813            fileName
3814          ),
3815          action: (0, import_i18n8.__)("The file may be corrupted. Try a different file.")
3816        },
3817        [ErrorCode.MEDIA_FINALIZE_ERROR]: {
3818          title: (0, import_i18n8.__)("Upload failed"),
3819          description: (0, import_i18n8.sprintf)(
3820            /* translators: %s: file name */
3821            (0, import_i18n8.__)('Could not finalize the upload of "%s".'),
3822            fileName
3823          ),
3824          action: (0, import_i18n8.__)("Please try again.")
3825        },
3826        [ErrorCode.GENERAL]: {
3827          title: (0, import_i18n8.__)("Upload failed"),
3828          description: (0, import_i18n8.sprintf)(
3829            /* translators: %s: file name */
3830            (0, import_i18n8.__)('Failed to upload "%s".'),
3831            fileName
3832          ),
3833          action: (0, import_i18n8.__)("Please try again.")
3834        }
3835      };
3836      return messages[code] || {
3837        title: (0, import_i18n8.__)("Upload failed"),
3838        description: (0, import_i18n8.sprintf)(
3839          /* translators: %s: file name */
3840          (0, import_i18n8.__)('Failed to upload "%s".'),
3841          fileName
3842        ),
3843        action: (0, import_i18n8.__)("Please try again.")
3844      };
3845    }
3846    return __toCommonJS(index_exports);
3847  })();
3848  (window.wp ||= {}).uploadMedia = wp.uploadMedia;
3849  })();


Generated : Mon Oct 12 08:20:33 2026 Cross-referenced by PHPXref