import * as __WEBPACK_EXTERNAL_MODULE_webcola__ from "webcola";
/******/ var __webpack_modules__ = ([
/* 0 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   connectWorker: () => (/* binding */ connectWorker)
/* harmony export */ });
/**
 * Establishes a specific connection protocol between the callee (worker) and external
 * caller (which created a worker via `new Worker(...)` constructor).
 *
 * The protocol assumes the worker exposes an RPC-like interface via a `class` where
 * every public method returns a `Promise`. This interface is transparently mapped
 * from the caller to the worker via messages.
 *
 * **Example**:
 * ```ts
 * // calc-worker.ts
 * class Calculator {
 *     constructor(precision: number) { ... }
 *     add(a: number, b: number): Promise<number> { ... }
 * }
 *
 * connectWorker(Calculator);
 *
 * // component.ts
 * const calcWorker = defineWorker(() => new Worker('./calc-worker.js'), [0.1]);
 * ...
 * function Component() {
 *     const calc = useWorker(calcWorker);
 *     ...
 *     const result = await calc.add(2, 3);
 * }
 * ```
 */
function connectWorker(factory) {
    let handler;
    onmessage = async (e) => {
        const message = e.data;
        if (message.type === 'call') {
            let response;
            try {
                if (handler) {
                    const result = await handler[message.method](...message.args);
                    response = {
                        type: 'success',
                        id: message.id,
                        result,
                    };
                }
                else {
                    if (message.method !== 'constructor') {
                        throw new Error('Cannot call worker method without initializing it first');
                    }
                    handler = new factory(...message.args);
                    response = {
                        type: 'success',
                        id: message.id,
                        result: undefined,
                    };
                }
            }
            catch (err) {
                response = {
                    type: 'error',
                    id: message.id,
                    error: err,
                };
            }
            postMessage(response);
        }
    };
}


/***/ }),
/* 1 */,
/* 2 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   blockingDefaultLayout: () => (/* binding */ blockingDefaultLayout),
/* harmony export */   colaFlowLayout: () => (/* binding */ colaFlowLayout),
/* harmony export */   colaForceLayout: () => (/* binding */ colaForceLayout),
/* harmony export */   colaRemoveOverlaps: () => (/* binding */ colaRemoveOverlaps),
/* harmony export */   evaluateColaLayout: () => (/* binding */ evaluateColaLayout),
/* harmony export */   getContentFittingBoxForLayout: () => (/* binding */ getContentFittingBoxForLayout),
/* harmony export */   layoutPadded: () => (/* binding */ layoutPadded),
/* harmony export */   layoutPaddedBiasFree: () => (/* binding */ layoutPaddedBiasFree)
/* harmony export */ });
/* harmony import */ var webcola__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3);

/**
 * @category Geometry
 */
function evaluateColaLayout(graph, state, evaluateLayout) {
    const nodes = new Map();
    const links = [];
    for (const [id, node] of Object.entries(graph.nodes)) {
        const bounds = Object.hasOwn(state.bounds, id)
            ? state.bounds[id] : undefined;
        nodes.set(id, {
            x: bounds ? bounds.x : 0,
            y: bounds ? bounds.y : 0,
            width: bounds ? bounds.width : undefined,
            height: bounds ? bounds.height : undefined,
            fixed: node.fixed ? 1 : 0,
        });
    }
    for (const link of graph.links) {
        const source = nodes.get(link.source);
        const target = nodes.get(link.target);
        if (source && target) {
            links.push({ source, target });
        }
    }
    evaluateLayout(nodes, links);
    const bounds = Object.create(null);
    for (const [id, node] of nodes) {
        bounds[id] = {
            x: node.x,
            y: node.y,
            width: node.width ?? 0,
            height: node.height ?? 0,
        };
    }
    return { bounds };
}
/**
 * @category Geometry
 */
function colaForceLayout(graph, state, options) {
    const { preferredLinkLength = 200, avoidOverlaps = true, } = options ?? {};
    return evaluateColaLayout(graph, state, (nodes, links) => {
        const layout = new webcola__WEBPACK_IMPORTED_MODULE_0__.Layout()
            .nodes(Array.from(nodes.values()))
            .links(links)
            .avoidOverlaps(avoidOverlaps)
            .convergenceThreshold(1e-9)
            .jaccardLinkLengths(preferredLinkLength)
            .handleDisconnected(true);
        layout.start(30, 0, 10, undefined, false);
    });
}
/**
 * @category Geometry
 */
