@imgly/plugin-background-removal-web 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/utils.ts", "../src/constants.ts", "../src/registerComponents.ts", "../src/enableFeatures.ts", "../src/processBackgroundRemoval.ts", "../src/plugin.ts", "../src/index.ts"],
4
- "sourcesContent": ["import type CreativeEditorSDK from '@cesdk/cesdk-js';\nimport isEqual from 'lodash/isEqual';\n\nimport {\n BGRemovalError,\n BGRemovalMetadata,\n BGRemovalProcessed,\n BGRemovalProcessing\n} from './types';\nimport { BG_REMOVAL_ID } from './constants';\n\n/**\n * Sets the metadata for the background removal state.\n */\nexport function setBGRemovalMetadata(\n cesdk: CreativeEditorSDK,\n id: number,\n metadata: BGRemovalMetadata\n) {\n cesdk.engine.block.setMetadata(id, BG_REMOVAL_ID, JSON.stringify(metadata));\n}\n\n/**\n * Returns the current metadata for the background removal state. If no metadata\n * is set on the given block, it will return an IDLE state.\n */\nexport function getBGRemovalMetadata(\n cesdk: CreativeEditorSDK,\n id: number\n): BGRemovalMetadata {\n if (cesdk.engine.block.hasMetadata(id, BG_REMOVAL_ID)) {\n return JSON.parse(cesdk.engine.block.getMetadata(id, BG_REMOVAL_ID));\n } else {\n return {\n status: 'IDLE'\n };\n }\n}\n\n/**\n * If BG Removal metadata is set, it will be cleared.\n */\nexport function clearBGRemovalMetadata(cesdk: CreativeEditorSDK, id: number) {\n if (cesdk.engine.block.hasMetadata(id, BG_REMOVAL_ID)) {\n cesdk.engine.block.removeMetadata(id, BG_REMOVAL_ID);\n }\n}\n\n/**\n * Detect if the block has been duplicated with processed or processing\n * background removal. In that case the background removal state is still\n * valid, but blockId and fillId have changed.\n */\nexport function isDuplicate(\n cesdk: CreativeEditorSDK,\n blockId: number,\n metadata: BGRemovalMetadata\n): boolean {\n if (!cesdk.engine.block.isValid(blockId)) return false;\n if (\n metadata.status === 'IDLE' ||\n metadata.status === 'PENDING' ||\n metadata.status === 'ERROR'\n )\n return false;\n\n if (!cesdk.engine.block.hasFill(blockId)) return false;\n const fillId = cesdk.engine.block.getFill(blockId);\n\n // It cannot be a duplicate if the blockId or fillId are the same\n if (metadata.blockId === blockId || metadata.fillId === fillId) return false;\n\n return true;\n}\n\n/**\n * Fixes the metadata if the block has been duplicated, i.e. the blockId and\n * fillId will be updated to the current block/fill.\n *\n * Please note: Call this method only on duplicates (see isDuplicate).\n */\nexport function fixDuplicateMetadata(\n cesdk: CreativeEditorSDK,\n blockId: number\n) {\n const fillId = cesdk.engine.block.getFill(blockId);\n const metadata = getBGRemovalMetadata(cesdk, blockId);\n if (\n metadata.status === 'IDLE' ||\n metadata.status === 'PENDING' ||\n metadata.status === 'ERROR'\n )\n return;\n setBGRemovalMetadata(cesdk, blockId, {\n ...metadata,\n blockId,\n fillId\n });\n}\n\n/**\n * Check if the image has a consisten metadata state. A inconsistent state is\n * caused by outside changes of the fill data.\n *\n * @returns true if the metadata is consistent, false otherwise\n */\nexport function isMetadataConsistent(\n cesdk: CreativeEditorSDK,\n blockId: number\n): boolean {\n // In case the block was removed, we just abort and mark it\n // as reset by returning true\n if (!cesdk.engine.block.isValid(blockId)) return false;\n const metadata = getBGRemovalMetadata(cesdk, blockId);\n if (metadata.status === 'IDLE' || metadata.status === 'PENDING') return true;\n\n if (!cesdk.engine.block.hasFill(blockId)) return false;\n const fillId = cesdk.engine.block.getFill(blockId);\n if (fillId == null) return false;\n\n if (blockId !== metadata.blockId || fillId !== metadata.fillId) return false;\n\n const sourceSet = cesdk.engine.block.getSourceSet(\n fillId,\n 'fill/image/sourceSet'\n );\n const imageFileURI = cesdk.engine.block.getString(\n fillId,\n 'fill/image/imageFileURI'\n );\n\n if (\n sourceSet.length === 0 &&\n !imageFileURI &&\n metadata.status === 'PROCESSING'\n ) {\n // While we process it is OK to have no image file URI and no source set\n // (which we cleared to show the spinning loader)\n return true;\n }\n\n // Source sets have precedence over imageFileURI so if we have a source set,\n // we only need to check if it has changed to something else.\n if (sourceSet?.length > 0) {\n const initialSourceSet = metadata.initialSourceSet;\n // If we have already processed the image, we need to check if the source set\n // we need to check against both source sets, the removed and the initial\n if (\n metadata.status === 'PROCESSED_WITH_BG' ||\n metadata.status === 'PROCESSED_WITHOUT_BG'\n ) {\n const removedBackground = metadata.removedBackground;\n if (\n !isEqual(sourceSet, removedBackground) &&\n !isEqual(sourceSet, initialSourceSet)\n ) {\n return false;\n }\n } else {\n if (!isEqual(sourceSet, initialSourceSet)) {\n return false;\n }\n }\n } else {\n if (\n metadata.status === 'PROCESSED_WITH_BG' ||\n metadata.status === 'PROCESSED_WITHOUT_BG'\n ) {\n if (\n imageFileURI !== metadata.initialImageFileURI &&\n imageFileURI !== metadata.removedBackground\n ) {\n return false;\n }\n } else {\n if (imageFileURI !== metadata.initialImageFileURI) {\n return false;\n }\n }\n }\n return true;\n}\n\n/**\n * Toggle between the background removed image and the original image if either\n * in the state \"PROCESSED_WITH_BG\" or \"PROCESSED_WITHOUT_BG\". Otherwise do\n * nothing.\n */\nexport function toggleBackgroundRemovalData(\n cesdk: CreativeEditorSDK,\n blockId: number\n) {\n const blockApi = cesdk.engine.block;\n if (!blockApi.hasFill(blockId)) return; // Nothing to recover (no fill anymore)\n const fillId = blockApi.getFill(blockId);\n\n const metadata = getBGRemovalMetadata(cesdk, blockId);\n\n if (metadata.status === 'PROCESSED_WITH_BG') {\n setBGRemovalMetadata(cesdk, blockId, {\n ...metadata,\n status: 'PROCESSED_WITHOUT_BG'\n });\n\n if (typeof metadata.removedBackground === 'string') {\n blockApi.setString(\n fillId,\n 'fill/image/imageFileURI',\n metadata.removedBackground\n );\n } else {\n blockApi.setSourceSet(\n fillId,\n 'fill/image/sourceSet',\n metadata.removedBackground\n );\n }\n\n cesdk.engine.editor.addUndoStep();\n } else if (metadata.status === 'PROCESSED_WITHOUT_BG') {\n setBGRemovalMetadata(cesdk, blockId, {\n ...metadata,\n status: 'PROCESSED_WITH_BG'\n });\n\n blockApi.setString(\n fillId,\n 'fill/image/imageFileURI',\n metadata.initialImageFileURI\n );\n blockApi.setSourceSet(\n fillId,\n 'fill/image/sourceSet',\n metadata.initialSourceSet\n );\n cesdk.engine.editor.addUndoStep();\n }\n}\n\n/**\n * Recover the initial values to avoid the loading spinner and have the same\n * state as before the background removal was started.\n */\nexport function recoverInitialImageData(\n cesdk: CreativeEditorSDK,\n blockId: number\n) {\n const blockApi = cesdk.engine.block;\n if (!blockApi.hasFill(blockId)) return; // Nothing to recover (no fill anymore)\n\n const metadata = getBGRemovalMetadata(cesdk, blockId);\n\n if (metadata.status === 'PENDING' || metadata.status === 'IDLE') {\n return;\n }\n\n const initialSourceSet = metadata.initialSourceSet;\n const initialImageFileURI = metadata.initialImageFileURI;\n\n const fillId = getValidFill(cesdk, blockId, metadata);\n if (fillId == null) return;\n\n if (initialImageFileURI) {\n cesdk.engine.block.setString(\n fillId,\n 'fill/image/imageFileURI',\n initialImageFileURI\n );\n }\n if (initialSourceSet.length > 0) {\n cesdk.engine.block.setSourceSet(\n fillId,\n 'fill/image/sourceSet',\n initialSourceSet\n );\n }\n}\n\n/**\n * Returns the fill id of the block if it has a valid fill that was used for\n * background removal. Returns undefined otherwise.\n */\nfunction getValidFill(\n cesdk: CreativeEditorSDK,\n blockId: number,\n metadata: BGRemovalProcessing | BGRemovalError | BGRemovalProcessed\n): number | undefined {\n if (\n !cesdk.engine.block.isValid(blockId) ||\n !cesdk.engine.block.hasFill(blockId) ||\n blockId !== metadata.blockId\n ) {\n return undefined;\n }\n const fillId = cesdk.engine.block.getFill(blockId);\n if (fillId !== metadata.fillId) {\n return undefined;\n }\n\n return fillId;\n}\n", "export const BG_REMOVAL_ID = '@imgly/plugin-background-removal-web';\nexport const CANVAS_MENU_COMPONENT_ID = `${BG_REMOVAL_ID}.canvasMenu`;\nexport const CANVAS_MENU_COMPONENT_BUTTON_ID = `${CANVAS_MENU_COMPONENT_ID}.button`;\nexport const FEATURE_ID = `${BG_REMOVAL_ID}.feature`;\n", "import type CreativeEditorSDK from '@cesdk/cesdk-js';\n\nimport {\n CANVAS_MENU_COMPONENT_BUTTON_ID,\n CANVAS_MENU_COMPONENT_ID,\n FEATURE_ID\n} from './constants';\nimport {\n getBGRemovalMetadata,\n setBGRemovalMetadata,\n toggleBackgroundRemovalData\n} from './utils';\n\n/**\n * Registers the components that can be used to remove the background of\n * a block.\n */\nexport function registerComponents(cesdk: CreativeEditorSDK) {\n // Always prepend the registered component to the canvas menu order.\n cesdk.ui.unstable_setCanvasMenuOrder([\n CANVAS_MENU_COMPONENT_ID,\n ...cesdk.ui.unstable_getCanvasMenuOrder()\n ]);\n cesdk.ui.unstable_registerComponent(\n CANVAS_MENU_COMPONENT_ID,\n ({ builder: { Button }, engine }) => {\n if (\n !cesdk.feature.unstable_isEnabled(FEATURE_ID, {\n engine\n })\n ) {\n return;\n }\n\n const [id] = engine.block.findAllSelected();\n\n const metadata = getBGRemovalMetadata(cesdk, id);\n\n const isActive = metadata.status === 'PROCESSED_WITHOUT_BG';\n const isLoading = metadata.status === 'PROCESSING';\n const isDisabled =\n metadata.status === 'PENDING' || metadata.status === 'PROCESSING';\n\n let loadingProgress: number | undefined;\n if (isLoading && metadata.progress) {\n const { key, current, total } = metadata.progress;\n\n if (key === 'compute:inference') {\n loadingProgress = undefined;\n } else if (key.startsWith('fetch:/models/')) {\n loadingProgress = (current / total) * 50;\n } else if (key.startsWith('fetch:/onnxruntime-web/')) {\n loadingProgress = 50 + (current / total) * 50;\n } else {\n loadingProgress = undefined;\n }\n }\n\n Button(CANVAS_MENU_COMPONENT_BUTTON_ID, {\n label: 'BG Removal',\n icon: '@imgly/icons/BGRemove',\n isActive,\n isLoading,\n isDisabled,\n loadingProgress,\n onClick: () => {\n switch (metadata.status) {\n case 'IDLE':\n case 'ERROR': {\n setBGRemovalMetadata(cesdk, id, {\n status: 'PENDING'\n });\n break;\n }\n\n case 'PROCESSED_WITHOUT_BG':\n case 'PROCESSED_WITH_BG': {\n toggleBackgroundRemovalData(cesdk, id);\n break;\n }\n\n default: {\n // We do not care about the other states in the button\n }\n }\n }\n });\n }\n );\n}\n", "import type CreativeEditorSDK from '@cesdk/cesdk-js';\nimport { FEATURE_ID } from './constants';\nimport { getBGRemovalMetadata } from './utils';\n\n/**\n * Defines the feature that determines in which context (on which block)\n * background removal is allowed/enabled.\n */\nexport function enableFeatures(cesdk: CreativeEditorSDK) {\n cesdk.feature.unstable_enable(FEATURE_ID, ({ engine }) => {\n const selectedIds = engine.block.findAllSelected();\n if (selectedIds.length !== 1) {\n return false;\n }\n const [selectedId] = selectedIds;\n\n if (cesdk.engine.block.hasFill(selectedId)) {\n const fillId = cesdk.engine.block.getFill(selectedId);\n const fillType = cesdk.engine.block.getType(fillId);\n\n if (fillType !== '//ly.img.ubq/fill/image') {\n return false;\n }\n\n const fileUri = engine.block.getString(fillId, 'fill/image/imageFileURI');\n const sourceSet = engine.block.getSourceSet(\n fillId,\n 'fill/image/sourceSet'\n );\n\n if (sourceSet.length > 0 || fileUri !== '') return true;\n\n // If we are in a processing state we do not have a imageFileURI or\n // source set set (to show the loading spinner), but the feature is still\n // enabled.\n const metadata = getBGRemovalMetadata(cesdk, selectedId);\n return metadata.status === 'PROCESSING';\n }\n\n return false;\n });\n}\n", "import type CreativeEditorSDK from '@cesdk/cesdk-js';\nimport { type Source } from '@cesdk/cesdk-js';\nimport {\n segmentForeground,\n applySegmentationMask,\n type Config\n} from '@imgly/background-removal';\n\nimport throttle from 'lodash/throttle';\n\nimport {\n getBGRemovalMetadata,\n recoverInitialImageData,\n isMetadataConsistent,\n setBGRemovalMetadata\n} from './utils';\n\n/**\n * Triggers the background removal process.\n */\nexport async function processBackgroundRemoval(\n cesdk: CreativeEditorSDK,\n blockId: number,\n configuration: Config\n) {\n const blockApi = cesdk.engine.block;\n if (!blockApi.hasFill(blockId))\n throw new Error('Block has no fill to remove the background from');\n\n const fillId = blockApi.getFill(blockId);\n\n // Get the current image URI and source set as initial values.\n const initialSourceSet = blockApi.getSourceSet(\n fillId,\n 'fill/image/sourceSet'\n );\n const initialImageFileURI = blockApi.getString(\n fillId,\n 'fill/image/imageFileURI'\n );\n\n try {\n // Clear values in the engine to trigger the loading spinner\n blockApi.setString(fillId, 'fill/image/imageFileURI', '');\n blockApi.setSourceSet(fillId, 'fill/image/sourceSet', []);\n\n const metadata = getBGRemovalMetadata(cesdk, blockId);\n setBGRemovalMetadata(cesdk, blockId, {\n ...metadata,\n version: PLUGIN_VERSION,\n initialSourceSet,\n initialImageFileURI,\n blockId,\n fillId,\n status: 'PROCESSING'\n });\n\n const uriToProcess =\n // Source sets have priority in the engine\n initialSourceSet.length > 0\n ? // Choose the highest resolution image in the source set\n initialSourceSet.sort(\n (a, b) => b.width * b.height - a.height * a.width\n )[0].uri\n : initialImageFileURI;\n\n // Creating the mask from the highest resolution image\n const mask = await segmentForeground(uriToProcess, configuration);\n\n if (initialSourceSet.length > 0) {\n // Source set code path\n // ====================\n const uploaded = await maskSourceSet<Source>(\n cesdk,\n blockId,\n initialSourceSet,\n mask,\n configuration\n );\n if (uploaded == null) return;\n\n if (uploaded.every((url) => url == null)) {\n throw new Error('Could not upload any BG removed image');\n }\n\n const newSourceSet = initialSourceSet.map((source, index) => {\n return {\n ...source,\n uri: uploaded[index]\n };\n });\n\n setBGRemovalMetadata(cesdk, blockId, {\n version: PLUGIN_VERSION,\n initialSourceSet,\n initialImageFileURI,\n blockId,\n fillId,\n status: 'PROCESSED_WITHOUT_BG',\n removedBackground: newSourceSet\n });\n blockApi.setSourceSet(fillId, 'fill/image/sourceSet', newSourceSet);\n } else {\n // ImageFileURI code path\n // ======================\n const uploaded = await maskSourceSet<{ uri: string }>(\n cesdk,\n blockId,\n [{ uri: uriToProcess }],\n mask,\n configuration\n );\n if (uploaded == null) return;\n\n const uploadedUrl = uploaded[0];\n if (uploadedUrl == null) {\n throw new Error('Could not upload BG removed image');\n }\n\n setBGRemovalMetadata(cesdk, blockId, {\n version: PLUGIN_VERSION,\n initialSourceSet,\n initialImageFileURI,\n blockId,\n fillId,\n status: 'PROCESSED_WITHOUT_BG',\n removedBackground: uploadedUrl\n });\n blockApi.setString(fillId, 'fill/image/imageFileURI', uploadedUrl);\n }\n // Finally, create an undo step\n cesdk.engine.editor.addUndoStep();\n } catch (error) {\n if (cesdk.engine.block.isValid(blockId)) {\n setBGRemovalMetadata(cesdk, blockId, {\n version: PLUGIN_VERSION,\n initialSourceSet,\n initialImageFileURI,\n blockId,\n fillId,\n status: 'ERROR'\n });\n\n recoverInitialImageData(cesdk, blockId);\n }\n // eslint-disable-next-line no-console\n console.log(error);\n }\n}\n\nasync function maskSourceSet<T extends { uri: string }>(\n cesdk: CreativeEditorSDK,\n blockId: number,\n urisOrSources: T[],\n mask: Blob,\n configurationFromArgs: Config\n): Promise<string[] | undefined> {\n const configuration = {\n ...configurationFromArgs,\n progress: throttle((key, current, total) => {\n const metadataDuringProgress = getBGRemovalMetadata(cesdk, blockId);\n if (\n metadataDuringProgress.status !== 'PROCESSING' ||\n !isMetadataConsistent(cesdk, blockId)\n )\n return;\n configurationFromArgs.progress?.(key, current, total);\n setBGRemovalMetadata(cesdk, blockId, {\n ...metadataDuringProgress,\n progress: { key, current, total }\n });\n }, 100)\n };\n\n const masked = await Promise.all(\n urisOrSources.map(async (source): Promise<[Blob, T]> => {\n // Applying the mask to the original image\n const blob = await applySegmentationMask(source.uri, mask, configuration);\n return [blob, source];\n })\n );\n\n // Check for externally changed state while we were applying the mask and\n // do not proceed if the state was reset.\n if (\n getBGRemovalMetadata(cesdk, blockId).status !== 'PROCESSING' ||\n !isMetadataConsistent(cesdk, blockId)\n )\n return;\n\n const uploaded = await Promise.all(\n masked.map(async ([blob, source]): Promise<[string, T]> => {\n const pathname = new URL(source.uri).pathname;\n const parts = pathname.split('/');\n const filename = parts[parts.length - 1];\n\n const uploadedAssets = await cesdk.unstable_upload(\n new File([blob], filename, { type: blob.type }),\n () => {\n // TODO Delegate process to UI component\n }\n );\n\n const url = uploadedAssets.meta?.uri;\n if (url == null) {\n throw new Error('Could not upload BG removed image');\n }\n return [url, source];\n })\n );\n\n // Check for externally changed state while we were uploading and\n // do not proceed if the state was reset.\n if (\n getBGRemovalMetadata(cesdk, blockId).status !== 'PROCESSING' ||\n !isMetadataConsistent(cesdk, blockId)\n )\n return;\n\n return uploaded.map(([url]) => url);\n}\n", "import type CreativeEditorSDK from '@cesdk/cesdk-js';\n\nimport {\n clearBGRemovalMetadata,\n fixDuplicateMetadata,\n getBGRemovalMetadata,\n isDuplicate,\n isMetadataConsistent\n} from './utils';\nimport { BG_REMOVAL_ID, FEATURE_ID } from './constants';\nimport { registerComponents } from './registerComponents';\nimport { enableFeatures } from './enableFeatures';\nimport { processBackgroundRemoval } from './processBackgroundRemoval';\nimport type { Config as BackgroundRemovalConfiguration } from '@imgly/background-removal';\n\nexport interface PluginConfiguration {\n backgroundRemoval?: BackgroundRemovalConfiguration;\n}\n\nexport default (pluginConfiguration: PluginConfiguration = {}) => {\n const backgroundRemovalConfiguration: BackgroundRemovalConfiguration =\n pluginConfiguration?.backgroundRemoval ?? {};\n\n return {\n initialize() {},\n\n update() {},\n\n initializeUserInterface({ cesdk }: { cesdk: CreativeEditorSDK }) {\n cesdk.engine.event.subscribe([], async (events) => {\n events.forEach((e) => {\n const id = e.block;\n if (\n !cesdk.engine.block.isValid(id) ||\n !cesdk.engine.block.hasMetadata(id, BG_REMOVAL_ID)\n ) {\n return;\n }\n\n if (e.type === 'Created') {\n const metadata = getBGRemovalMetadata(cesdk, id);\n if (isDuplicate(cesdk, id, metadata)) {\n fixDuplicateMetadata(cesdk, id);\n }\n } else if (e.type === 'Updated') {\n handleUpdateEvent(cesdk, id, backgroundRemovalConfiguration);\n }\n });\n });\n\n registerComponents(cesdk);\n enableFeatures(cesdk);\n }\n };\n};\n\n/**\n * Handle every possible state of the background removal state if the block was\n * updated.\n */\nasync function handleUpdateEvent(\n cesdk: CreativeEditorSDK,\n blockId: number,\n configuration: BackgroundRemovalConfiguration\n) {\n const metadata = getBGRemovalMetadata(cesdk, blockId);\n\n switch (metadata.status) {\n case 'PENDING': {\n if (\n cesdk.feature.unstable_isEnabled(FEATURE_ID, {\n engine: cesdk.engine\n })\n ) {\n processBackgroundRemoval(cesdk, blockId, configuration);\n }\n break;\n }\n\n case 'PROCESSING':\n case 'PROCESSED_WITH_BG':\n case 'PROCESSED_WITHOUT_BG': {\n if (!isMetadataConsistent(cesdk, blockId)) {\n clearBGRemovalMetadata(cesdk, blockId);\n }\n break;\n }\n\n default: {\n // We do not care about other states\n }\n }\n}\n", "import plugin, { type PluginConfiguration } from './plugin';\n\nimport { BG_REMOVAL_ID } from './constants';\n\nconst Plugin = (pluginConfiguration?: PluginConfiguration) => ({\n name: BG_REMOVAL_ID,\n version: PLUGIN_VERSION,\n ...plugin(pluginConfiguration)\n});\n\nexport default Plugin;\n"],
5
- "mappings": ";AACA,OAAO,aAAa;;;ACDb,IAAM,gBAAgB;AACtB,IAAM,2BAA2B,GAAG,aAAa;AACjD,IAAM,kCAAkC,GAAG,wBAAwB;AACnE,IAAM,aAAa,GAAG,aAAa;;;ADWnC,SAAS,qBACd,OACA,IACA,UACA;AACA,QAAM,OAAO,MAAM,YAAY,IAAI,eAAe,KAAK,UAAU,QAAQ,CAAC;AAC5E;AAMO,SAAS,qBACd,OACA,IACmB;AACnB,MAAI,MAAM,OAAO,MAAM,YAAY,IAAI,aAAa,GAAG;AACrD,WAAO,KAAK,MAAM,MAAM,OAAO,MAAM,YAAY,IAAI,aAAa,CAAC;AAAA,EACrE,OAAO;AACL,WAAO;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAKO,SAAS,uBAAuB,OAA0B,IAAY;AAC3E,MAAI,MAAM,OAAO,MAAM,YAAY,IAAI,aAAa,GAAG;AACrD,UAAM,OAAO,MAAM,eAAe,IAAI,aAAa;AAAA,EACrD;AACF;AAOO,SAAS,YACd,OACA,SACA,UACS;AACT,MAAI,CAAC,MAAM,OAAO,MAAM,QAAQ,OAAO;AAAG,WAAO;AACjD,MACE,SAAS,WAAW,UACpB,SAAS,WAAW,aACpB,SAAS,WAAW;AAEpB,WAAO;AAET,MAAI,CAAC,MAAM,OAAO,MAAM,QAAQ,OAAO;AAAG,WAAO;AACjD,QAAM,SAAS,MAAM,OAAO,MAAM,QAAQ,OAAO;AAGjD,MAAI,SAAS,YAAY,WAAW,SAAS,WAAW;AAAQ,WAAO;AAEvE,SAAO;AACT;AAQO,SAAS,qBACd,OACA,SACA;AACA,QAAM,SAAS,MAAM,OAAO,MAAM,QAAQ,OAAO;AACjD,QAAM,WAAW,qBAAqB,OAAO,OAAO;AACpD,MACE,SAAS,WAAW,UACpB,SAAS,WAAW,aACpB,SAAS,WAAW;AAEpB;AACF,uBAAqB,OAAO,SAAS;AAAA,IACnC,GAAG;AAAA,IACH;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAQO,SAAS,qBACd,OACA,SACS;AAGT,MAAI,CAAC,MAAM,OAAO,MAAM,QAAQ,OAAO;AAAG,WAAO;AACjD,QAAM,WAAW,qBAAqB,OAAO,OAAO;AACpD,MAAI,SAAS,WAAW,UAAU,SAAS,WAAW;AAAW,WAAO;AAExE,MAAI,CAAC,MAAM,OAAO,MAAM,QAAQ,OAAO;AAAG,WAAO;AACjD,QAAM,SAAS,MAAM,OAAO,MAAM,QAAQ,OAAO;AACjD,MAAI,UAAU;AAAM,WAAO;AAE3B,MAAI,YAAY,SAAS,WAAW,WAAW,SAAS;AAAQ,WAAO;AAEvE,QAAM,YAAY,MAAM,OAAO,MAAM;AAAA,IACnC;AAAA,IACA;AAAA,EACF;AACA,QAAM,eAAe,MAAM,OAAO,MAAM;AAAA,IACtC;AAAA,IACA;AAAA,EACF;AAEA,MACE,UAAU,WAAW,KACrB,CAAC,gBACD,SAAS,WAAW,cACpB;AAGA,WAAO;AAAA,EACT;AAIA,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM,mBAAmB,SAAS;AAGlC,QACE,SAAS,WAAW,uBACpB,SAAS,WAAW,wBACpB;AACA,YAAM,oBAAoB,SAAS;AACnC,UACE,CAAC,QAAQ,WAAW,iBAAiB,KACrC,CAAC,QAAQ,WAAW,gBAAgB,GACpC;AACA,eAAO;AAAA,MACT;AAAA,IACF,OAAO;AACL,UAAI,CAAC,QAAQ,WAAW,gBAAgB,GAAG;AACzC,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF,OAAO;AACL,QACE,SAAS,WAAW,uBACpB,SAAS,WAAW,wBACpB;AACA,UACE,iBAAiB,SAAS,uBAC1B,iBAAiB,SAAS,mBAC1B;AACA,eAAO;AAAA,MACT;AAAA,IACF,OAAO;AACL,UAAI,iBAAiB,SAAS,qBAAqB;AACjD,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,4BACd,OACA,SACA;AACA,QAAM,WAAW,MAAM,OAAO;AAC9B,MAAI,CAAC,SAAS,QAAQ,OAAO;AAAG;AAChC,QAAM,SAAS,SAAS,QAAQ,OAAO;AAEvC,QAAM,WAAW,qBAAqB,OAAO,OAAO;AAEpD,MAAI,SAAS,WAAW,qBAAqB;AAC3C,yBAAqB,OAAO,SAAS;AAAA,MACnC,GAAG;AAAA,MACH,QAAQ;AAAA,IACV,CAAC;AAED,QAAI,OAAO,SAAS,sBAAsB,UAAU;AAClD,eAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF,OAAO;AACL,eAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,OAAO,OAAO,YAAY;AAAA,EAClC,WAAW,SAAS,WAAW,wBAAwB;AACrD,yBAAqB,OAAO,SAAS;AAAA,MACnC,GAAG;AAAA,MACH,QAAQ;AAAA,IACV,CAAC;AAED,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA,SAAS;AAAA,IACX;AACA,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA,SAAS;AAAA,IACX;AACA,UAAM,OAAO,OAAO,YAAY;AAAA,EAClC;AACF;AAMO,SAAS,wBACd,OACA,SACA;AACA,QAAM,WAAW,MAAM,OAAO;AAC9B,MAAI,CAAC,SAAS,QAAQ,OAAO;AAAG;AAEhC,QAAM,WAAW,qBAAqB,OAAO,OAAO;AAEpD,MAAI,SAAS,WAAW,aAAa,SAAS,WAAW,QAAQ;AAC/D;AAAA,EACF;AAEA,QAAM,mBAAmB,SAAS;AAClC,QAAM,sBAAsB,SAAS;AAErC,QAAM,SAAS,aAAa,OAAO,SAAS,QAAQ;AACpD,MAAI,UAAU;AAAM;AAEpB,MAAI,qBAAqB;AACvB,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,aACP,OACA,SACA,UACoB;AACpB,MACE,CAAC,MAAM,OAAO,MAAM,QAAQ,OAAO,KACnC,CAAC,MAAM,OAAO,MAAM,QAAQ,OAAO,KACnC,YAAY,SAAS,SACrB;AACA,WAAO;AAAA,EACT;AACA,QAAM,SAAS,MAAM,OAAO,MAAM,QAAQ,OAAO;AACjD,MAAI,WAAW,SAAS,QAAQ;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;AE3RO,SAAS,mBAAmB,OAA0B;AAE3D,QAAM,GAAG,4BAA4B;AAAA,IACnC;AAAA,IACA,GAAG,MAAM,GAAG,4BAA4B;AAAA,EAC1C,CAAC;AACD,QAAM,GAAG;AAAA,IACP;AAAA,IACA,CAAC,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,MAAM;AACnC,UACE,CAAC,MAAM,QAAQ,mBAAmB,YAAY;AAAA,QAC5C;AAAA,MACF,CAAC,GACD;AACA;AAAA,MACF;AAEA,YAAM,CAAC,EAAE,IAAI,OAAO,MAAM,gBAAgB;AAE1C,YAAM,WAAW,qBAAqB,OAAO,EAAE;AAE/C,YAAM,WAAW,SAAS,WAAW;AACrC,YAAM,YAAY,SAAS,WAAW;AACtC,YAAM,aACJ,SAAS,WAAW,aAAa,SAAS,WAAW;AAEvD,UAAI;AACJ,UAAI,aAAa,SAAS,UAAU;AAClC,cAAM,EAAE,KAAK,SAAS,MAAM,IAAI,SAAS;AAEzC,YAAI,QAAQ,qBAAqB;AAC/B,4BAAkB;AAAA,QACpB,WAAW,IAAI,WAAW,gBAAgB,GAAG;AAC3C,4BAAmB,UAAU,QAAS;AAAA,QACxC,WAAW,IAAI,WAAW,yBAAyB,GAAG;AACpD,4BAAkB,KAAM,UAAU,QAAS;AAAA,QAC7C,OAAO;AACL,4BAAkB;AAAA,QACpB;AAAA,MACF;AAEA,aAAO,iCAAiC;AAAA,QACtC,OAAO;AAAA,QACP,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,MAAM;AACb,kBAAQ,SAAS,QAAQ;AAAA,YACvB,KAAK;AAAA,YACL,KAAK,SAAS;AACZ,mCAAqB,OAAO,IAAI;AAAA,gBAC9B,QAAQ;AAAA,cACV,CAAC;AACD;AAAA,YACF;AAAA,YAEA,KAAK;AAAA,YACL,KAAK,qBAAqB;AACxB,0CAA4B,OAAO,EAAE;AACrC;AAAA,YACF;AAAA,YAEA,SAAS;AAAA,YAET;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;ACjFO,SAAS,eAAe,OAA0B;AACvD,QAAM,QAAQ,gBAAgB,YAAY,CAAC,EAAE,OAAO,MAAM;AACxD,UAAM,cAAc,OAAO,MAAM,gBAAgB;AACjD,QAAI,YAAY,WAAW,GAAG;AAC5B,aAAO;AAAA,IACT;AACA,UAAM,CAAC,UAAU,IAAI;AAErB,QAAI,MAAM,OAAO,MAAM,QAAQ,UAAU,GAAG;AAC1C,YAAM,SAAS,MAAM,OAAO,MAAM,QAAQ,UAAU;AACpD,YAAM,WAAW,MAAM,OAAO,MAAM,QAAQ,MAAM;AAElD,UAAI,aAAa,2BAA2B;AAC1C,eAAO;AAAA,MACT;AAEA,YAAM,UAAU,OAAO,MAAM,UAAU,QAAQ,yBAAyB;AACxE,YAAM,YAAY,OAAO,MAAM;AAAA,QAC7B;AAAA,QACA;AAAA,MACF;AAEA,UAAI,UAAU,SAAS,KAAK,YAAY;AAAI,eAAO;AAKnD,YAAM,WAAW,qBAAqB,OAAO,UAAU;AACvD,aAAO,SAAS,WAAW;AAAA,IAC7B;AAEA,WAAO;AAAA,EACT,CAAC;AACH;;;ACvCA;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AAEP,OAAO,cAAc;AAYrB,eAAsB,yBACpB,OACA,SACA,eACA;AACA,QAAM,WAAW,MAAM,OAAO;AAC9B,MAAI,CAAC,SAAS,QAAQ,OAAO;AAC3B,UAAM,IAAI,MAAM,iDAAiD;AAEnE,QAAM,SAAS,SAAS,QAAQ,OAAO;AAGvC,QAAM,mBAAmB,SAAS;AAAA,IAChC;AAAA,IACA;AAAA,EACF;AACA,QAAM,sBAAsB,SAAS;AAAA,IACnC;AAAA,IACA;AAAA,EACF;AAEA,MAAI;AAEF,aAAS,UAAU,QAAQ,2BAA2B,EAAE;AACxD,aAAS,aAAa,QAAQ,wBAAwB,CAAC,CAAC;AAExD,UAAM,WAAW,qBAAqB,OAAO,OAAO;AACpD,yBAAqB,OAAO,SAAS;AAAA,MACnC,GAAG;AAAA,MACH,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAED,UAAM;AAAA;AAAA,MAEJ,iBAAiB,SAAS;AAAA;AAAA,QAEtB,iBAAiB;AAAA,UACf,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE;AAAA,QAC9C,EAAE,CAAC,EAAE;AAAA,UACL;AAAA;AAGN,UAAM,OAAO,MAAM,kBAAkB,cAAc,aAAa;AAEhE,QAAI,iBAAiB,SAAS,GAAG;AAG/B,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,YAAY;AAAM;AAEtB,UAAI,SAAS,MAAM,CAAC,QAAQ,OAAO,IAAI,GAAG;AACxC,cAAM,IAAI,MAAM,uCAAuC;AAAA,MACzD;AAEA,YAAM,eAAe,iBAAiB,IAAI,CAAC,QAAQ,UAAU;AAC3D,eAAO;AAAA,UACL,GAAG;AAAA,UACH,KAAK,SAAS,KAAK;AAAA,QACrB;AAAA,MACF,CAAC;AAED,2BAAqB,OAAO,SAAS;AAAA,QACnC,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,mBAAmB;AAAA,MACrB,CAAC;AACD,eAAS,aAAa,QAAQ,wBAAwB,YAAY;AAAA,IACpE,OAAO;AAGL,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA;AAAA,QACA,CAAC,EAAE,KAAK,aAAa,CAAC;AAAA,QACtB;AAAA,QACA;AAAA,MACF;AACA,UAAI,YAAY;AAAM;AAEtB,YAAM,cAAc,SAAS,CAAC;AAC9B,UAAI,eAAe,MAAM;AACvB,cAAM,IAAI,MAAM,mCAAmC;AAAA,MACrD;AAEA,2BAAqB,OAAO,SAAS;AAAA,QACnC,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,mBAAmB;AAAA,MACrB,CAAC;AACD,eAAS,UAAU,QAAQ,2BAA2B,WAAW;AAAA,IACnE;AAEA,UAAM,OAAO,OAAO,YAAY;AAAA,EAClC,SAAS,OAAO;AACd,QAAI,MAAM,OAAO,MAAM,QAAQ,OAAO,GAAG;AACvC,2BAAqB,OAAO,SAAS;AAAA,QACnC,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,MACV,CAAC;AAED,8BAAwB,OAAO,OAAO;AAAA,IACxC;AAEA,YAAQ,IAAI,KAAK;AAAA,EACnB;AACF;AAEA,eAAe,cACb,OACA,SACA,eACA,MACA,uBAC+B;AAC/B,QAAM,gBAAgB;AAAA,IACpB,GAAG;AAAA,IACH,UAAU,SAAS,CAAC,KAAK,SAAS,UAAU;AAC1C,YAAM,yBAAyB,qBAAqB,OAAO,OAAO;AAClE,UACE,uBAAuB,WAAW,gBAClC,CAAC,qBAAqB,OAAO,OAAO;AAEpC;AACF,4BAAsB,WAAW,KAAK,SAAS,KAAK;AACpD,2BAAqB,OAAO,SAAS;AAAA,QACnC,GAAG;AAAA,QACH,UAAU,EAAE,KAAK,SAAS,MAAM;AAAA,MAClC,CAAC;AAAA,IACH,GAAG,GAAG;AAAA,EACR;AAEA,QAAM,SAAS,MAAM,QAAQ;AAAA,IAC3B,cAAc,IAAI,OAAO,WAA+B;AAEtD,YAAM,OAAO,MAAM,sBAAsB,OAAO,KAAK,MAAM,aAAa;AACxE,aAAO,CAAC,MAAM,MAAM;AAAA,IACtB,CAAC;AAAA,EACH;AAIA,MACE,qBAAqB,OAAO,OAAO,EAAE,WAAW,gBAChD,CAAC,qBAAqB,OAAO,OAAO;AAEpC;AAEF,QAAM,WAAW,MAAM,QAAQ;AAAA,IAC7B,OAAO,IAAI,OAAO,CAAC,MAAM,MAAM,MAA4B;AACzD,YAAM,WAAW,IAAI,IAAI,OAAO,GAAG,EAAE;AACrC,YAAM,QAAQ,SAAS,MAAM,GAAG;AAChC,YAAM,WAAW,MAAM,MAAM,SAAS,CAAC;AAEvC,YAAM,iBAAiB,MAAM,MAAM;AAAA,QACjC,IAAI,KAAK,CAAC,IAAI,GAAG,UAAU,EAAE,MAAM,KAAK,KAAK,CAAC;AAAA,QAC9C,MAAM;AAAA,QAEN;AAAA,MACF;AAEA,YAAM,MAAM,eAAe,MAAM;AACjC,UAAI,OAAO,MAAM;AACf,cAAM,IAAI,MAAM,mCAAmC;AAAA,MACrD;AACA,aAAO,CAAC,KAAK,MAAM;AAAA,IACrB,CAAC;AAAA,EACH;AAIA,MACE,qBAAqB,OAAO,OAAO,EAAE,WAAW,gBAChD,CAAC,qBAAqB,OAAO,OAAO;AAEpC;AAEF,SAAO,SAAS,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG;AACpC;;;ACzMA,IAAO,iBAAQ,CAAC,sBAA2C,CAAC,MAAM;AAChE,QAAM,iCACJ,qBAAqB,qBAAqB,CAAC;AAE7C,SAAO;AAAA,IACL,aAAa;AAAA,IAAC;AAAA,IAEd,SAAS;AAAA,IAAC;AAAA,IAEV,wBAAwB,EAAE,MAAM,GAAiC;AAC/D,YAAM,OAAO,MAAM,UAAU,CAAC,GAAG,OAAO,WAAW;AACjD,eAAO,QAAQ,CAAC,MAAM;AACpB,gBAAM,KAAK,EAAE;AACb,cACE,CAAC,MAAM,OAAO,MAAM,QAAQ,EAAE,KAC9B,CAAC,MAAM,OAAO,MAAM,YAAY,IAAI,aAAa,GACjD;AACA;AAAA,UACF;AAEA,cAAI,EAAE,SAAS,WAAW;AACxB,kBAAM,WAAW,qBAAqB,OAAO,EAAE;AAC/C,gBAAI,YAAY,OAAO,IAAI,QAAQ,GAAG;AACpC,mCAAqB,OAAO,EAAE;AAAA,YAChC;AAAA,UACF,WAAW,EAAE,SAAS,WAAW;AAC/B,8BAAkB,OAAO,IAAI,8BAA8B;AAAA,UAC7D;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAED,yBAAmB,KAAK;AACxB,qBAAe,KAAK;AAAA,IACtB;AAAA,EACF;AACF;AAMA,eAAe,kBACb,OACA,SACA,eACA;AACA,QAAM,WAAW,qBAAqB,OAAO,OAAO;AAEpD,UAAQ,SAAS,QAAQ;AAAA,IACvB,KAAK,WAAW;AACd,UACE,MAAM,QAAQ,mBAAmB,YAAY;AAAA,QAC3C,QAAQ,MAAM;AAAA,MAChB,CAAC,GACD;AACA,iCAAyB,OAAO,SAAS,aAAa;AAAA,MACxD;AACA;AAAA,IACF;AAAA,IAEA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,wBAAwB;AAC3B,UAAI,CAAC,qBAAqB,OAAO,OAAO,GAAG;AACzC,+BAAuB,OAAO,OAAO;AAAA,MACvC;AACA;AAAA,IACF;AAAA,IAEA,SAAS;AAAA,IAET;AAAA,EACF;AACF;;;ACxFA,IAAM,SAAS,CAAC,yBAA+C;AAAA,EAC7D,MAAM;AAAA,EACN,SAAS;AAAA,EACT,GAAG,eAAO,mBAAmB;AAC/B;AAEA,IAAO,cAAQ;",
6
- "names": []
3
+ "sources": ["../src/constants.ts", "../src/utils.ts", "../src/enableFeatures.ts", "../src/processBackgroundRemoval.ts", "../src/registerComponents.ts", "../src/plugin.ts", "../src/index.ts"],
4
+ "sourcesContent": ["export const PLUGIN_ID = '@imgly/plugin-background-removal-web';\nexport const CANVAS_MENU_COMPONENT_ID = `${PLUGIN_ID}.canvasMenu`;\nexport const CANVAS_MENU_COMPONENT_BUTTON_ID = `${CANVAS_MENU_COMPONENT_ID}.button`;\nexport const FEATURE_ID = `${PLUGIN_ID}.feature`;\n", "import type CreativeEditorSDK from '@cesdk/cesdk-js';\nimport isEqual from 'lodash/isEqual';\n\nimport { PLUGIN_ID } from './constants';\nimport {\n PluginStatusError,\n PluginStatusMetadata,\n PluginStatusProcessed,\n PluginStatusProcessing\n} from './types';\n\n/**\n * Sets the metadata for the plugin state.\n */\nexport function setPluginMetadata(\n cesdk: CreativeEditorSDK,\n id: number,\n metadata: PluginStatusMetadata\n) {\n cesdk.engine.block.setMetadata(id, PLUGIN_ID, JSON.stringify(metadata));\n}\n\n/**\n * Returns the current metadata for the plugin state. If no metadata\n * is set on the given block, it will return an IDLE state.\n */\nexport function getPluginMetadata(\n cesdk: CreativeEditorSDK,\n id: number\n): PluginStatusMetadata {\n if (cesdk.engine.block.hasMetadata(id, PLUGIN_ID)) {\n return JSON.parse(cesdk.engine.block.getMetadata(id, PLUGIN_ID));\n } else {\n return {\n status: 'IDLE'\n };\n }\n}\n\n/**\n * If plugin metadata is set, it will be cleared.\n */\nexport function clearPluginMetadata(cesdk: CreativeEditorSDK, id: number) {\n if (cesdk.engine.block.hasMetadata(id, PLUGIN_ID)) {\n cesdk.engine.block.removeMetadata(id, PLUGIN_ID);\n }\n}\n\n/**\n * Detect if the block has been duplicated with processed or processing\n * background removal. In that case the background removal state is still\n * valid, but blockId and fillId have changed.\n */\nexport function isDuplicate(\n cesdk: CreativeEditorSDK,\n blockId: number,\n metadata: PluginStatusMetadata\n): boolean {\n if (!cesdk.engine.block.isValid(blockId)) return false;\n if (\n metadata.status === 'IDLE' ||\n metadata.status === 'PENDING' ||\n metadata.status === 'ERROR'\n )\n return false;\n\n if (!cesdk.engine.block.hasFill(blockId)) return false;\n const fillId = cesdk.engine.block.getFill(blockId);\n\n // It cannot be a duplicate if the blockId or fillId are the same\n if (metadata.blockId === blockId || metadata.fillId === fillId) return false;\n\n return true;\n}\n\n/**\n * Fixes the metadata if the block has been duplicated, i.e. the blockId and\n * fillId will be updated to the current block/fill.\n *\n * Please note: Call this method only on duplicates (see isDuplicate).\n */\nexport function fixDuplicateMetadata(\n cesdk: CreativeEditorSDK,\n blockId: number\n) {\n const fillId = cesdk.engine.block.getFill(blockId);\n const metadata = getPluginMetadata(cesdk, blockId);\n if (\n metadata.status === 'IDLE' ||\n metadata.status === 'PENDING' ||\n metadata.status === 'ERROR'\n )\n return;\n setPluginMetadata(cesdk, blockId, {\n ...metadata,\n blockId,\n fillId\n });\n}\n\n/**\n * Check if the image has a consisten metadata state. A inconsistent state is\n * caused by outside changes of the fill data.\n *\n * @returns true if the metadata is consistent, false otherwise\n */\nexport function isMetadataConsistent(\n cesdk: CreativeEditorSDK,\n blockId: number\n): boolean {\n // In case the block was removed, we just abort and mark it\n // as reset by returning true\n if (!cesdk.engine.block.isValid(blockId)) return false;\n const metadata = getPluginMetadata(cesdk, blockId);\n if (metadata.status === 'IDLE' || metadata.status === 'PENDING') return true;\n\n if (!cesdk.engine.block.hasFill(blockId)) return false;\n const fillId = cesdk.engine.block.getFill(blockId);\n if (fillId == null) return false;\n\n if (blockId !== metadata.blockId || fillId !== metadata.fillId) return false;\n\n const sourceSet = cesdk.engine.block.getSourceSet(\n fillId,\n 'fill/image/sourceSet'\n );\n const imageFileURI = cesdk.engine.block.getString(\n fillId,\n 'fill/image/imageFileURI'\n );\n\n if (\n sourceSet.length === 0 &&\n !imageFileURI &&\n metadata.status === 'PROCESSING'\n ) {\n // While we process it is OK to have no image file URI and no source set\n // (which we cleared to show the spinning loader)\n return true;\n }\n\n // Source sets have precedence over imageFileURI so if we have a source set,\n // we only need to check if it has changed to something else.\n if (sourceSet?.length > 0) {\n const initialSourceSet = metadata.initialSourceSet;\n // If we have already processed the image, we need to check if the source set\n // we need to check against both source sets, the removed and the initial\n if (metadata.status === 'PROCESSED') {\n const removedBackground = metadata.removedBackground;\n if (\n !isEqual(sourceSet, removedBackground) &&\n !isEqual(sourceSet, initialSourceSet)\n ) {\n return false;\n }\n } else {\n if (!isEqual(sourceSet, initialSourceSet)) {\n return false;\n }\n }\n } else {\n if (metadata.status === 'PROCESSED') {\n if (\n imageFileURI !== metadata.initialImageFileURI &&\n imageFileURI !== metadata.removedBackground\n ) {\n return false;\n }\n } else {\n if (imageFileURI !== metadata.initialImageFileURI) {\n return false;\n }\n }\n }\n return true;\n}\n\n/**\n * Recover the initial values to avoid the loading spinner and have the same\n * state as before the background removal was started.\n */\nexport function recoverInitialImageData(\n cesdk: CreativeEditorSDK,\n blockId: number\n) {\n const blockApi = cesdk.engine.block;\n if (!blockApi.hasFill(blockId)) return; // Nothing to recover (no fill anymore)\n\n const metadata = getPluginMetadata(cesdk, blockId);\n\n if (metadata.status === 'PENDING' || metadata.status === 'IDLE') {\n return;\n }\n\n const initialSourceSet = metadata.initialSourceSet;\n const initialImageFileURI = metadata.initialImageFileURI;\n const initialPreviewFileURI = metadata.initialPreviewFileURI;\n\n const fillId = getValidFill(cesdk, blockId, metadata);\n if (fillId == null) return;\n\n if (initialImageFileURI) {\n cesdk.engine.block.setString(\n fillId,\n 'fill/image/imageFileURI',\n initialImageFileURI\n );\n }\n if (initialPreviewFileURI) {\n cesdk.engine.block.setString(\n fillId,\n 'fill/image/previewFileURI',\n initialPreviewFileURI\n );\n }\n if (initialSourceSet.length > 0) {\n cesdk.engine.block.setSourceSet(\n fillId,\n 'fill/image/sourceSet',\n initialSourceSet\n );\n }\n}\n\n/**\n * Returns the fill id of the block if it has a valid fill that was used for\n * background removal. Returns undefined otherwise.\n */\nfunction getValidFill(\n cesdk: CreativeEditorSDK,\n blockId: number,\n metadata: PluginStatusProcessing | PluginStatusError | PluginStatusProcessed\n): number | undefined {\n if (\n !cesdk.engine.block.isValid(blockId) ||\n !cesdk.engine.block.hasFill(blockId) ||\n blockId !== metadata.blockId\n ) {\n return undefined;\n }\n const fillId = cesdk.engine.block.getFill(blockId);\n if (fillId !== metadata.fillId) {\n return undefined;\n }\n\n return fillId;\n}\n", "import type CreativeEditorSDK from '@cesdk/cesdk-js';\nimport { FEATURE_ID } from './constants';\nimport { getPluginMetadata } from './utils';\n\n/**\n * Defines the feature that determines in which context (on which block)\n * background removal is allowed/enabled.\n */\nexport function enableFeatures(cesdk: CreativeEditorSDK) {\n cesdk.feature.unstable_enable(FEATURE_ID, ({ engine }) => {\n const selectedIds = engine.block.findAllSelected();\n if (selectedIds.length !== 1) {\n return false;\n }\n const [selectedId] = selectedIds;\n\n if (cesdk.engine.block.hasFill(selectedId)) {\n const fillId = cesdk.engine.block.getFill(selectedId);\n const fillType = cesdk.engine.block.getType(fillId);\n\n if (fillType !== '//ly.img.ubq/fill/image') {\n return false;\n }\n\n const fileUri = engine.block.getString(fillId, 'fill/image/imageFileURI');\n const sourceSet = engine.block.getSourceSet(\n fillId,\n 'fill/image/sourceSet'\n );\n\n if (sourceSet.length > 0 || fileUri !== '') return true;\n\n // If we are in a processing state we do not have a imageFileURI or\n // source set set (to show the loading spinner), but the feature is still\n // enabled.\n const metadata = getPluginMetadata(cesdk, selectedId);\n return metadata.status === 'PROCESSING';\n }\n\n return false;\n });\n}\n", "import type CreativeEditorSDK from '@cesdk/cesdk-js';\nimport { type Source } from '@cesdk/cesdk-js';\nimport {\n applySegmentationMask,\n segmentForeground,\n type Config\n} from '@imgly/background-removal';\n\nimport throttle from 'lodash/throttle';\n\nimport {\n getPluginMetadata,\n isMetadataConsistent,\n recoverInitialImageData,\n setPluginMetadata\n} from './utils';\n\n/**\n * Triggers the background removal process.\n */\nexport async function processBackgroundRemoval(\n cesdk: CreativeEditorSDK,\n blockId: number,\n configuration: Config\n) {\n const blockApi = cesdk.engine.block;\n if (!blockApi.hasFill(blockId))\n throw new Error('Block has no fill to remove the background from');\n\n const fillId = blockApi.getFill(blockId);\n\n // Get the current image URI and source set as initial values.\n const initialSourceSet = blockApi.getSourceSet(\n fillId,\n 'fill/image/sourceSet'\n );\n const initialImageFileURI = blockApi.getString(\n fillId,\n 'fill/image/imageFileURI'\n );\n const initialPreviewFileURI = blockApi.getString(\n fillId,\n 'fill/image/previewFileURI'\n );\n\n try {\n // Clear values in the engine to trigger the loading spinner\n blockApi.setString(fillId, 'fill/image/imageFileURI', '');\n blockApi.setSourceSet(fillId, 'fill/image/sourceSet', []);\n\n const metadata = getPluginMetadata(cesdk, blockId);\n setPluginMetadata(cesdk, blockId, {\n ...metadata,\n version: PLUGIN_VERSION,\n initialSourceSet,\n initialImageFileURI,\n initialPreviewFileURI,\n blockId,\n fillId,\n status: 'PROCESSING'\n });\n\n const uriToProcess =\n // Source sets have priority in the engine\n initialSourceSet.length > 0\n ? // Choose the highest resolution image in the source set\n initialSourceSet.sort(\n (a, b) => b.width * b.height - a.height * a.width\n )[0].uri\n : initialImageFileURI;\n\n // If there is no initial preview file URI, set the current URI.\n // It will be used as the image displayed while showing the loading spinner.\n if (!initialPreviewFileURI) {\n blockApi.setString(fillId, 'fill/image/previewFileURI', uriToProcess);\n }\n\n // Creating the mask from the highest resolution image\n const mask = await segmentForeground(uriToProcess, configuration);\n\n if (initialSourceSet.length > 0) {\n // Source set code path\n // ====================\n const uploaded = await maskSourceSet<Source>(\n cesdk,\n blockId,\n initialSourceSet,\n mask,\n configuration\n );\n if (uploaded == null) return;\n\n if (uploaded.every((url) => url == null)) {\n throw new Error('Could not upload any BG removed image');\n }\n\n const newSourceSet = initialSourceSet.map((source, index) => {\n return {\n ...source,\n uri: uploaded[index]\n };\n });\n\n setPluginMetadata(cesdk, blockId, {\n version: PLUGIN_VERSION,\n initialSourceSet,\n initialImageFileURI,\n initialPreviewFileURI,\n blockId,\n fillId,\n status: 'PROCESSED',\n removedBackground: newSourceSet\n });\n blockApi.setSourceSet(fillId, 'fill/image/sourceSet', newSourceSet);\n // TODO: Generate a thumb/preview uri\n blockApi.setString(fillId, 'fill/image/previewFileURI', '');\n } else {\n // ImageFileURI code path\n // ======================\n const uploaded = await maskSourceSet<{ uri: string }>(\n cesdk,\n blockId,\n [{ uri: uriToProcess }],\n mask,\n configuration\n );\n if (uploaded == null) return;\n\n const uploadedUrl = uploaded[0];\n if (uploadedUrl == null) {\n throw new Error('Could not upload BG removed image');\n }\n\n setPluginMetadata(cesdk, blockId, {\n version: PLUGIN_VERSION,\n initialSourceSet,\n initialImageFileURI,\n initialPreviewFileURI,\n blockId,\n fillId,\n status: 'PROCESSED',\n removedBackground: uploadedUrl\n });\n blockApi.setString(fillId, 'fill/image/imageFileURI', uploadedUrl);\n // TODO: Generate a thumb/preview uri\n blockApi.setString(fillId, 'fill/image/previewFileURI', '');\n }\n // Finally, create an undo step\n cesdk.engine.editor.addUndoStep();\n } catch (error) {\n if (cesdk.engine.block.isValid(blockId)) {\n setPluginMetadata(cesdk, blockId, {\n version: PLUGIN_VERSION,\n initialSourceSet,\n initialImageFileURI,\n initialPreviewFileURI,\n blockId,\n fillId,\n status: 'ERROR'\n });\n\n recoverInitialImageData(cesdk, blockId);\n }\n // eslint-disable-next-line no-console\n console.log(error);\n }\n}\n\nasync function maskSourceSet<T extends { uri: string }>(\n cesdk: CreativeEditorSDK,\n blockId: number,\n urisOrSources: T[],\n mask: Blob,\n configurationFromArgs: Config\n): Promise<string[] | undefined> {\n const configuration = {\n ...configurationFromArgs,\n progress: throttle((key, current, total) => {\n const metadataDuringProgress = getPluginMetadata(cesdk, blockId);\n if (\n metadataDuringProgress.status !== 'PROCESSING' ||\n !isMetadataConsistent(cesdk, blockId)\n )\n return;\n configurationFromArgs.progress?.(key, current, total);\n setPluginMetadata(cesdk, blockId, {\n ...metadataDuringProgress,\n progress: { key, current, total }\n });\n }, 100)\n };\n\n const masked = await Promise.all(\n urisOrSources.map(async (source): Promise<[Blob, T]> => {\n // Applying the mask to the original image\n const blob = await applySegmentationMask(source.uri, mask, configuration);\n return [blob, source];\n })\n );\n\n // Check for externally changed state while we were applying the mask and\n // do not proceed if the state was reset.\n if (\n getPluginMetadata(cesdk, blockId).status !== 'PROCESSING' ||\n !isMetadataConsistent(cesdk, blockId)\n )\n return;\n\n const uploaded = await Promise.all(\n masked.map(async ([blob, source]): Promise<[string, T]> => {\n const pathname = new URL(source.uri).pathname;\n const parts = pathname.split('/');\n const filename = parts[parts.length - 1];\n\n const uploadedAssets = await cesdk.unstable_upload(\n new File([blob], filename, { type: blob.type }),\n () => {\n // TODO Delegate process to UI component\n }\n );\n\n const url = uploadedAssets.meta?.uri;\n if (url == null) {\n throw new Error('Could not upload BG removed image');\n }\n return [url, source];\n })\n );\n\n // Check for externally changed state while we were uploading and\n // do not proceed if the state was reset.\n if (\n getPluginMetadata(cesdk, blockId).status !== 'PROCESSING' ||\n !isMetadataConsistent(cesdk, blockId)\n )\n return;\n\n return uploaded.map(([url]) => url);\n}\n", "import type CreativeEditorSDK from '@cesdk/cesdk-js';\n\nimport {\n CANVAS_MENU_COMPONENT_BUTTON_ID,\n CANVAS_MENU_COMPONENT_ID,\n FEATURE_ID,\n PLUGIN_ID\n} from './constants';\nimport { Location, UserInterfaceConfiguration } from './types';\nimport { getPluginMetadata, setPluginMetadata } from './utils';\n\nconst REMOVE_BACKGROUND_ACTION_I18N_KEY = `plugin.${PLUGIN_ID}.action.removeBackground`;\n\n/**\n * Registers the components that can be used to remove the background of\n * a block.\n */\nexport function registerComponents(\n cesdk: CreativeEditorSDK,\n configuration: UserInterfaceConfiguration = {}\n) {\n if (hasDefaultLocation('canvasMenu', configuration)) {\n // Always prepend the registered component to the canvas menu order.\n cesdk.ui.unstable_setCanvasMenuOrder([\n CANVAS_MENU_COMPONENT_ID,\n ...cesdk.ui.unstable_getCanvasMenuOrder()\n ]);\n }\n\n cesdk.setTranslations({\n en: {\n [REMOVE_BACKGROUND_ACTION_I18N_KEY]: 'BG Removal'\n }\n });\n\n cesdk.ui.unstable_registerComponent(\n CANVAS_MENU_COMPONENT_ID,\n ({ builder: { Button }, engine }) => {\n if (\n !cesdk.feature.unstable_isEnabled(FEATURE_ID, {\n engine\n })\n ) {\n return;\n }\n\n const [id] = engine.block.findAllSelected();\n\n const metadata = getPluginMetadata(cesdk, id);\n\n const isLoading = metadata.status === 'PROCESSING';\n const isDisabled =\n metadata.status === 'PENDING' || metadata.status === 'PROCESSING';\n\n let loadingProgress: number | undefined;\n if (isLoading && metadata.progress) {\n const { key, current, total } = metadata.progress;\n\n if (key === 'compute:inference') {\n loadingProgress = undefined;\n } else if (key.startsWith('fetch:/models/')) {\n loadingProgress = (current / total) * 50;\n } else if (key.startsWith('fetch:/onnxruntime-web/')) {\n loadingProgress = 50 + (current / total) * 50;\n } else {\n loadingProgress = undefined;\n }\n }\n\n Button(CANVAS_MENU_COMPONENT_BUTTON_ID, {\n label: REMOVE_BACKGROUND_ACTION_I18N_KEY,\n icon: '@imgly/icons/BGRemove',\n isLoading,\n isDisabled,\n loadingProgress,\n onClick: () => {\n if (\n metadata.status === 'IDLE' ||\n metadata.status === 'ERROR' ||\n metadata.status === 'PROCESSED'\n ) {\n setPluginMetadata(cesdk, id, {\n status: 'PENDING'\n });\n }\n }\n });\n }\n );\n}\n\nfunction hasDefaultLocation(\n location: Location,\n configuration: UserInterfaceConfiguration\n) {\n return (\n configuration.locations &&\n (Array.isArray(configuration.locations)\n ? configuration.locations\n : [configuration.locations]\n ).includes(location)\n );\n}\n", "import type CreativeEditorSDK from '@cesdk/cesdk-js';\n\nimport type { Config as BackgroundRemovalConfiguration } from '@imgly/background-removal';\nimport { FEATURE_ID, PLUGIN_ID } from './constants';\nimport { enableFeatures } from './enableFeatures';\nimport { processBackgroundRemoval } from './processBackgroundRemoval';\nimport { registerComponents } from './registerComponents';\nimport { UserInterfaceConfiguration } from './types';\nimport {\n clearPluginMetadata,\n fixDuplicateMetadata,\n getPluginMetadata,\n isDuplicate,\n isMetadataConsistent\n} from './utils';\n\nexport interface PluginConfiguration {\n ui?: UserInterfaceConfiguration;\n backgroundRemoval?: BackgroundRemovalConfiguration;\n}\n\nexport default (pluginConfiguration: PluginConfiguration = {}) => {\n const backgroundRemovalConfiguration: BackgroundRemovalConfiguration =\n pluginConfiguration?.backgroundRemoval ?? {};\n\n return {\n initialize() {},\n\n update() {},\n\n initializeUserInterface({ cesdk }: { cesdk: CreativeEditorSDK }) {\n cesdk.engine.event.subscribe([], async (events) => {\n events.forEach((e) => {\n const id = e.block;\n if (\n !cesdk.engine.block.isValid(id) ||\n !cesdk.engine.block.hasMetadata(id, PLUGIN_ID)\n ) {\n return;\n }\n\n if (e.type === 'Created') {\n const metadata = getPluginMetadata(cesdk, id);\n if (isDuplicate(cesdk, id, metadata)) {\n fixDuplicateMetadata(cesdk, id);\n }\n } else if (e.type === 'Updated') {\n handleUpdateEvent(cesdk, id, backgroundRemovalConfiguration);\n }\n });\n });\n\n registerComponents(cesdk, pluginConfiguration.ui);\n enableFeatures(cesdk);\n }\n };\n};\n\n/**\n * Handle every possible state of the background removal state if the block was\n * updated.\n */\nasync function handleUpdateEvent(\n cesdk: CreativeEditorSDK,\n blockId: number,\n configuration: BackgroundRemovalConfiguration\n) {\n const metadata = getPluginMetadata(cesdk, blockId);\n\n switch (metadata.status) {\n case 'PENDING': {\n if (\n cesdk.feature.unstable_isEnabled(FEATURE_ID, {\n engine: cesdk.engine\n })\n ) {\n processBackgroundRemoval(cesdk, blockId, configuration);\n }\n break;\n }\n\n case 'PROCESSING':\n case 'PROCESSED': {\n if (!isMetadataConsistent(cesdk, blockId)) {\n clearPluginMetadata(cesdk, blockId);\n }\n break;\n }\n\n default: {\n // We do not care about other states\n }\n }\n}\n", "import plugin, { type PluginConfiguration } from './plugin';\n\nimport { PLUGIN_ID } from './constants';\n\nconst Plugin = (pluginConfiguration?: PluginConfiguration) => ({\n name: PLUGIN_ID,\n version: PLUGIN_VERSION,\n ...plugin(pluginConfiguration)\n});\n\nexport default Plugin;\n"],
5
+ "mappings": "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",
6
+ "names": ["PLUGIN_ID", "CANVAS_MENU_COMPONENT_ID", "CANVAS_MENU_COMPONENT_BUTTON_ID", "FEATURE_ID", "isEqual", "setPluginMetadata", "cesdk", "id", "metadata", "PLUGIN_ID", "getPluginMetadata", "clearPluginMetadata", "isDuplicate", "blockId", "fillId", "fixDuplicateMetadata", "isMetadataConsistent", "sourceSet", "imageFileURI", "initialSourceSet", "removedBackground", "isEqual", "recoverInitialImageData", "initialImageFileURI", "initialPreviewFileURI", "getValidFill", "enableFeatures", "cesdk", "FEATURE_ID", "engine", "selectedIds", "selectedId", "fillId", "fileUri", "getPluginMetadata", "applySegmentationMask", "segmentForeground", "throttle", "processBackgroundRemoval", "cesdk", "blockId", "configuration", "blockApi", "fillId", "initialSourceSet", "initialImageFileURI", "initialPreviewFileURI", "metadata", "getPluginMetadata", "setPluginMetadata", "uriToProcess", "a", "b", "mask", "segmentForeground", "uploaded", "maskSourceSet", "url", "newSourceSet", "source", "index", "uploadedUrl", "error", "recoverInitialImageData", "urisOrSources", "configurationFromArgs", "throttle", "key", "current", "total", "metadataDuringProgress", "isMetadataConsistent", "masked", "applySegmentationMask", "blob", "parts", "filename", "REMOVE_BACKGROUND_ACTION_I18N_KEY", "PLUGIN_ID", "registerComponents", "cesdk", "configuration", "hasDefaultLocation", "CANVAS_MENU_COMPONENT_ID", "Button", "engine", "FEATURE_ID", "id", "metadata", "getPluginMetadata", "isLoading", "isDisabled", "loadingProgress", "key", "current", "total", "CANVAS_MENU_COMPONENT_BUTTON_ID", "setPluginMetadata", "location", "plugin_default", "pluginConfiguration", "backgroundRemovalConfiguration", "cesdk", "events", "e", "id", "PLUGIN_ID", "metadata", "getPluginMetadata", "isDuplicate", "fixDuplicateMetadata", "handleUpdateEvent", "registerComponents", "enableFeatures", "blockId", "configuration", "FEATURE_ID", "processBackgroundRemoval", "isMetadataConsistent", "clearPluginMetadata", "Plugin", "pluginConfiguration", "PLUGIN_ID", "plugin_default", "src_default"]
7
7
  }
