import { assertExists, DisposableGroup } from '@blockeditor/global/utils';
import { fromJSON, Job, Workspace, } from '@blockeditor/store';
import { EMBED_CARD_HEIGHT, EMBED_CARD_WIDTH, } from '../../../_common/consts.js';
import { matchFlavours } from '../../../_common/utils/index.js';
import { groupBy } from '../../../_common/utils/iterable.js';
import { blockElementGetter, getEditorContainer, isInsideDocEditor, } from '../../../_common/utils/query.js';
import { isUrlInClipboard } from '../../../_common/utils/url.js';
import { BookmarkStyles, } from '../../../bookmark-block/bookmark-model.js';
import { ConnectorElement } from '../../../surface-block/elements/connector/connector-element.js';
import { CanvasElementType } from '../../../surface-block/elements/edgeless-element.js';
import { GroupElement, } from '../../../surface-block/elements/index.js';
import { compare } from '../../../surface-block/managers/group-manager.js';
import { Bound, getCommonBound } from '../../../surface-block/utils/bound.js';
import { Vec } from '../../../surface-block/utils/vec.js';
import { PageClipboard } from '../../clipboard/index.js';
import { edgelessElementsBound } from '../utils/bound-utils.js';
import { deleteElements } from '../utils/crud.js';
import { isBookmarkBlock, isCanvasElementWithText, isEmbedFigmaBlock, isEmbedGithubBlock, isEmbedLinkedDocBlock, isEmbedYoutubeBlock, isFrameBlock, isImageBlock, isNoteBlock, isTopLevelBlock, } from '../utils/query.js';
const BLOCKSUITE_SURFACE = 'blockeditor/surface';
const IMAGE_PNG = 'image/png';
const { GROUP } = CanvasElementType;
export class EdgelessClipboardController extends PageClipboard {
    constructor(host) {
        super(host);
        this.host = host;
        this._initEdgelessClipboard = () => {
            this.host.handleEvent('copy', ctx => {
                const { selections, selectedIds } = this.selectionManager;
                if (selectedIds.length === 0)
                    return false;
                this._onCopy(ctx, selections).catch(console.error);
                return;
            }, { global: true });
            this.host.handleEvent('paste', ctx => {
                this._onPaste(ctx).catch(console.error);
            }, { global: true });
            this.host.handleEvent('cut', ctx => {
                this._onCut(ctx);
            }, { global: true });
        };
        this._onCopy = async (_context, surfaceSelection) => {
            const event = _context.get('clipboardState').raw;
            event.preventDefault();
            const elements = getCopyElements(this.surface, this.selectionManager.elements);
            // when note active, handle copy like page mode
            if (surfaceSelection[0] && surfaceSelection[0].editing) {
                // use build-in copy handler in rich-text when copy in surface text element
                if (isCanvasElementWithText(elements[0]))
                    return;
                this.onPageCopy(_context);
                return;
            }
            this.std.clipboard
                .writeToClipboard(async (_items) => {
                const data = await prepareClipboardData(elements, this.std);
                return {
                    ..._items,
                    [BLOCKSUITE_SURFACE]: JSON.stringify(data),
                };
            })
                .catch(console.error);
        };
        this._onPaste = async (_context) => {
            if (document.activeElement instanceof HTMLInputElement ||
                document.activeElement instanceof HTMLTextAreaElement) {
                return;
            }
            const event = _context.get('clipboardState').raw;
            event.preventDefault();
            const { selections, elements } = this.selectionManager;
            if (selections[0]?.editing) {
                // use build-in paste handler in rich-text when paste in surface text element
                if (isCanvasElementWithText(elements[0]))
                    return;
                this.onPagePaste(_context);
                return;
            }
            const data = event.clipboardData;
            if (!data)
                return;
            if (isPureFileInClipboard(data)) {
                const files = data.files;
                if (files.length === 0)
                    return;
                const imageFiles = [...files].filter(file => file.type.startsWith('image/'));
                await this.host.addImages(imageFiles);
                return;
            }
            if (isUrlInClipboard(data)) {
                const url = data.getData('text/plain');
                const { lastMousePos } = this.toolManager;
                const [x, y] = this.surface.toModelCoord(lastMousePos.x, lastMousePos.y);
                const embedOptions = this._pageService.getEmbedBlockOptions(url);
                const flavour = embedOptions
                    ? embedOptions.flavour
                    : 'affine:bookmark';
                const style = embedOptions ? embedOptions.styles[0] : BookmarkStyles[0];
                const width = EMBED_CARD_WIDTH[style];
                const height = EMBED_CARD_HEIGHT[style];
                const id = this.surface.addElement(flavour, {
                    xywh: Bound.fromCenter(Vec.toVec({
                        x,
                        y,
                    }), width, height).serialize(),
                    url,
                    style,
                }, this.surface.model.id);
                this.selectionManager.set({
                    editing: false,
                    elements: [id],
                });
                return;
            }
            const json = this.std.clipboard.readFromClipboard(data);
            const elementsRawData = JSON.parse(json[BLOCKSUITE_SURFACE]);
            this._pasteShapesAndBlocks(elementsRawData).catch(console.error);
        };
        this._onCut = (_context) => {
            const { selections, elements } = this.selectionManager;
            if (elements.length === 0)
                return;
            const event = _context.get('clipboardState').event;
            event.preventDefault();
            this._onCopy(_context, selections).catch(console.error);
            if (selections[0]?.editing) {
                // use build-in cut handler in rich-text when cut in surface text element
                if (isCanvasElementWithText(elements[0]))
                    return;
                this.onPageCut(_context);
                return;
            }
            this.page.transact(() => {
                deleteElements(this.surface, elements);
            });
            this.selectionManager.set({
                editing: false,
                elements: [],
            });
        };
    }
    get std() {
        return this.host.std;
    }
    get page() {
        return this.host.page;
    }
    get surface() {
        return this.host.surface;
    }
    get toolManager() {
        return this.host.tools;
    }
    get selectionManager() {
        return this.host.selectionManager;
    }
    get _pageService() {
        const pageService = this.std.spec.getService('affine:page');
        assertExists(pageService);
        return pageService;
    }
    hostConnected() {
        if (this._disposables.disposed) {
            this._disposables = new DisposableGroup();
        }
        this._init();
        this._initEdgelessClipboard();
    }
    _createCanvasElement(clipboardData, idMap) {
        if (clipboardData.type === GROUP) {
            const yMap = new Workspace.Y.Map();
            const children = clipboardData.children ?? {};
            for (const [key, value] of Object.entries(children)) {
                const newKey = idMap.get(key);
                assertExists(newKey);
                yMap.set(newKey, value);
            }
            clipboardData.children = yMap;
        }
        const id = this.surface.addElement(clipboardData.type, clipboardData);
        const element = this.surface.pickById(id);
        assertExists(element);
        return element;
    }
    _createCanvasElements(elements, idMap) {
        const result = groupBy(elements, item => {
            switch (item.type) {
                case 'connector':
                    return 'connectors';
                case 'group':
                    return 'groups';
                default:
                    return 'others';
            }
        });
        return [
            ...(result.others
                ?.map(d => {
                const oldId = d.id;
                assertExists(oldId);
                const element = this._createCanvasElement(d, idMap);
                idMap.set(oldId, element.id);
                return element;
            })
                .filter(e => !!e) ?? []),
            ...(result.connectors?.map(connector => {
                const sourceId = connector.source.id;
                if (sourceId) {
                    connector.source.id =
                        idMap.get(sourceId) ?? sourceId;
                }
                const targetId = connector.target.id;
                if (targetId) {
                    connector.target.id =
                        idMap.get(targetId) ?? targetId;
                }
                const element = this._createCanvasElement(connector, idMap);
                idMap.set(connector.id, element.id);
                return element;
            }) ?? []),
            ...(result.groups?.map(group => {
                const oldId = group.id;
                assertExists(oldId);
                const element = this._createCanvasElement(group, idMap);
                idMap.set(oldId, element.id);
                return element;
            }) ?? []),
        ];
    }
    _createNoteBlocks(notes, oldToNewIdMap) {
        const { surface } = this;
        const noteIds = notes.map(({ id, props, children }) => {
            delete props.index;
            assertExists(props.xywh);
            const noteId = this.surface.addElement('affine:note', props, this.page.root?.id);
            const note = surface.pickById(noteId);
            if (id)
                oldToNewIdMap.set(id, noteId);
            assertExists(note);
            children.forEach((child, index) => {
                this.onBlockSnapshotPaste(child, this.page, note.id, index);
            });
            return noteId;
        });
        return noteIds;
    }
    _createFrameBlocks(frames) {
        const frameIds = frames.map(({ props }) => {
            const { xywh, title, background } = props;
            const frameId = this.surface.addElement('affine:frame', {
                xywh,
                background,
                title: fromJSON(title),
            }, this.surface.model.id);
            return frameId;
        });
        return frameIds;
    }
    _createImageBlocks(images) {
        const imageIds = images.map(({ props }) => {
            const { xywh, sourceId, rotate } = props;
            const imageId = this.surface.addElement('affine:image', {
                xywh,
                sourceId,
                rotate,
            }, this.surface.model.id);
            return imageId;
        });
        return imageIds;
    }
    _createBookmarkBlocks(bookmarks) {
        const bookmarkIds = bookmarks.map(({ props }) => {
            const { xywh, style, url, caption, description, icon, image, title } = props;
            const bookmarkId = this.surface.addElement('affine:bookmark', {
                xywh,
                style,
                url,
                caption,
                description,
                icon,
                image,
                title,
            }, this.surface.model.id);
            return bookmarkId;
        });
        return bookmarkIds;
    }
    _createGithubEmbedBlocks(githubEmbeds) {
        const embedGithubIds = githubEmbeds.map(({ props }) => {
            const { xywh, style, owner, repo, githubType, githubId, url, caption, image, status, statusReason, title, description, createdAt, assignees, } = props;
            const embedGithubId = this.surface.addElement('affine:embed-github', {
                xywh,
                style,
                owner,
                repo,
                githubType,
                githubId,
                url,
                caption,
                image,
                status,
                statusReason,
                title,
                description,
                createdAt,
                assignees,
            }, this.surface.model.id);
            return embedGithubId;
        });
        return embedGithubIds;
    }
    _createYoutubeEmbedBlocks(youtubeEmbeds) {
        const embedYoutubeIds = youtubeEmbeds.map(({ props }) => {
            const { xywh, style, url, caption, videoId, image, title, description, creator, creatorUrl, creatorImage, } = props;
            const embedYoutubeId = this.surface.addElement('affine:embed-youtube', {
                xywh,
                style,
                url,
                caption,
                videoId,
                image,
                title,
                description,
                creator,
                creatorUrl,
                creatorImage,
            }, this.surface.model.id);
            return embedYoutubeId;
        });
        return embedYoutubeIds;
    }
    _createFigmaEmbedBlocks(figmaEmbeds) {
        const embedFigmaIds = figmaEmbeds.map(({ props }) => {
            const { xywh, style, url, caption, title, description } = props;
            const embedFigmaId = this.surface.addElement('affine:embed-figma', {
                xywh,
                style,
                url,
                caption,
                title,
                description,
            }, this.surface.model.id);
            return embedFigmaId;
        });
        return embedFigmaIds;
    }
    _createLinkedDocEmbedBlocks(linkedDocEmbeds) {
        const embedLinkedDocIds = linkedDocEmbeds.map(({ props }) => {
            const { xywh, style, caption, pageId } = props;
            return this.surface.addElement('affine:embed-linked-doc', {
                xywh,
                style,
                caption,
                pageId,
            }, this.surface.model.id);
        });
        return embedLinkedDocIds;
    }
    _emitSelectionChangeAfterPaste(canvasElementIds, blockIds) {
        const newSelected = [
            ...canvasElementIds,
            ...blockIds.filter(id => {
                return isTopLevelBlock(this.page.getBlockById(id));
            }),
        ];
        this.selectionManager.set({
            editing: false,
            elements: newSelected,
        });
    }
    async createElementsFromClipboardData(elementsRawData, pasteCenter) {
        const groupedByType = groupBy(elementsRawData, data => isNoteBlock(data)
            ? 'notes'
            : isFrameBlock(data)
                ? 'frames'
                : isImageBlock(data)
                    ? 'images'
                    : isBookmarkBlock(data)
                        ? 'bookmarks'
                        : isEmbedGithubBlock(data)
                            ? 'githubEmbeds'
                            : isEmbedYoutubeBlock(data)
                                ? 'youtubeEmbeds'
                                : isEmbedFigmaBlock(data)
                                    ? 'figmaEmbeds'
                                    : isEmbedLinkedDocBlock(data)
                                        ? 'linkedDocEmbeds'
                                        : 'elements');
        pasteCenter =
            pasteCenter ??
                this.surface.toModelCoord(this.toolManager.lastMousePos.x, this.toolManager.lastMousePos.y);
        // map old id to new id to rebuild connector's source and target
        const oldIdToNewIdMap = new Map();
        // create and add blocks to page
        const noteIds = this._createNoteBlocks(groupedByType.notes || [], oldIdToNewIdMap);
        const frameIds = this._createFrameBlocks(groupedByType.frames ?? []);
        const imageIds = this._createImageBlocks(groupedByType.images ?? []);
        const bookmarkIds = this._createBookmarkBlocks(groupedByType.bookmarks ?? []);
        const embedGithubIds = this._createGithubEmbedBlocks(groupedByType.githubEmbeds ?? []);
        const embedYoutubeIds = this._createYoutubeEmbedBlocks(groupedByType.youtubeEmbeds ?? []);
        const embedFigmaIds = this._createFigmaEmbedBlocks(groupedByType.figmaEmbeds ?? []);
        const embedLinkedDocIds = this._createLinkedDocEmbedBlocks(groupedByType.linkedDocEmbeds ?? []);
        const notes = noteIds.map(id => this.page.getBlockById(id));
        const frames = frameIds.map(id => this.page.getBlockById(id));
        const images = imageIds.map(id => this.surface.pickById(id));
        const bookmarks = bookmarkIds.map(id => this.surface.pickById(id));
        const githubEmbeds = embedGithubIds.map(id => this.surface.pickById(id));
        const youtubeEmbeds = embedYoutubeIds.map(id => this.surface.pickById(id));
        const figmaEmbeds = embedFigmaIds.map(id => this.surface.pickById(id));
        const linkedDocEmbeds = embedLinkedDocIds.map(id => this.surface.pickById(id));
        const elements = this._createCanvasElements(groupedByType.elements || [], oldIdToNewIdMap);
        const [modelX, modelY] = pasteCenter;
        const oldCommonBound = edgelessElementsBound([
            ...elements,
            ...notes,
            ...frames,
            ...images,
            ...bookmarks,
            ...githubEmbeds,
            ...youtubeEmbeds,
            ...figmaEmbeds,
            ...linkedDocEmbeds,
        ]);
        const pasteX = modelX - oldCommonBound.w / 2;
        const pasteY = modelY - oldCommonBound.h / 2;
        // update canvas elements' position to mouse position
        elements.forEach(ele => {
            const newBound = new Bound(pasteX + ele.x - oldCommonBound.x, pasteY + ele.y - oldCommonBound.y, ele.w, ele.h);
            if (ele instanceof ConnectorElement) {
                this.surface.connector.updateXYWH(ele, newBound);
            }
            else {
                this.surface.updateElement(ele.id, {
                    xywh: newBound.serialize(),
                });
            }
        });
        const blocks = [...notes, ...frames, ...images, ...bookmarks];
        blocks.forEach(block => {
            const bound = Bound.deserialize(block.xywh);
            bound.x += pasteX - oldCommonBound.x;
            bound.y += pasteY - oldCommonBound.y;
            this.surface.updateElement(block.id, {
                xywh: bound.serialize(),
            });
        });
        return [elements, blocks];
    }
    async _pasteShapesAndBlocks(elementsRawData) {
        const [elements, blocks] = await this.createElementsFromClipboardData(elementsRawData);
        this._emitSelectionChangeAfterPaste(elements.map(ele => ele.id), blocks.map(block => block.id));
    }
    async toCanvas(blocks, shapes) {
        blocks.sort(compare);
        shapes.sort(compare);
        const bounds = [];
        blocks.forEach(block => {
            bounds.push(Bound.deserialize(block.xywh));
        });
        shapes.forEach(shape => {
            bounds.push(Bound.deserialize(shape.xywh));
        });
        const bound = getCommonBound(bounds);
        assertExists(bound, 'bound not exist');
        const canvas = await this._edgelessToCanvas(this.host, bound, blocks, shapes);
        return canvas;
    }
    async copyAsPng(blocks, shapes) {
        const blocksLen = blocks.length;
        const shapesLen = shapes.length;
        if (blocksLen + shapesLen === 0)
            return;
        const canvas = await this.toCanvas(blocks, shapes);
        assertExists(canvas);
        // @ts-ignore
        if (window.apis?.clipboard?.copyAsImageFromString) {
            // @ts-ignore
            await window.apis.clipboard?.copyAsImageFromString(canvas.toDataURL(IMAGE_PNG));
        }
        else {
            const blob = await new Promise((resolve, reject) => canvas.toBlob(blob => (blob ? resolve(blob) : reject('Canvas can not export blob')), IMAGE_PNG));
            assertExists(blob);
            this.std.clipboard
                .writeToClipboard(async (_items) => {
                return {
                    ..._items,
                    [IMAGE_PNG]: blob,
                };
            })
                .catch(console.error);
        }
    }
    async _replaceRichTextWithSvgElement(element) {
        const richList = Array.from(element.querySelectorAll('.inline-editor'));
        await Promise.all(richList.map(async (rich) => {
            const svgEle = await this._elementToSvgElement(rich.cloneNode(true), rich.clientWidth, rich.clientHeight + 1);
            rich.parentElement?.appendChild(svgEle);
            rich.parentElement?.removeChild(rich);
        }));
    }
    async _elementToSvgElement(node, width, height) {
        const xmlns = 'http://www.w3.org/2000/svg';
        const svg = document.createElementNS(xmlns, 'svg');
        const foreignObject = document.createElementNS(xmlns, 'foreignObject');
        svg.setAttribute('width', `${width}`);
        svg.setAttribute('height', `${height}`);
        svg.setAttribute('viewBox', `0 0 ${width} ${height}`);
        foreignObject.setAttribute('width', '100%');
        foreignObject.setAttribute('height', '100%');
        foreignObject.setAttribute('x', '0');
        foreignObject.setAttribute('y', '0');
        foreignObject.setAttribute('externalResourcesRequired', 'true');
        svg.appendChild(foreignObject);
        foreignObject.appendChild(node);
        return svg;
    }
    async _edgelessToCanvas(edgeless, bound, nodes, canvasElements = []) {
        const host = edgeless.host;
        const root = this.page.root;
        if (!root)
            return;
        const html2canvas = (await import('html2canvas')).default;
        if (!(html2canvas instanceof Function))
            return;
        const pathname = location.pathname;
        const pageMode = isInsideDocEditor(host);
        const editorContainer = getEditorContainer(host);
        const container = editorContainer.querySelector('.affine-block-children-container');
        if (!container)
            return;
        const dpr = window.devicePixelRatio || 1;
        const canvas = document.createElement('canvas');
        canvas.width = (bound.w + 100) * dpr;
        canvas.height = (bound.h + 100) * dpr;
        const ctx = canvas.getContext('2d');
        if (!ctx)
            return;
        ctx.scale(dpr, dpr);
        ctx.fillStyle = window.getComputedStyle(container).backgroundColor;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        const replaceRichTextWithSvgElementFunc = this._replaceRichTextWithSvgElement.bind(this);
        let _imageProxyEndpoint;
        if (!_imageProxyEndpoint &&
            location.protocol === 'https:' &&
            location.hostname.split('.').includes('affine')) {
            _imageProxyEndpoint =
                'https://workers.toeverything.workers.dev/proxy/image';
        }
        const html2canvasOption = {
            ignoreElements: function (element) {
                if (element.tagName === 'AFFINE-BLOCK-HUB' ||
                    element.tagName === 'EDGELESS-TOOLBAR' ||
                    element.classList.contains('dg')) {
                    return true;
                }
                else {
                    return false;
                }
            },
            onclone: async function (documentClone, element) {
                // html2canvas can't support transform feature
                element.style.setProperty('transform', 'none');
                const layer = documentClone.querySelector('.affine-edgeless-layer');
                if (layer && layer instanceof HTMLElement) {
                    layer.style.setProperty('transform', 'none');
                }
                const boxShadowEles = documentClone.querySelectorAll("[style*='box-shadow']");
                boxShadowEles.forEach(function (element) {
                    if (element instanceof HTMLElement) {
                        element.style.setProperty('box-shadow', 'none');
                    }
                });
                await replaceRichTextWithSvgElementFunc(element);
            },
            backgroundColor: window.getComputedStyle(editorContainer).backgroundColor,
            useCORS: _imageProxyEndpoint ? false : true,
            proxy: _imageProxyEndpoint,
        };
        const _drawTopLevelBlock = async (block, isInFrame = false) => {
            let blockElement = blockElementGetter(block, this.std.view)
                ?.parentElement;
            const blockPortalSelector = block.flavour.replace('affine:', '.edgeless-block-portal-');
            blockElement = blockElement?.closest(blockPortalSelector);
            if (!blockElement) {
                throw new Error('Could not find edgeless block portal.');
            }
            const blockBound = Bound.deserialize(block.xywh);
            const canvasData = await html2canvas(blockElement, html2canvasOption);
            ctx.drawImage(canvasData, blockBound.x - bound.x + 50, blockBound.y - bound.y + 50, blockBound.w, isInFrame
                ? (blockBound.w / canvasData.width) * canvasData.height
                : blockBound.h);
        };
        const nodeElements = nodes ?? edgeless.getSortedElementsByBound(bound);
        for (const nodeElement of nodeElements) {
            await _drawTopLevelBlock(nodeElement);
            if (matchFlavours(nodeElement, ['affine:frame'])) {
                const blocksInsideFrame = [];
                this.surface.frame
                    .getElementsInFrame(nodeElement, false)
                    .forEach(ele => {
                    if (isTopLevelBlock(ele)) {
                        blocksInsideFrame.push(ele);
                    }
                    else {
                        canvasElements.push(ele);
                    }
                });
                for (let i = 0; i < blocksInsideFrame.length; i++) {
                    const element = blocksInsideFrame[i];
                    await _drawTopLevelBlock(element, true);
                }
            }
            this._checkCanContinueToCanvas(host, pathname, pageMode);
        }
        const surfaceCanvas = edgeless.surface.viewport.getCanvasByBound(bound, canvasElements);
        ctx.drawImage(surfaceCanvas, 50, 50, bound.w, bound.h);
        return canvas;
    }
    _checkCanContinueToCanvas(host, pathName, pageMode) {
        if (location.pathname !== pathName ||
            isInsideDocEditor(host) !== pageMode) {
            throw new Error('Unable to export content to canvas');
        }
    }
}
export function getCopyElements(surface, elements) {
    const set = new Set();
    elements.forEach(element => {
        if (isFrameBlock(element)) {
            set.add(element);
            surface.frame.getElementsInFrame(element).forEach(ele => set.add(ele));
        }
        else if (element instanceof GroupElement) {
            getCopyElements(surface, element.childElements).forEach(ele => set.add(ele));
            set.add(element);
        }
        else {
            set.add(element);
        }
    });
    return Array.from(set);
}
function prepareConnectorClipboardData(connector, selected) {
    const sourceId = connector.source?.id;
    const targetId = connector.target?.id;
    const serialized = connector.serialize();
    if (sourceId && !selected.find(s => s.id === sourceId)) {
        serialized.source = { position: connector.absolutePath[0] };
    }
    if (targetId && !selected.find(s => s.id === targetId)) {
        serialized.target = {
            position: connector.absolutePath[connector.absolutePath.length - 1],
        };
    }
    return serialized;
}
export async function prepareClipboardData(selectedAll, std) {
    const selected = await Promise.all(selectedAll.map(async (selected) => {
        const job = new Job({
            workspace: std.workspace,
        });
        if (isNoteBlock(selected)) {
            const snapshot = await job.blockToSnapshot(selected);
            return { ...snapshot };
        }
        else if (isFrameBlock(selected)) {
            const snapshot = await job.blockToSnapshot(selected);
            return { ...snapshot };
        }
        else if (isImageBlock(selected)) {
            const snapshot = await job.blockToSnapshot(selected);
            return { ...snapshot };
        }
        else if (isBookmarkBlock(selected)) {
            const snapshot = await job.blockToSnapshot(selected);
            return { ...snapshot };
        }
        else if (isEmbedGithubBlock(selected)) {
            const snapshot = await job.blockToSnapshot(selected);
            return { ...snapshot };
        }
        else if (isEmbedYoutubeBlock(selected)) {
            const snapshot = await job.blockToSnapshot(selected);
            return { ...snapshot };
        }
        else if (isEmbedFigmaBlock(selected)) {
            const snapshot = await job.blockToSnapshot(selected);
            return { ...snapshot };
        }
        else if (isEmbedLinkedDocBlock(selected)) {
            const snapshot = await job.blockToSnapshot(selected);
            return { ...snapshot };
        }
        else if (selected instanceof ConnectorElement) {
            return prepareConnectorClipboardData(selected, selectedAll);
        }
        else {
            return selected.serialize();
        }
    }));
    return selected.filter(d => !!d);
}
function isPureFileInClipboard(clipboardData) {
    const types = clipboardData.types;
    return ((types.length === 1 && types[0] === 'Files') ||
        (types.length === 2 &&
            (types.includes('text/plain') || types.includes('text/html')) &&
            types.includes('Files')));
}
//# sourceMappingURL=clipboard.js.map