function colaFlowLayout(graph, state, options) {
    const { axis = 'y', minSeparation = 200, preferredLinkLength = 50, avoidOverlaps = true, } = options ?? {};
    return evaluateColaLayout(graph, state, (nodes, links) => {
        const layout = new webcola__WEBPACK_IMPORTED_MODULE_0__.Layout()
            .nodes(Array.from(nodes.values()))
            .links(links)
            .avoidOverlaps(avoidOverlaps)
            .flowLayout(axis, minSeparation)
            .symmetricDiffLinkLengths(preferredLinkLength);
        layout.start(10, 20, 20, undefined, false);
    });
}
/**
 * @category Geometry
 */
function colaRemoveOverlaps(state) {
    const nodeRectangles = new Map();
    for (const [id, { x, y, width, height }] of Object.entries(state.bounds)) {
        nodeRectangles.set(id, new webcola__WEBPACK_IMPORTED_MODULE_0__.Rectangle(x, x + width, y, y + height));
    }
    webcola__WEBPACK_IMPORTED_MODULE_0__.removeOverlaps(Array.from(nodeRectangles.values()));
    const bounds = Object.create(null);
    for (const [id, { x, y }] of nodeRectangles) {
        const nodeBounds = Object.hasOwn(state.bounds, id) ? state.bounds[id] : undefined;
        bounds[id] = {
            x, y,
            width: nodeBounds ? nodeBounds.width : 0,
            height: nodeBounds ? nodeBounds.height : 0,
        };
    }
    return { bounds };
}
/**
 * @category Geometry
 */
function layoutPadded(state, padding) {
    if (!padding) {
        return { state, unwrap: transformed => transformed };
    }
    const paddedBounds = Object.create(null);
    for (const [id, { x, y, width, height }] of Object.entries(state.bounds)) {
        paddedBounds[id] = {
            x: x - padding.x,
            y: y - padding.y,
            width: width + padding.x * 2,
            height: height + padding.y * 2,
        };
    }
    const paddedState = { bounds: paddedBounds };
    return {
        state: paddedState,
        unwrap: transformed => {
            const shrinkBounds = Object.create(null);
            for (const [id, { x, y, width, height }] of Object.entries(transformed.bounds)) {
                shrinkBounds[id] = {
                    x: x + padding.x,
                    y: y + padding.y,
                    width: width - padding.x * 2,
                    height: height - padding.y * 2,
                };
            }
            return { bounds: shrinkBounds };
        }
    };
}
/**
 * @category Geometry
 */
function layoutPaddedBiasFree(state, padding) {
    const extendedBounds = Object.create(null);
    let compressX = Infinity;
    let compressY = Infinity;
    for (const [id, { x, y, width, height }] of Object.entries(state.bounds)) {
        const maxSide = Math.max(width, height);
        compressX = Math.min(width ? (maxSide / width) : 1, compressX);
        compressY = Math.min(height ? (maxSide / height) : 1, compressY);
        extendedBounds[id] = {
            x, y,
            width: maxSide,
            height: maxSide,
        };
    }
    const padded = layoutPadded({ bounds: extendedBounds }, padding);
    return {
        state: padded.state,
        unwrap: transformed => {
            const withoutPadding = padded.unwrap(transformed);
            const fittingBox = getContentFittingBoxForLayout(withoutPadding);
            const uncompressedBounds = Object.create(null);
            for (const [id, bounds] of Object.entries(withoutPadding.bounds)) {
                const initialBounds = Object.hasOwn(state.bounds, id) ? state.bounds[id] : undefined;
                uncompressedBounds[id] = {
                    x: (bounds.x - fittingBox.x) / compressX + fittingBox.x,
                    y: (bounds.y - fittingBox.y) / compressY + fittingBox.y,
                    width: initialBounds ? initialBounds.width : bounds.width,
                    height: initialBounds ? initialBounds.height : bounds.height,
                };
            }
            return { bounds: uncompressedBounds };
        }
    };
}
/**
 * Default (fallback) diagram layout function.
 *
 * The algorithm used is force-directed layout from [cola.js](https://ialab.it.monash.edu/webcola/).
 *
 * This function is computationally expensive and should be used only as fallback
 * when other ways to compute diagram layout is not available.
 * The recommended way is to use web workers via `@reactodia/workspace/layout.worker`
 * and {@link useWorker Reactodia.useWorker()}`.
 *
 * @category Geometry
 */