package/dist/plugin.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import type CreativeEditorSDK from '@cesdk/cesdk-js';
2
2
  import type { Config as BackgroundRemovalConfiguration } from '@imgly/background-removal';
3
+ import { UserInterfaceConfiguration } from './types';
3
4
  export interface PluginConfiguration {
5
+ ui?: UserInterfaceConfiguration;
4
6
  backgroundRemoval?: BackgroundRemovalConfiguration;
5
7
  }
6
8
  declare const _default: (pluginConfiguration?: PluginConfiguration) => {
@@ -1,6 +1,7 @@
1
1
  import type CreativeEditorSDK from '@cesdk/cesdk-js';
2
+ import { UserInterfaceConfiguration } from './types';
2
3
  /**
3
4
  * Registers the components that can be used to remove the background of
4
5
  * a block.
5
6
  */
6
- export declare function registerComponents(cesdk: CreativeEditorSDK): void;
7
+ export declare function registerComponents(cesdk: CreativeEditorSDK, configuration?: UserInterfaceConfiguration): void;
package/dist/types.d.ts CHANGED
@@ -1,15 +1,16 @@
1
1
  import { type Source } from '@cesdk/cesdk-js';
2
- export type BGRemovalIdle = {
2
+ export type PluginStatusIdle = {
3
3
  status: 'IDLE';
4
4
  };
5
- export type BGRemovalPending = {
5
+ export type PluginStatusPending = {
6
6
  status: 'PENDING';
7
7
  };
8
- export type BGRemovalProcessing = {
8
+ export type PluginStatusProcessing = {
9
9
  version: string;
10
10
  status: 'PROCESSING';
11
11
  initialImageFileURI: string;
12
12
  initialSourceSet: Source[];
13
+ initialPreviewFileURI: string;
13
14
  blockId: number;
14
15
  fillId: number;
15
16
  progress?: {
@@ -18,21 +19,27 @@ export type BGRemovalProcessing = {
18
19
  total: number;
19
20
  };
20
21
  };
21
- export type BGRemovalProcessed = {
22
+ export type PluginStatusProcessed = {
22
23
  version: string;
23
- status: 'PROCESSED_WITH_BG' | 'PROCESSED_WITHOUT_BG';
24
+ status: 'PROCESSED';
24
25
  initialImageFileURI: string;
25
26
  initialSourceSet: Source[];
27
+ initialPreviewFileURI: string;
26
28
  blockId: number;
27
29
  fillId: number;
28
30
  removedBackground: string | Source[];
29
31
  };
30
- export type BGRemovalError = {
32
+ export type PluginStatusError = {
31
33
  version: string;
32
34
  status: 'ERROR';
33
35
  initialImageFileURI: string;
34
36
  initialSourceSet: Source[];
37
+ initialPreviewFileURI: string;
35
38
  blockId: number;
36
39
  fillId: number;
37
40
  };
38
- export type BGRemovalMetadata = BGRemovalIdle | BGRemovalError | BGRemovalPending | BGRemovalProcessing | BGRemovalProcessed;
41
+ export type PluginStatusMetadata = PluginStatusIdle | PluginStatusError | PluginStatusPending | PluginStatusProcessing | PluginStatusProcessed;
42
+ export type Location = 'canvasMenu';
43
+ export interface UserInterfaceConfiguration {
44
+ locations?: Location | Location[];
45
+ }
package/dist/utils.d.ts CHANGED
@@ -1,24 +1,24 @@
1
1
  import type CreativeEditorSDK from '@cesdk/cesdk-js';
2
- import { BGRemovalMetadata } from './types';
2
+ import { PluginStatusMetadata } from './types';
3
3
  /**
4
- * Sets the metadata for the background removal state.
4
+ * Sets the metadata for the plugin state.
5
5
  */
6
- export declare function setBGRemovalMetadata(cesdk: CreativeEditorSDK, id: number, metadata: BGRemovalMetadata): void;
6
+ export declare function setPluginMetadata(cesdk: CreativeEditorSDK, id: number, metadata: PluginStatusMetadata): void;
7
7
  /**
8
- * Returns the current metadata for the background removal state. If no metadata
8
+ * Returns the current metadata for the plugin state. If no metadata
9
9
  * is set on the given block, it will return an IDLE state.
10
10
  */
11
- export declare function getBGRemovalMetadata(cesdk: CreativeEditorSDK, id: number): BGRemovalMetadata;
11
+ export declare function getPluginMetadata(cesdk: CreativeEditorSDK, id: number): PluginStatusMetadata;
12
12
  /**
13
- * If BG Removal metadata is set, it will be cleared.
13
+ * If plugin metadata is set, it will be cleared.
14
14
  */
15
- export declare function clearBGRemovalMetadata(cesdk: CreativeEditorSDK, id: number): void;
15
+ export declare function clearPluginMetadata(cesdk: CreativeEditorSDK, id: number): void;
16
16
  /**
17
17
  * Detect if the block has been duplicated with processed or processing
18
18
  * background removal. In that case the background removal state is still
19
19
  * valid, but blockId and fillId have changed.
20
20
  */
21
- export declare function isDuplicate(cesdk: CreativeEditorSDK, blockId: number, metadata: BGRemovalMetadata): boolean;
21
+ export declare function isDuplicate(cesdk: CreativeEditorSDK, blockId: number, metadata: PluginStatusMetadata): boolean;
22
22
  /**
23
23
  * Fixes the metadata if the block has been duplicated, i.e. the blockId and
24
24
  * fillId will be updated to the current block/fill.
@@ -33,12 +33,6 @@ export declare function fixDuplicateMetadata(cesdk: CreativeEditorSDK, blockId:
33
33
  * @returns true if the metadata is consistent, false otherwise
34
34
  */
35
35
  export declare function isMetadataConsistent(cesdk: CreativeEditorSDK, blockId: number): boolean;
36
- /**
37
- * Toggle between the background removed image and the original image if either
38
- * in the state "PROCESSED_WITH_BG" or "PROCESSED_WITHOUT_BG". Otherwise do
39
- * nothing.
40
- */
41
- export declare function toggleBackgroundRemovalData(cesdk: CreativeEditorSDK, blockId: number): void;
42
36
  /**
43
37
  * Recover the initial values to avoid the loading spinner and have the same
44
38
  * state as before the background removal was started.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imgly/plugin-background-removal-web",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Background Removal plugin for the CE.SDK editor",
5
5
  "keywords": [
6
6
  "CE.SDK",
@@ -46,7 +46,8 @@
46
46
  "start": "npm run watch",
47
47
  "clean": "npx rimraf dist",
48
48
  "build": "npm run clean && node scripts/build.mjs && yarn run types:create",
49
- "watch": "npm run clean && node scripts/watch.mjs",
49
+ "dev": "npm run clean && node scripts/watch.mjs",
50
+ "dev:types": "tsc --emitDeclarationOnly --watch --preserveWatchOutput",
50
51
  "publish:latest": "npm run build && npm publish --tag latest --access public",
51
52
  "publish:next": "npm run build && npm publish --tag next --access public",
52
53
  "check:all": "concurrently -n lint,type,pretty \"yarn check:lint\" \"yarn check:type\" \"yarn check:pretty\"",
@@ -56,7 +57,7 @@
56
57
  "types:create": "tsc --emitDeclarationOnly"
57
58
  },
58
59
  "devDependencies": {
59
- "@cesdk/cesdk-js": "~1.20.0",
60
+ "@cesdk/cesdk-js": "~1.21.0",
60
61
  "@types/ndarray": "^1.0.14",
61
62
  "chalk": "^5.3.0",
62
63
  "concurrently": "^8.2.2",
@@ -65,10 +66,10 @@
65
66
  "typescript": "^5.3.3"
66
67
  },
67
68
  "peerDependencies": {
68
- "@cesdk/cesdk-js": "1.20.0-rc.0"
69
+ "@cesdk/cesdk-js": "~1.21.0"
69
70
  },
70
71
  "dependencies": {
71
- "@imgly/background-removal": "^1.4.1",
72
+ "@imgly/background-removal": "^1.4.4",
72
73
  "lodash": "^4.17.21"
73
74
  }
74
75
  }