var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
import { e as editorDefaults, T as Transform, M as Matrix, u as uuid, t as transformMath, k as isGroup, j as templetUtils, l as loader, P as utils, v as createPromiseQueue, w as murmurHash2, Q as isAnimationImage, d as parseTransform$1, Y as BaseRender, x as createCanvas, O as ImageRenderer, B as newDrawImageToCanvas, I as autoStretchImage } from "./watermark.js";
import { $ as tinycolor, l as lodash, Z as lru, X as Promise$1 } from "./index.js";
function parseTransform(matrixData) {
  let transform = new Transform();
  if (matrixData) {
    if (matrixData.localTransform) {
      transform = lodash.exports.cloneDeep(matrixData);
    } else {
      const matrix = new Matrix();
      matrix.copy.call(matrixData, matrix);
      matrix.decompose(transform);
    }
  }
  return transform;
}
function hexaToRgba(val, defaultVal = null) {
  if (!val) {
    return defaultVal;
  }
  const color = tinycolor(val).toString("rgb");
  return color;
}
function useEffects(type, props, mergeDefault) {
  delete props.$linkIndex;
  if (props.imageEffects) {
    props.imageEffects.forEach((item) => {
      if (!item.enable)
        return;
      const { offset, stroke, shadow, expand, filling, mask } = item;
      if (lodash.exports.get(offset, "x", 0) === 0 && lodash.exports.get(offset, "y", 0) === 0 && lodash.exports.get(stroke, "enable") === false && lodash.exports.get(shadow, "enable") === false && lodash.exports.get(expand, "enable") === false && lodash.exports.get(filling, "enable") === false && lodash.exports.get(mask, "enable") === false) {
        item.filling.type = "base";
        item.filling.enable = true;
      }
    });
  }
  const isText = ["text", "effectText"].includes(type);
  const effects = isText ? props.textEffects : props.imageEffects;
  const validEffects = effects.filter((effect) => effect.enable !== false);
  if (mergeDefault) {
    effects.forEach((effect) => {
      const keys = ["enable", "excludeScale"].concat(Object.keys(effect));
      const defaultEffect = lodash.exports.cloneDeep(lodash.exports.pick(isText ? editorDefaults.textEffect : editorDefaults.imageEffect, keys));
      return lodash.exports.defaultsDeep(effect, defaultEffect);
    });
  }
  if (!props.aggregatedColors || !props.aggregatedColors.length) {
    const aggregatedColors = [];
    let isNeedAddSelfColor = !validEffects.length;
    validEffects.forEach((efA, i) => {
      if (efA.filling && efA.filling.enable)
        return;
      const isValid = !isText ? false : effects.some((efB, j) => {
        if (i <= j || !efB.filling || !efB.filling.enable)
          return false;
        const offsetA = efA.offset || { x: 0, y: 0 };
        const offsetB = efB.offset || { x: 0, y: 0 };
        return offsetA.x === offsetB.x && offsetA.y === offsetB.y && !lodash.exports.get(efA, "skew.enable") && !lodash.exports.get(efB, "skew.enable");
      });
      if (i === 0 || !isValid) {
        isNeedAddSelfColor = true;
      }
    });
    validEffects.forEach((effect) => {
      ["stroke", "filling", "shadow"].forEach((key) => {
        if (!effect[key])
          return;
        const typeValid = key === "filling" && effect[key].type !== 0 && effect[key].type !== "color";
        if (!effect[key].color || !effect[key].enable || typeValid) {
          return;
        }
        const color = aggregatedColors.find((color2) => {
          return tinycolor.equals(effect[key].color, color2);
        });
        if (!color) {
          aggregatedColors.push(effect[key].color);
        }
      });
    });
    if (props.color && (!isText || isNeedAddSelfColor) && !aggregatedColors.some((color) => tinycolor.equals(color, props.color))) {
      aggregatedColors.push(props.color);
    }
    props.aggregatedColors = aggregatedColors;
  }
  effects.forEach((effect) => {
    ["stroke", "filling", "shadow"].forEach((key) => {
      if (!effect[key])
        return;
      const typeValid = key === "filling" && effect[key].type !== 0 && effect[key].type !== "color";
      if (!effect[key].color || !effect[key].enable || typeValid) {
        return;
      }
      const linkIndex = lodash.exports.findIndex(props.aggregatedColors, (aggregatedColor) => {
        return tinycolor.equals(effect[key].color, aggregatedColor);
      });
      if (linkIndex > -1) {
        effect[key].$linkIndex = linkIndex;
      }
    });
  });
  if (type === "text" || type === "effectText") {
    const linkIndex = lodash.exports.findIndex(props.aggregatedColors, (aggregatedColor) => {
      return tinycolor.equals(props.color, aggregatedColor);
    });
    if (linkIndex > -1) {
      props.$linkIndex = linkIndex;
    }
  }
  if (props.backgroundColor && tinycolor(props.backgroundColor).getAlpha() !== 0) {
    const linkIndex = lodash.exports.findIndex(props.aggregatedColors, (aggregatedColor) => {
      return tinycolor.equals(props.backgroundColor, aggregatedColor);
    });
    if (linkIndex > -1) {
      props.$backgroundColorLinkIndex = linkIndex;
    } else {
      props.$backgroundColorLinkIndex = props.aggregatedColors.length;
      props.aggregatedColors.push(props.backgroundColor);
    }
  } else {
    delete props.$backgroundColorLinkIndex;
  }
  props.aggregatedColors = props.aggregatedColors.map((color) => tinycolor(color).toString("rgb"));
}
function getEffectedTextEffects(model) {
  let result = model.textEffects.filter((effect) => {
    return effect.enable !== false;
  });
  result = result.reduce((newResult, effect) => {
    const valid = effect.enable !== false && effect.stroke && effect.stroke.enable !== false && effect.stroke.type === "outer";
    effect = lodash.exports.cloneDeep(effect);
    if (!valid) {
      newResult.push(effect);
    } else {
      const nextEffect = lodash.exports.merge({}, effect, {
        stroke: {
          enable: true,
          type: "center",
          color: effect.stroke.color,
          width: effect.stroke.width * 2
        }
      });
      if (effect.stroke)
        effect.stroke.enable = false;
      if (effect.shadow)
        effect.shadow.enable = false;
      newResult.push(effect);
      newResult.push(nextEffect);
    }
    return newResult;
  }, []);
  result.reverse();
  return result;
}
function getAdaptationImageTransform(model) {
  const {
    naturalWidth,
    naturalHeight,
    $imageWidth,
    $imageHeight,
    $imageLeft,
    $imageTop,
    imageTransform,
    width,
    height
  } = model;
  const newImageTransform = model.parseTransform(imageTransform);
  const { position, scale } = newImageTransform;
  scale.x = $imageWidth / naturalWidth;
  scale.y = $imageHeight / naturalHeight;
  position.x = $imageLeft + $imageWidth / 2 - width / 2;
  position.y = $imageTop + $imageHeight / 2 - height / 2;
  return newImageTransform;
}
function adaptationImageTransform(model, img) {
  var _a;
  let {
    $imageWidth,
    $imageHeight,
    $imageLeft,
    $imageTop,
    background,
    imageTransform,
    width,
    height
  } = model;
  const flipX = imageTransform.scale.x < 0 ? -1 : 1;
  const flipY = imageTransform.scale.y < 0 ? -1 : 1;
  imageTransform = imageTransform || ((_a = background == null ? void 0 : background.image) == null ? void 0 : _a.imageTransform);
  imageTransform.scale.x = $imageWidth / img.naturalWidth * flipX;
  imageTransform.scale.y = $imageHeight / img.naturalHeight * flipY;
  imageTransform.position.x = $imageLeft + $imageWidth / 2 - width / 2;
  imageTransform.position.y = $imageTop + $imageHeight / 2 - height / 2;
  imageTransform.updateLocalTransform();
}
class ElementModel {
  constructor(data) {
    const type = data && data.type;
    if (!type) {
      throw new Error("No type to create model: " + type);
    }
    lodash.exports.merge(this, editorDefaults.element, editorDefaults.elementExts, editorDefaults[type + "Element"], data);
    if (this.backgroundEffect && this.backgroundEffect.image) {
      this.backgroundEffect.image.transform = this.parseTransform(this.backgroundEffect.image.transform);
    }
    if (this.backgroundColor) {
      this.backgroundColor = hexaToRgba(this.backgroundColor);
    }
    if (this.border) {
      this.border.color = hexaToRgba(this.border.color);
    }
    this.transform = this.parseTransform(data.transform);
    if (this.boxShadow) {
      const shadow = this.boxShadow;
      shadow.color = hexaToRgba(shadow.color);
    }
    this.width = Number(this.width);
    this.height = Number(this.height);
    this.left = Number(this.left);
    this.top = Number(this.top);
    if (this.linkId === 0 || this.linkId === "0") {
      this.linkId = "";
    }
    if (typeof this.category === "object") {
      this.category = "";
    }
    if (!this.$id) {
      this.$id = uuid();
    }
    if (!this.uuid) {
      this.uuid = uuid();
    }
  }
  get rotation() {
    return this.transform.rotation;
  }
  set rotation(rotation) {
    this.transform.rotation = rotation;
  }
  get rotate() {
    return transformMath.radToDeg(this.rotation);
  }
  set rotate(deg) {
    this.transform.rotation = transformMath.degToRad(deg);
  }
  get scaleX() {
    return this.transform.scale.x;
  }
  set scaleX(v) {
    this.transform.scale.x = v;
  }
  get scaleY() {
    return this.transform.scale.y;
  }
  set scaleY(v) {
    this.transform.scale.y = v;
  }
  get skewX() {
    return this.transform.skew.x;
  }
  set skewX(v) {
    this.transform.skew.x = v;
  }
  get skewY() {
    return this.transform.skew.y;
  }
  set skewY(v) {
    this.transform.skew.y = v;
  }
  parseTransform(matrixData) {
    return parseTransform(matrixData);
  }
  reset() {
    const id = this.$id;
    const parentId = this.$parentId;
    const cacheParentId = this.$cacheParentId;
    const tempGroupId = this.$tempGroupId;
    const renderId = this.$renderId;
    const extProps = lodash.exports.cloneDeep(editorDefaults.elementExts);
    lodash.exports.merge(this, extProps);
    this.$id = id;
    this.$parentId = parentId;
    this.$cacheParentId = cacheParentId;
    this.$tempGroupId = tempGroupId;
    this.$renderId = renderId;
  }
  enableEditable() {
    this.rotatable = true;
    this.dragable = true;
  }
  disableEditable() {
    this.rotatable = false;
    this.dragable = false;
  }
  toString() {
    return JSON.stringify(this);
  }
  clone(keepProps = ["$renderId"]) {
    keepProps = keepProps || [];
    const keepPropsMap = keepProps.reduce((obj, name) => {
      obj[name] = true;
      return obj;
    }, {});
    const cloneElement = (element) => {
      if (isGroup(element)) {
        element.elements = element.elements.map((el) => {
          return cloneElement(Object.assign({}, el));
        });
      }
      return Object.keys(element).reduce((elem, key) => {
        if (!key.startsWith("$") || keepPropsMap[key]) {
          elem[key] = lodash.exports.cloneDeep(element[key]);
        }
        return elem;
      }, {});
    };
    return cloneElement(Object.assign({}, this));
  }
}
const MAX_LENGTH = 500;
const rControl = /[\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000b\u000c\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f\u007F]/gm;
const rEmoji = /([\uE000-\uF8FF]|\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDDFF])/g;
const rBreakLine = /<br>|\r|\n/g;
const listStyleMap = {
  decimal: "0123456789.",
  "upper-alpha": "ABCDEFGHIJKLMNOPQRSTUVWXYZ.",
  "lower-alpha": "abcdefghijklmnopqrstuvwxyz.",
  "cjk-ideographic": "\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341\u3001",
  "decimal-leading-zero": "0123456789."
};
function getFontsSubset(layouts, options) {
  const { supportTypes = ["text"] } = options.fontSubset || {};
  const fontsContent = {};
  const textElements = [];
  templetUtils.walkTemplet((element) => {
    const hasContent = element.contents && element.contents.length || element.content;
    if (supportTypes.indexOf(element.type) !== -1 && hasContent) {
      textElements.push(element);
    }
  }, true, layouts);
  textElements.forEach((element) => {
    let { contents, content, fontFamily } = element;
    contents = contents && contents.length > 0 ? contents : [{ content }];
    contents.forEach((item) => {
      const defFont = options.fontsMap[fontFamily];
      const font = options.fontsMap[item.fontFamily] || defFont;
      if (!font)
        return;
      if (!fontsContent[font.name]) {
        fontsContent[font.name] = options.fontSubset.defaultContent || "";
      }
      fontsContent[font.name] += item.content;
      if (!defFont || !listStyleMap[element.listStyle])
        return;
      if (!fontsContent[defFont.name]) {
        fontsContent[defFont.name] = "";
      }
      fontsContent[defFont.name] += listStyleMap[element.listStyle];
    });
  });
  Object.keys(fontsContent).forEach((key) => {
    fontsContent[key] = lodash.exports.unescape(fontsContent[key]);
    fontsContent[key] = new Set(fontsContent[key]);
    fontsContent[key] = Array.from(fontsContent[key]);
    fontsContent[key] = fontsContent[key].sort().join("");
    fontsContent[key] = fontsContent[key].replace(rBreakLine, "").replace(rEmoji, "").replace(rControl, "");
  });
  return fontsContent;
}
function getUpdateFontsSubset(layouts, options) {
  const fontsContent = getFontsSubset(layouts, options);
  const result = {};
  const arr = Object.keys(fontsContent).filter((key) => {
    const font = options.fontsMap[key];
    const content = fontsContent[key];
    const cacheContent = options.fontSubsetsMap[font.name] && options.fontSubsetsMap[font.name].subsetContent;
    if (!cacheContent) {
      result[key] = content;
      return true;
    }
    for (let i = 0; i < content.length; i++) {
      const str = content.charAt(i);
      if (cacheContent.indexOf(str) === -1) {
        result[key] = fontsContent[key];
        return true;
      }
    }
    return false;
  });
  return arr.length ? result : null;
}
function loadFontsSubset(layouts, options) {
  const fontData = getUpdateFontsSubset(layouts, options);
  if (fontData && options.fontSubset.getUrl) {
    Object.keys(fontData).forEach((key) => {
      const font = options.fontsMap[key];
      const fontSubset = options.fontSubsetsMap[font.name];
      if (fontData[key] && fontData[key].length < MAX_LENGTH) {
        options.fontSubsetsMap[font.name] = {
          loadType: fontSubset ? fontSubset.loadType : "subset",
          subsetContent: fontData[key],
          subsetPromise: options.fontSubset.getUrl(font, fontData[key])
        };
      } else {
        delete options.fontSubsetsMap[font.name];
      }
    });
  }
}
const fontCaches = new lru.LRUMap(10);
function loadImage(url) {
  return new Promise$1(function(resolve, reject) {
    const img = new Image();
    img.onload = function() {
      URL.revokeObjectURL(url);
      resolve(img);
    };
    img.onerror = () => {
      reject(new Error("svg \u56FE\u7247\u52A0\u8F7D\u5931\u8D25\uFF0C\u5B58\u5728\u975E\u6CD5\u5B57\u7B26"));
    };
    img.src = url;
  });
}
function featchFont(font, url) {
  url = url || font.woff || font.ttf;
  if (!url)
    return Promise$1.resolve(font);
  return fetch(url, {
    method: "get",
    responseType: "blob"
  }).then((res) => {
    return res.blob();
  }).then((blob) => {
    if (window.safari && blob.size >= 10 * 1024 * 1024) {
      throw new Error("\u5B57\u4F53\u5927\u4E8E10M\uFF0Csafari\u65E0\u6CD5\u8D70\u6D4F\u89C8\u5668\u7F13\u5B58");
    }
    return new Promise$1(function(resolve) {
      const f = new FileReader();
      f.onload = function() {
        resolve(f.result);
      };
      f.readAsDataURL(blob);
    });
  }).then(function(dataURL) {
    return __spreadProps(__spreadValues({}, font), {
      dataURL
    });
  });
}
function loadFont(font) {
  if (!fontCaches.get(font.name)) {
    const promise = loader.loadFont(font).then(() => {
      return featchFont(font);
    }).catch(() => {
      return featchFont(font);
    });
    fontCaches.set(font.name, promise);
  }
  return fontCaches.get(font.name);
}
function loadFonts(fonts, editor) {
  const exportEnableCallback = editor.options.fontSubset.exportEnableCallback;
  const exportEnable = exportEnableCallback && exportEnableCallback(editor);
  if (exportEnable) {
    loadFontsSubset(editor.layouts, editor.options);
  }
  const needUpdateSubsetsData = getUpdateFontsSubset(editor.layouts, editor.options);
  console.log("exportEnable:" + exportEnable);
  return Promise$1.map(fonts, (font) => {
    const subsetValid = !needUpdateSubsetsData || !needUpdateSubsetsData[font.name] && !needUpdateSubsetsData[font.family];
    if (subsetValid) {
      const fontSubset = editor.options.fontSubsetsMap[font.name];
      return fontSubset ? fontSubset.subsetPromise.then((url) => {
        const subsetName = font.name + editor.options.subsetSuffix;
        const fontFace = loader._documentFonts && loader._documentFonts[subsetName];
        if (fontFace && fontFace.status === "error") {
          throw new Error("font file parse error");
        }
        return featchFont(font, url);
      }).catch((e) => {
        console.warn(e);
        return loadFont(font);
      }) : loadFont(font);
    } else {
      return loadFont(font);
    }
  });
}
const isEdge = window.navigator.userAgent.indexOf("Edge") > -1;
class TableRenderer {
  constructor(model, html, editor) {
    this._model = model;
    this._html = html;
    this.editor = editor;
  }
  createStyle() {
    return `<style>
            * {
                box-sizing: border-box;
                margin: 0;
                padding: 0;
            }
            .editor-element-table {
                position: relative;
                width: ${this._model.width} + 'px';
                height: ${this._model.height} + 'px';
                left: 0 !important;
                top: 0 !important;
                transform: none !important;
            }

            .editor-element .element-main {
                height: 100%;
                width: 100%;
                position: absolute;
                left: 0;
                top: 0;
            }

            .editor-element {
                background: no-repeat 50% 50%;
                line-height: 1;
                position: absolute;
                z-index: 1;
                text-align: left;
            }

            .grid-base-cell {
                position: relative;
                display: flex;
                justify-content: center;
                align-items: center;
                overflow: hidden;
                width: 100%;
                height: 100%;
                margin: 0;
                background-clip: content-box;
                border: none;
            }
            
            .editor-element-table .element-inner {
                position: relative;
                width: 100%;
                height: 100%;
                transform-origin: 0 0;
                transform: none !important
            }
            .editor-table {
                width: 100%;
                height: 100%;
                position: relative;
            }
            .grid-core {
                position: relative;
                box-sizing: border-box;
                overflow: hidden;
                width: 100%;
                height: 100%;
                border-collapse: collapse;
            }
            
            .grid-core__cell {
                padding: 0;
                margin: 0;
                border: none;
            }
            
            .grid-core__cell--checkbox {
                width: 200px;
            }
            
            .grid-core__cell--checkbox-header {
                width: 300px;
            }
            .grid-checkbox {
                overflow: hidden;
                width: 100%;
                height: 100%;
                border: none;
                display: flex;
                justify-content: center;
                align-items: center;
            }
            
            .grid-checkbox__content {
                position: relative;
                border-color: transparent;
            }
            
            .grid-checkbox__content::after {
                content: " ";
                position: absolute;
                width: 100%;
                top: 130%;
                left: 0;
                border-bottom: 2px solid transparent;
                border-color: inherit;
            }

            .fill-checkbox {
                display: flex;
                justify-content: center;
                align-items: center;
                overflow: hidden;
                width: 100%;
                height: 100%;
                border: none;
            }
            
            .fill-checkbox__content {
                position: relative;
                display: flex;
                justify-content: center;
                align-items: center;
                width: 100%;
                height: 32px;
                border: none;
            }
            .fill-checkbox__content--start {
                border-radius: 16px 0 0 16px;
            }
            .fill-checkbox__content--end {
                border-radius: 0 16px 16px 0;
            }
            .gradient-checkbox {
                display: flex;
                justify-content: center;
                align-items: center;
                overflow: hidden;
                width: 100%;
                height: 100%;
                border: none;
            }
            
            .gradient-checkbox__content {
                position: relative;
                width: 100%;
                height: 8px;
                text-align: center;
            }
            .grid-container {
                position: relative;
                overflow: hidden;
                width: 100%;
                height: 100%;
                font-size: 22px;
                font-weight: 400;
                background: none;
            }
            .gradient-checkbox__content--start {
                border-radius: 4px 0 0 4px;
            }
            .gradient-checkbox__content--end {
                border-radius: 0 4px 4px 0;
            }
        
            .gradient-checkbox__hide {
                opacity: 0;
            }
        
            .gradient-checkbox__text {
                display: block;
                position: absolute;
                top: 200%;
                left: 0;
                width: 100%;
                font-size: 18px;
            }
        
            .gradient-checkbox__sliding {
                position: absolute;
                top: 50%;
                left: 50%;
                width: 60%;
                height: 180%;
                transform: translate(-50%, -50%);
                border: 1px solid #000;
                background: #fff;
                border-radius: 50px;
            }
        </style>`;
  }
  renderImage() {
    const fonts = this.editor.options.fontList.filter((font2) => font2.name === this._model.fontFamily);
    const font = fonts && fonts.length && fonts[0] || this.editor.options.fontList[0];
    return loadFont(font).then((font2) => this.createSvg([font2]));
  }
  createSvg(fonts) {
    let { width, height } = this._model;
    width = Math.round(width);
    height = Math.round(height);
    let styleHtml = "";
    fonts.forEach((font) => {
      if (font.dataURL) {
        styleHtml += `@font-face {font-family: "${font.name}";src: url(${font.dataURL}) format('woff');font-display: swap;font-weight: ${font.weight}}`;
      }
    });
    const svgString = `<svg viewBox="0 0 ${width} ${height}" width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">${this.createStyle()}<style>${styleHtml}</style><foreignObject x="0" y="0" width="${width}" height="${height}"><div xmlns="http://www.w3.org/1999/xhtml" style="width:${width}px; height:${height}px; position: relative">${this._html}</div></foreignObject></svg>`;
    let url;
    if (!isEdge) {
      url = "data:image/svg+xml;charset=utf8," + encodeURIComponent(svgString);
    } else {
      const blob = new Blob([svgString], { type: "image/svg+xml" });
      url = URL.createObjectURL(blob);
    }
    return loadImage(url).delay(window.safari ? 1500 : 500).then((img) => {
      return img;
    });
  }
  renderCanvas() {
    return this.renderImage().then((img) => {
      const element = this._model;
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");
      canvas.width = element.width;
      canvas.height = element.height;
      ctx.drawImage(img, 0, 0, element.width, element.height);
      return canvas;
    });
  }
}
const queue = createPromiseQueue({
  timeout: 1e4
});
const editorResourceMap = {
  data: /* @__PURE__ */ new Map(),
  longData: new lru.LRUMap(15),
  get(key) {
    return editorResourceMap.data.get(key) || editorResourceMap.longData.get(key);
  },
  set(key, val) {
    if (!key)
      return;
    let data = editorResourceMap.data;
    if (lodash.exports.isString(key) && key.length > 100) {
      data = editorResourceMap.longData;
    } else {
      queue.run(val, () => {
        return utils.loadImage(val);
      });
    }
    data.set(key, val);
  }
};
const urlToBlob = (element, mapKeys) => {
  const resource = {};
  const promises = [];
  mapKeys.forEach((key) => {
    const url = lodash.exports.get(element, key);
    const isBase64 = url && url.includes(";base64");
    const isBlob = url && url.includes("blob:");
    if (editorResourceMap.get(url)) {
      resource[key] = editorResourceMap.get(url);
    } else if (isBase64) {
      resource[key] = utils.dataurlToBlob(url);
    } else if (isBlob) {
      promises.push(utils.bloburlToBlob(url).then((blob) => {
        resource[key] = blob;
      }));
    }
  });
  return Promise.all(promises).then(() => resource);
};
const canvasToBlob = (canvas, resource) => {
  return new Promise((resolve) => {
    canvas.toBlob((blob) => {
      resolve(blob);
    }, "image/png");
  }).then((blob) => {
    resource.imageUrl = blob;
    return resource;
  });
};
const getComponentById = function(editor, id) {
  let component = editor.getComponentById(id);
  if (!component) {
    const el = document.querySelector(`.editor-element[data-id="${id}"]`);
    component = el && el.__vue__;
  }
  return component;
};
const checkLoaded = function checkLoaded2(ele, callback) {
  const awaitTime = 200;
  setTimeout(() => {
    if (ele.$loaded) {
      callback();
    } else {
      checkLoaded2(ele, callback);
    }
  }, awaitTime);
};
const hashIgnoreProps = lodash.exports.omit(Object.assign({}, editorDefaults.element, { imageUrl: true }), [
  "padding",
  "width",
  "height",
  "transform",
  "title"
]);
const hashIgnoreTypes = [
  "mask",
  "image",
  "group",
  "text",
  "flex",
  "svg",
  "watermark",
  "ninePatch"
].reduce((obj, k) => {
  obj[k] = true;
  return obj;
}, {});
const getElementHash = function(element) {
  if (!element.imageUrl || hashIgnoreTypes[element.type])
    return;
  const props = lodash.exports.omitBy(element, (v, k) => {
    return k[0] === "$" || hashIgnoreProps[k] !== void 0;
  });
  const hash = murmurHash2(JSON.stringify(props));
  return hash;
};
const getImageUrlByHash = function(hash) {
  hash = lodash.exports.isObject(hash) && hash.type ? getElementHash(hash) : hash;
  return hash && editorResourceMap.get(hash);
};
const setImageUrlByHash = function(hash, imageUrl) {
  hash = lodash.exports.isObject(hash) && hash.type ? getElementHash(hash) : hash;
  return hash && editorResourceMap.set(hash, imageUrl);
};
class ImageBaseModel extends ElementModel {
  constructor(data, options = {}) {
    super(data);
    this.imageTransform = this.parseTransform(this.imageTransform);
    this.imageEffects && useEffects("image", this, true);
    const hasEffects = this.hasEffects;
    const hasFilters = this.hasFilters;
    if (!data.effectedResult && hasEffects) {
      this.imageUrl = "";
    }
    if (data.isGif) {
      this.resourceType = "gif";
    }
    if (typeof data.loop === "boolean") {
      this.loop = data.loop ? 0 : 1;
    }
    this.filterInfo = data.filterInfo || {
      id: -1,
      url: "",
      strong: 0.8,
      intensity: 0.8
    };
    if (!hasEffects && this.effectedResult) {
      this.effectedResult.width = 0;
      this.effectedResult.height = 0;
      this.effectedResult.left = 0;
      this.effectedResult.top = 0;
    }
    if (!hasEffects && !hasFilters) {
      this.effectedImage = "";
    } else if (this.effectedImage) {
      this.imageUrl = this.effectedImage;
    }
    if (!data.naturalWidth) {
      this.naturalWidth = data.imageWidth || data.width;
      this.naturalHeight = data.imageHeight || data.height;
      this.$imageLeft = this.imageTransform.position.x;
      this.$imageTop = this.imageTransform.position.y;
    } else {
      this.naturalWidth = data.naturalWidth;
      this.naturalHeight = data.naturalHeight;
    }
    if (this.imageUrl && !this.$renderId) {
      this.$renderId = this.$id;
    }
    if (this.imageUrl && this.imageUrl.startsWith("data:image")) {
      this.imageUrl = "";
    }
    if (editorResourceMap.get(this.$renderId)) {
      this.imageUrl = editorResourceMap.get(this.$renderId);
    } else if (this.imageUrl) {
      editorResourceMap.set(this.$renderId, this.imageUrl);
    }
    this.url = editorResourceMap.get(this.url) || this.url;
    this.setSizeBeforeEffectRendered(options);
    if (!this.$clipCache) {
      this.setClipCache();
    }
    delete this.effectedImage;
    delete this.effectedImageWidth;
    delete this.effectedImageHeight;
    delete this.effectedImageOffsetLeft;
    delete this.effectedImageOffsetTop;
    delete this.imageWidth;
    delete this.imageHeight;
    delete this.originWidth;
    delete this.originHeight;
    delete this.clip;
  }
  setSizeBeforeEffectRendered() {
    this.$beforeEffectRenderedWidth = this.width;
    this.$beforeEffectRenderedHeight = this.height;
  }
  setClipCache() {
    this.$clipCache = {
      offsetX: this.imageTransform.position.x,
      offsetY: this.imageTransform.position.y,
      scaleX: this.imageTransform.scale.x,
      scaleY: this.imageTransform.scale.y,
      width: this.width,
      height: this.height
    };
  }
  set imageWidth(v) {
    if (!this.$id)
      return;
    this.$imageWidth = v;
    console.error(new Error("imageWidth \u5B57\u6BB5\u5DF2\u5E9F\u5F03, \u9700\u7528 imageTransform.scaleX * naturalWidth \u5B9E\u73B0"));
  }
  set imageHeight(v) {
    if (!this.$id)
      return;
    this.$imageHeight = v;
    console.error(new Error("imageHeight \u5B57\u6BB5\u5DF2\u5E9F\u5F03, \u9700\u7528 imageTransform.scaleY * naturalHeight \u5B9E\u73B0"));
  }
  get $imageWidth() {
    return Math.abs(this.naturalWidth * this.imageTransform.scale.x);
  }
  set $imageWidth(v) {
    if (!this.$id || !this.imageTransform.scale)
      return;
    const baseNum = this.imageTransform.scale.x < 0 ? -1 : 1;
    this.imageTransform.scale.x = v / this.naturalWidth * baseNum;
  }
  get $imageHeight() {
    return Math.abs(this.naturalHeight * this.imageTransform.scale.y);
  }
  set $imageHeight(v) {
    if (!this.$id || !this.imageTransform.scale)
      return;
    const baseNum = this.imageTransform.scale.y < 0 ? -1 : 1;
    this.imageTransform.scale.y = v / this.naturalHeight * baseNum;
  }
  get $imageLeft() {
    const {
      imageTransform: { position },
      $imageWidth,
      width
    } = this;
    return width / 2 - $imageWidth / 2 + position.x;
  }
  set $imageLeft(v) {
    if (!this.$id || !this.imageTransform.scale)
      return;
    this.imageTransform.position.x = v + this.$imageWidth / 2 - this.width / 2;
  }
  get $imageTop() {
    const {
      imageTransform: { position },
      $imageHeight,
      height
    } = this;
    return height / 2 - $imageHeight / 2 + position.y;
  }
  set $imageTop(v) {
    if (!this.$id || !this.imageTransform.scale)
      return;
    this.imageTransform.position.y = v + this.$imageHeight / 2 - this.height / 2;
  }
  get hasComplexFilters() {
    const { filterInfo } = this;
    return filterInfo && (filterInfo.url || filterInfo.prunedZipUrl);
  }
  get hasBaseFilters() {
    const { filter } = this;
    const defaultFilter = editorDefaults.element.filter;
    if (!filter)
      return false;
    return Object.keys(filter).some((key) => filter[key] !== defaultFilter[key]);
  }
  get hasFilters() {
    return this.hasBaseFilters || this.hasComplexFilters;
  }
  get hasEffects() {
    return !!(this.imageEffects || []).find((item) => item.enable);
  }
  get isGif() {
    return this.resourceType === "gif";
  }
  get isApng() {
    return this.resourceType === "apng";
  }
  get isVideo() {
    return this.resourceType === "video" || this.resourceType === "mp4";
  }
  get $renderProps() {
    return [
      this.width,
      this.height,
      this.opacity,
      this.maskInfo.enable,
      this.imageTransform,
      this.imageEffects
    ];
  }
}
class ImageModel extends ImageBaseModel {
  constructor(data, options) {
    const { clip } = data;
    if (clip && !data.imageTransform) {
      data.imageWidth = clip.left + clip.right + data.width;
      data.imageHeight = clip.top + clip.bottom + data.height;
      const imageTransform = data.imageTransform;
      if (!imageTransform) {
        data.imageTransform = { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 };
      }
      data.imageTransform.tx = -clip.left;
      data.imageTransform.ty = -clip.top;
    }
    super(data, options);
    if (!this.hasEffects && !this.hasFilters) {
      this.imageUrl = "";
    }
    delete this.mask;
    if (isAnimationImage(data)) {
      this.imageUrl = data.imageUrl || "";
      this.enableDragToMask = false;
    }
  }
}
const layoutDefault = lodash.exports.omit(editorDefaults.layout, [
  "backgroundColor",
  "backgroundImage",
  "backgroundImageInfo",
  "backgroundGradient",
  "backgroundWatermarkEnable"
]);
function converPropsBackground(props, background) {
  if (!(props.backgroundColor || props.backgroundImage || props.backgroundImageInfo || props.backgroundGradient || props.backgroundWatermarkEnable) || props.background) {
    return props;
  }
  props = __spreadValues({}, props);
  if (props.backgroundColor !== void 0) {
    lodash.exports.set(props, "background.color", props.backgroundColor);
    delete props.backgroundColor;
  }
  if (props.backgroundImage !== void 0) {
    lodash.exports.set(props, "background.image.url", props.backgroundImage);
    delete props.backgroundImage;
  }
  if (props.backgroundImageInfo !== void 0) {
    lodash.exports.set(props, "background.image.naturalWidth", props.backgroundImageInfo.width);
    lodash.exports.set(props, "background.image.naturalHeight", props.backgroundImageInfo.height);
    lodash.exports.set(props, "background.image.imageTransform", props.backgroundImageInfo.transform);
    lodash.exports.set(props, "background.image.opacity", props.backgroundImageInfo.opacity);
    delete props.backgroundImageInfo;
  }
  if (props.backgroundGradient !== void 0) {
    lodash.exports.set(props, "background.gradient", props.backgroundGradient);
    delete props.backgroundGradient;
  }
  if (props.backgroundWatermarkEnable !== void 0) {
    lodash.exports.set(props, "background.watermarkEnable", props.backgroundWatermarkEnable);
    delete props.backgroundWatermarkEnable;
  }
  if (props.background) {
    background = lodash.exports.merge({}, background, props.background);
    props.background = background;
  }
  return props;
}
function convertModelBackground(model) {
  var _a, _b, _c;
  if (((_a = model.background) == null ? void 0 : _a.image) || ((_b = model.background) == null ? void 0 : _b.gradient))
    return model;
  const image = model.backgroundImageInfo && __spreadProps(__spreadValues({}, model.backgroundImageInfo), {
    url: model.backgroundImage,
    width: model.width,
    height: model.height,
    left: 0,
    top: 0,
    naturalWidth: model.backgroundImageInfo.width,
    naturalHeight: model.backgroundImageInfo.height,
    imageTransform: model.backgroundImageInfo.transform,
    transform: { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 },
    repeat: model.backgroundRepeat,
    opacity: lodash.exports.get(model, "backgroundImageInfo.opacity", 1),
    filterInfo: model.filterInfo || null,
    filter: model.filter || null
  });
  const background = {
    color: ((_c = model.background) == null ? void 0 : _c.color) || model.backgroundColor
  };
  if (model.backgroundGradient) {
    background.gradient = model.backgroundGradient;
  }
  if (image) {
    background.image = image;
  }
  background.watermarkEnable = !!model.backgroundWatermarkEnable;
  model.background = lodash.exports.cloneDeep(background);
  delete model.backgroundEffect;
  delete model.backgroundRepeat;
  delete model.backgroundImageInfo;
  delete model.filter;
  delete model.filterInfo;
  delete model.backgroundWatermarkEnable;
  delete model.backgroundImage;
  return model;
}
const resetLayoutProps = (layout) => {
  var _a, _b, _c, _d;
  convertModelBackground(layout);
  if (lodash.exports.get(layout, "background.image")) {
    const image = layout.background.image;
    if (!image.width)
      lodash.exports.set(image, "width", layout.width);
    if (!image.height)
      lodash.exports.set(image, "height", layout.height);
    !((_a = image.imageTransform) == null ? void 0 : _a.localTransform) && lodash.exports.set(layout, "background.image.imageTransform", parseTransform$1(image.imageTransform));
    !((_b = image.transform) == null ? void 0 : _b.localTransform) && lodash.exports.set(layout, "background.image.transform", parseTransform$1(image.transform));
  } else {
    lodash.exports.set(layout, "backgroundImageInfo.transform", parseTransform$1(lodash.exports.get(layout, "backgroundImageInfo.transform")));
  }
  const defaultLayout = Object.assign(lodash.exports.cloneDeep(layoutDefault), {
    border: __spreadValues({}, editorDefaults.border)
  });
  Object.keys(defaultLayout).forEach((key) => {
    const layoutValue = layout[key];
    if (lodash.exports.isUndefined(layoutValue) || lodash.exports.isNull(layoutValue)) {
      layout[key] = defaultLayout[key];
    }
  });
  lodash.exports.set(layout, "background.color", hexaToRgba(lodash.exports.get(layout, "background.color", "rgba(0,0,0,0)")));
  if (((_c = layout.background) == null ? void 0 : _c.image) && !layout.background.image.url && !((_d = layout.background.image.elementRefIds) == null ? void 0 : _d.length)) {
    layout.background.image = null;
  }
  return layout;
};
class LayoutModel {
  constructor(data, editor) {
    const newData = resetLayoutProps(__spreadValues({}, data));
    lodash.exports.merge(this, layoutDefault, { border: __spreadValues({}, editorDefaults.border) }, newData);
    this.top = 0;
    const elements = this.elements || this.elems || [];
    if (elements && elements.length && editor) {
      this.elements = elements.map((element) => {
        return editor.addElement(element, this, false);
      });
    } else {
      this.elements = [];
    }
    if (this.mosaic && this.mosaic.paths && editor) {
      this.mosaic.paths = this.mosaic.paths.map((path) => editor.createElement(path));
    }
    if (this.borderType) {
      this.border = Object.assign(this.border, {
        type: this.borderType,
        width: this.borderWidth,
        image: this.borderImage,
        imageSlice: this.borderImageSlice,
        opacity: this.borderOpacity,
        imageRepeat: this.borderImageRepeat
      });
    }
    lodash.exports.get(this, "background.gradient.stops", []).forEach((stopPoint) => {
      stopPoint.color = hexaToRgba(stopPoint.color);
    });
    if (this.border) {
      this.border.color = hexaToRgba(this.border.color);
      this.border.gradient && this.border.gradient.stops && this.border.gradient.stops.forEach((stopPoint) => {
        stopPoint.color = hexaToRgba(stopPoint.color);
      });
      if (this.border.type === "image" && !this.border.image) {
        this.border.enable = false;
      }
    }
    if (this.backgroundMask) {
      this.backgroundMask.color = hexaToRgba(this.backgroundMask.color);
    }
    if (this.mosaic) {
      this.mosaic.color = hexaToRgba(this.mosaic.color);
    }
    if (!this.$id) {
      this.$id = uuid();
    }
    if (!this.uuid) {
      this.uuid = uuid();
    }
    if (data.backgroundSize && this.$backgroundImageInfo) {
      this.$imageWidth = data.backgroundSize[0];
      this.$imageHeight = data.backgroundSize[1];
      this.$imageLeft = this.$backgroundImageInfo.imageTransform.position.x;
      this.$imageTop = this.$backgroundImageInfo.imageTransform.position.y;
    }
    if (this.background.image && /data:image\/gif|\.gif/i.test(this.background.image.url)) {
      lodash.exports.set(this, "background.image.resourceType", "gif");
    }
    delete this.backgroundSize;
    delete this.elems;
    delete this.backgroundPosition;
    delete this.borderType;
    delete this.borderWidth;
    delete this.borderImage;
    delete this.borderImageSlice;
    delete this.borderOpacity;
    delete this.borderColor;
    delete this.borderGradient;
    delete this.borderShadow;
  }
  exportData() {
    const mosaic = this.mosaic;
    const cloneLayout = __spreadValues({}, this);
    if (lodash.exports.isEqual(mosaic, layoutDefault.mosaic)) {
      cloneLayout.mosaic = null;
    } else {
      const paths = mosaic.paths.map((path) => {
        const cloneTransform = path.parseTransform(path.transform);
        cloneTransform.position.x = path.left;
        cloneTransform.position.y = path.top;
        const newPath = lodash.exports.pick(path, ["path", "type"]);
        newPath.transform = cloneTransform;
        if (path.type === "mosaicBrush") {
          newPath.strokeWidth = path.strokeWidth;
        }
        return newPath;
      });
      cloneLayout.mosaic = __spreadProps(__spreadValues({}, mosaic), {
        paths
      });
    }
    if (lodash.exports.isEqual(lodash.exports.omit(cloneLayout.border, ["$loaded"]), lodash.exports.omit(editorDefaults.border, ["$loaded"]))) {
      cloneLayout.border = null;
    }
    if (cloneLayout.background) {
      const image = cloneLayout.background.image;
      cloneLayout.backgroundColor = cloneLayout.background.color;
      if (image) {
        cloneLayout.backgroundImage = image.url;
        cloneLayout.backgroundImageInfo = {
          transform: image.imageTransform,
          width: image.naturalWidth,
          height: image.naturalHeight,
          opacity: image.opacity
        };
      }
      cloneLayout.backgroundGradient = cloneLayout.background.gradient;
      cloneLayout.backgroundWatermarkEnable = !!cloneLayout.background.watermarkEnable;
    }
    return cloneLayout;
  }
  get $backgroundImageInfo() {
    return lodash.exports.get(this.background, "image");
  }
  get $backgroundImage() {
    return lodash.exports.get(this.background, "image.url");
  }
  get $imageWidth() {
    if (!this.$backgroundImageInfo)
      return 0;
    return Math.abs(this.$backgroundImageInfo.naturalWidth * this.$backgroundImageInfo.imageTransform.scale.x);
  }
  set $imageWidth(v) {
    const imageTransform = this.$backgroundImageInfo.imageTransform;
    const baseNum = imageTransform.scale.x < 0 ? -1 : 1;
    imageTransform.scale.x = v / this.$backgroundImageInfo.naturalWidth * baseNum;
  }
  get $imageHeight() {
    if (!this.$backgroundImageInfo)
      return 0;
    return Math.abs(this.$backgroundImageInfo.naturalHeight * this.$backgroundImageInfo.imageTransform.scale.y);
  }
  set $imageHeight(v) {
    if (!this.$backgroundImageInfo)
      return;
    const imageTransform = this.$backgroundImageInfo.imageTransform;
    const baseNum = imageTransform.scale.y < 0 ? -1 : 1;
    imageTransform.scale.y = v / this.$backgroundImageInfo.naturalHeight * baseNum;
  }
  get $imageLeft() {
    if (!this.$backgroundImageInfo)
      return 0;
    const {
      $backgroundImageInfo: {
        width,
        imageTransform: { position }
      },
      $imageWidth
    } = this;
    return width / 2 - $imageWidth / 2 + position.x;
  }
  set $imageLeft(v) {
    if (!this.$backgroundImageInfo)
      return;
    this.$backgroundImageInfo.imageTransform.position.x = v + this.$imageWidth / 2 - this.$backgroundImageInfo.width / 2;
  }
  get $imageTop() {
    if (!this.$backgroundImageInfo)
      return 0;
    const {
      $backgroundImageInfo: {
        height,
        imageTransform: { position }
      },
      $imageHeight
    } = this;
    return height / 2 - $imageHeight / 2 + position.y;
  }
  set $imageTop(v) {
    if (!this.$backgroundImageInfo)
      return;
    this.$backgroundImageInfo.imageTransform.position.y = v + this.$imageHeight / 2 - this.$backgroundImageInfo.height / 2;
  }
  get hasComplexFilters() {
    const { filterInfo } = this.$backgroundImageInfo || {};
    return filterInfo && (filterInfo.url || filterInfo.prunedZipUrl);
  }
  get hasBaseFilters() {
    const { filter } = this.$backgroundImageInfo || {};
    const defaultFilter = editorDefaults.element.filter;
    if (!filter)
      return false;
    return Object.keys(filter).some((key) => filter[key] !== defaultFilter[key]);
  }
  get hasFilters() {
    return this.hasBaseFilters || this.hasComplexFilters;
  }
  get isGif() {
    return lodash.exports.get(this, "background.image.resourceType") === "gif";
  }
  get isApng() {
    return lodash.exports.get(this, "background.image.resourceType") === "apng";
  }
  get filter() {
    var _a, _b;
    return !!((_b = (_a = this.background) == null ? void 0 : _a.image) == null ? void 0 : _b.filter);
  }
  get filterInfo() {
    var _a, _b;
    return !!((_b = (_a = this.background) == null ? void 0 : _a.image) == null ? void 0 : _b.filterInfo);
  }
  get backgroundWatermarkEnable() {
    var _a;
    return !!((_a = this.background) == null ? void 0 : _a.watermarkEnable);
  }
  get backgroundColor() {
    var _a;
    return (_a = this.background) == null ? void 0 : _a.color;
  }
  get backgroundGradient() {
    var _a;
    return (_a = this.background) == null ? void 0 : _a.gradient;
  }
  get backgroundImage() {
    return this.$backgroundImage;
  }
  get backgroundImageInfo() {
    var _a;
    if (!((_a = this.background) == null ? void 0 : _a.image))
      return null;
    const image = this.background.image;
    return {
      transform: image.imageTransform,
      width: image.naturalWidth,
      height: image.naturalHeight,
      opacity: image.opacity
    };
  }
}
const { abs, PI, sin, cos } = Math;
function getPoint(angle, width, height) {
  const ang = (90 - angle) * (PI / 180);
  const gradientLineLength = abs(width * sin(ang)) + abs(height * cos(ang));
  const center = {
    x: width / 2,
    y: height / 2
  };
  const yDiff = sin(ang - PI / 2) * gradientLineLength / 2;
  const xDiff = cos(ang - PI / 2) * gradientLineLength / 2;
  return [center.x - xDiff, center.y - yDiff, center.x + xDiff, center.y + yDiff];
}
class BackgroundRender extends BaseRender {
  constructor({ editor, layout, element, canvas }) {
    super({
      canvas
    });
    this.editor = editor;
    this.layout = layout && layout.backgroundSize ? new LayoutModel(lodash.exports.cloneDeep(layout), editor) : layout;
    this.element = element;
    this.options = editor.options;
    this.canvas = canvas || createCanvas(Math.round(this.model.width), Math.round(this.model.height));
  }
  get model() {
    return this.element || this.layout;
  }
  get background() {
    return this.model.background;
  }
  get opacity() {
    const opacity = lodash.exports.get(this, "element.backgroundEffect.opacity") || this.backgroundImageInfo.opacity;
    return opacity === void 0 ? 1 : opacity;
  }
  get effectImage() {
    var _a;
    if (this.element) {
      return lodash.exports.get(this, "element.backgroundEffect.type") === "image" && lodash.exports.get(this, "element.backgroundEffect.image");
    }
    const image = Object.assign({}, (_a = this.background) == null ? void 0 : _a.image);
    image.url = this.layout.backgroundEffectImage || image.url;
    return image;
  }
  get effectGradient() {
    if (this.element) {
      return lodash.exports.get(this, "element.backgroundEffect.type") === "gradient" && lodash.exports.get(this, "element.backgroundEffect.gradient");
    }
    return this.background.gradient;
  }
  get effectNinePatch() {
    if (this.element) {
      return lodash.exports.get(this, "element.backgroundEffect.type") === "ninePatch" && lodash.exports.get(this, "element.backgroundEffect.ninePatch");
    }
    return void 0;
  }
  get backgroundImage() {
    return this.effectImage.url;
  }
  get backgroundImageInfo() {
    return lodash.exports.get(this.background, "image", this.model.backgroundImageInfo) || {};
  }
  get backgroundColor() {
    const color = lodash.exports.get(this.background, "color", this.model.backgroundColor);
    return color ? tinycolor(color) : null;
  }
  load() {
    return loader.loadImage(this.backgroundImage);
  }
  async export() {
    const { editor, model } = this;
    if (editor.getComponentById(model.$id)) {
      const layoutVm = this.editor.getComponentById(model.$id);
      const canvas = layoutVm.$refs.background && layoutVm.$refs.background.$refs.canvas;
      if (canvas && window.getComputedStyle(canvas).display !== "none") {
        await Promise$1.delay(10);
        this._promise && await this._promise;
        return canvas;
      }
    }
    await this.render();
    return this.canvas;
  }
  render() {
    this._promise = Promise$1.try(async () => {
      if (!this.isNeedRender())
        return this.canvas;
      this.setPreData();
      const ctx = this.canvas.getContext("2d");
      const {
        backgroundColor,
        effectImage,
        effectGradient,
        effectNinePatch,
        backgroundImage
      } = this;
      ctx.save();
      if (backgroundColor) {
        this.renderColor(ctx);
      }
      if (effectGradient) {
        this.renderGradient(ctx);
      }
      if (backgroundImage && effectImage) {
        await this.renderImage(ctx);
      }
      if (effectNinePatch) {
        await this.renderNinePatch(ctx);
      }
      ctx.restore();
      return ctx.canvas;
    });
    return this._promise;
  }
  async renderImage(ctx) {
    if (this.element) {
      return this.renderElementImage(ctx);
    }
    const { effectImage } = this;
    const bgImageModel = this.editor.createElement(__spreadProps(__spreadValues({}, effectImage), { type: "image" }));
    let imageRenderer = this.layout.hasFilters && this.editor.$renderers.get(this.layout.$id);
    if (this.layout.hasFilters && (!imageRenderer || !imageRenderer.promise)) {
      imageRenderer = new ImageRenderer({
        model: bgImageModel,
        byNaturalSize: !!this.isBackground,
        emitEventEnable: false,
        editor: this.editor
      });
    }
    const image = imageRenderer ? await imageRenderer.export() : await this.load();
    const tempCanvas = createCanvas(bgImageModel.width, bgImageModel.height);
    ctx.save();
    ctx.globalAlpha = effectImage.opacity;
    newDrawImageToCanvas({
      canvas: tempCanvas,
      width: bgImageModel.width,
      height: bgImageModel.height,
      naturalWidth: bgImageModel.naturalWidth,
      naturalHeight: bgImageModel.naturalHeight,
      imageTransformArray: bgImageModel.imageTransform.toArray(),
      blendMode: "source-over",
      image
    });
    this.editor.applyElementPropsToCanvas(bgImageModel, tempCanvas, ctx.canvas);
    tempCanvas.width = 0;
    tempCanvas.height = 0;
    ctx.restore();
    return ctx.canvas;
  }
  async renderElementImage(ctx) {
    const { model, effectImage, opacity } = this;
    const transform = effectImage.imageTransform || effectImage.transform;
    const image = await this.load();
    ctx.save();
    ctx.globalAlpha = opacity;
    newDrawImageToCanvas({
      canvas: ctx.canvas,
      image,
      width: model.width,
      height: model.height,
      naturalWidth: effectImage.naturalWidth,
      naturalHeight: effectImage.naturalHeight,
      imageTransformArray: transform.toArray ? transform.toArray() : Object.values(transform),
      blendMode: "source-over"
    });
    ctx.restore();
    return ctx.canvas;
  }
  renderColor(ctx) {
    const { model } = this;
    const bgColor = this.backgroundColor;
    ctx.save();
    ctx.globalAlpha = bgColor.getAlpha();
    ctx.fillStyle = bgColor.toHexString();
    ctx.fillRect(0, 0, model.width, model.height);
    ctx.restore();
  }
  renderGradient(ctx) {
    const { model, effectGradient } = this;
    ctx.save();
    ctx.globalAlpha = this.opacity;
    const { angle, stops } = effectGradient;
    const [topX, topY, botX, botY] = getPoint(angle, model.width, model.height);
    const gradientFill = ctx.createLinearGradient(topX, topY, botX, botY);
    stops.forEach((stop) => {
      gradientFill.addColorStop(stop.offset, tinycolor(stop.color).toRgbString());
    });
    ctx.fillStyle = gradientFill;
    ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    ctx.restore();
  }
  async renderNinePatch(ctx) {
    const { width, height } = this.model;
    const { url, imageSlice, effectScale } = this.effectNinePatch;
    ctx.save();
    ctx.globalAlpha = this.opacity;
    const _canvas = await autoStretchImage(url, {
      targetWidth: Math.round(width),
      targetHeight: Math.round(height),
      imageSlice,
      targetImageSlice: {
        left: imageSlice.left * effectScale,
        top: imageSlice.top * effectScale,
        right: imageSlice.right * effectScale,
        bottom: imageSlice.bottom * effectScale
      }
    });
    ctx.drawImage(_canvas, 0, 0, width, height);
    ctx.restore();
  }
}
export { BackgroundRender as B, ElementModel as E, ImageModel as I, LayoutModel as L, TableRenderer as T, ImageBaseModel as a, getUpdateFontsSubset as b, adaptationImageTransform as c, urlToBlob as d, editorResourceMap as e, getImageUrlByHash as f, getEffectedTextEffects as g, hexaToRgba as h, getElementHash as i, getComponentById as j, checkLoaded as k, canvasToBlob as l, converPropsBackground as m, getAdaptationImageTransform as n, loadFontsSubset as o, loadImage as p, loadFonts as q, resetLayoutProps as r, setImageUrlByHash as s, useEffects as u };