function blockingDefaultLayout(graph, state, options) {
    const { preferredLinkLength = 200, padding = { x: 50, y: 50 }, } = options ?? {};
    const withForce = colaForceLayout(graph, state, {
        preferredLinkLength,
        avoidOverlaps: false,
    });
    const padded = layoutPaddedBiasFree(withForce, padding);
    const withoutOverlaps = colaRemoveOverlaps(padded.state);
    const result = padded.unwrap(withoutOverlaps);
    return Promise.resolve(result);
}
/**
 * Computes complete bounding box for the element bounds in the provided layout state.
 *
 * @category Geometry
 */
function getContentFittingBoxForLayout(state) {
    let minX = Infinity, minY = Infinity;
    let maxX = -Infinity, maxY = -Infinity;
    for (const [id, { x, y, width, height }] of Object.entries(state.bounds)) {
        minX = Math.min(minX, x);
        minY = Math.min(minY, y);
        maxX = Math.max(maxX, x + width);
        maxY = Math.max(maxY, y + height);
    }
    return {
        x: Number.isFinite(minX) ? minX : 0,
        y: Number.isFinite(minY) ? minY : 0,
        width: Number.isFinite(minX) && Number.isFinite(maxX) ? (maxX - minX) : 0,
        height: Number.isFinite(minY) && Number.isFinite(maxY) ? (maxY - minY) : 0,
    };
}


/***/ }),
/* 3 */
/***/ ((module) => {

module.exports = __WEBPACK_EXTERNAL_MODULE_webcola__;

/***/ })
/******/ ]);
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/ 
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ 	// Check if module is in cache
/******/ 	var cachedModule = __webpack_module_cache__[moduleId];
/******/ 	if (cachedModule !== undefined) {
/******/ 		return cachedModule.exports;
/******/ 	}
/******/ 	// Create a new module (and put it into the cache)
/******/ 	var module = __webpack_module_cache__[moduleId] = {
/******/ 		// no module.id needed
/******/ 		// no module.loaded needed
/******/ 		exports: {}
/******/ 	};
/******/ 
/******/ 	// Execute the module function
/******/ 	__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 
/******/ 	// Return the exports of the module
/******/ 	return module.exports;
/******/ }
/******/ 
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ 	// define getter functions for harmony exports
/******/ 	__webpack_require__.d = (exports, definition) => {
/******/ 		for(var key in definition) {
/******/ 			if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ 				Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 			}
/******/ 		}
/******/ 	};
/******/ })();
/******/ 
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ 	__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/ 
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = (exports) => {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/ })();
/******/ 
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _worker_protocol__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
/* harmony import */ var _diagram_layoutShared__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);


/**
 * Provides a web worker with basic diagram layout algorithms.
 */
class DefaultLayouts {
    /**
     * Default layout algorithm, the same as {@link blockingDefaultLayout}
     * but non-blocking due to being run in a worker.
     *
     * @see {@link blockingDefaultLayout}
     */
    async defaultLayout(graph, state, options) {
        return (0,_diagram_layoutShared__WEBPACK_IMPORTED_MODULE_1__.blockingDefaultLayout)(graph, state, options);
    }
    /**
     * Force-directed layout algorithm from [cola.js](https://ialab.it.monash.edu/webcola/).
     */
    async forceLayout(graph, state, options) {
        return (0,_diagram_layoutShared__WEBPACK_IMPORTED_MODULE_1__.colaForceLayout)(graph, state, options);
    }
    /**
     * Flow layout algorithm from [cola.js](https://ialab.it.monash.edu/webcola/).
     */
    async flowLayout(graph, state, options) {
        return (0,_diagram_layoutShared__WEBPACK_IMPORTED_MODULE_1__.colaFlowLayout)(graph, state, options);
    }
    /**
     * Remove overlaps algorithm from [cola.js](https://ialab.it.monash.edu/webcola/).
     */
    async removeOverlaps(graph, state) {
        return (0,_diagram_layoutShared__WEBPACK_IMPORTED_MODULE_1__.colaRemoveOverlaps)(state);
    }
}
(0,_worker_protocol__WEBPACK_IMPORTED_MODULE_0__.connectWorker)(DefaultLayouts);

})();


//# sourceMappingURL=layout.worker.js.map