//
// Translation from Objects in help to Typescript interface.
// http://js.cytoscape.org/#notation/functions
// TypeScript Version: 2.3

/**
 * WARNING: This is a provisional specification of the Cytoscape.js
 * API in TypeScript, based on improvements made on the Typescript
 * specification for Cytoscape.js in DefinitelyTyped.  This is a work
 * in progress and may not be complete, and it may have errors. Please
 * report any issues to the issue tracker:
 *
 * https://github.com/cytoscape/cytoscape.js/issues
 *
 * cy   --> Cy.Core
 *  the core
 *
 * eles --> Cy.Collection
 *  a collection of one or more elements (nodes and edges)
 *
 * ele  --> Cy.Singular
 *  a collection of a single element (node or edge)
 *
 * node --> Cy.NodeSingular
 *  a collection of a single node
 *
 * nodes -> Cy.NodeCollection
 *  a collection of one or more nodes
 *
 * edge --> Cy.EdgeSingular
 *  a collection of a single edge
 *
 * edges -> Cy.EdgeCollection
 *  a collection of one or more edges
 *
 * The library makes a distinction between input and output parameters
 *  due to the dynamic behaviour of the Cytoscape library.
 *
 * For a input parameter it will always expect:
 *  - Cy.Collection
 *      The input can be any element (node and edge) collection.
 *  - Cy.NodeCollection
 *      The input must be a node collection.
 *  - Cy.EdgeCollection
 *      The input must be a edge collection.
 *  - Cy.Singular
 *      The input must be a single element.
 *  - Cy.NodeSingular
 *      The input must be a single node.
 *  - Cy.EdgeSingular
 *      The input must be a single edge.
 *
 * For a output of a function it will always give:
 *  - Cy.Elements
 *      The output is a collection of node and edge elements OR single element.
 *  - Cy.EdgeCollection
 *      The output is a collection of edge elements OR single edge.
 *  - Cy.NodeCollection
 *      The output is a collection of node elements OR single node.
 *
 * A number of interfaces contain nothing as they serve to collect interfaces.
 */
export = cytoscape;
export as namespace cytoscape;

/**
 * WARNING: This is a provisional specification of the Cytoscape.js
 * API in TypeScript, based on improvements made on the Typescript
 * specification for Cytoscape.js in DefinitelyTyped.  This is a work
 * in progress and may not be complete, and it may have errors. Please 
 * report any issues to the issue tracker:
 * 
 * https://github.com/cytoscape/cytoscape.js/issues
 */
declare function cytoscape(options?: cytoscape.CytoscapeOptions): cytoscape.Core;
declare function cytoscape(type: string, name: string): unknown;
declare function cytoscape(type: string, name: string, registrant: any): void;

declare namespace cytoscape {
    /***
    * extensions can add functionality  to the registry for Cytoscape ,
     * to three different types of functionality can be added
    **/
    type CytoscapeRegistry = (type: "core" | "collection" | "layout", name: string, extension: unknown) => void;
    interface Position {
        x: number;
        y: number;
    }

    interface BoundingBox {
        x1: number;
        y1: number;
        x2: number;
        y2: number;
        w: number;
        h: number;
    }

    type CssStyleDeclaration = any;

    interface ElementDefinition {
        group?: ElementGroup;
        data: NodeDataDefinition | EdgeDataDefinition;
        /**
         * Scratchpad data (usually temp or nonserialisable data)
         */
        scratch?: Scratchpad;
        /**
         * The model position of the node (optional on init, mandatory after)
         */
        position?: Position;
        /**
         * can alternatively specify position in rendered on-screen pixels
         */
        renderedPosition?: Position;
        /**
         * Whether the element is selected (default false)
         */
        selected?: boolean;
        /**
         * Whether the selection state is mutable (default true)
         */
        selectable?: boolean;
        /**
         * When locked a node's position is immutable (default false)
         */
        locked?: boolean;
        /**
         * Wether the node can be grabbed and moved by the user
         */
        grabbable?: boolean;
        /**
         * Whether the element has passthrough panning enabled.
         */
        pannable?: boolean;
        /**
         * a space separated list of class names that the element has
         */
        classes?: string[] | string;
        /**
         *  CssStyleDeclaration;
         */
        style?: CssStyleDeclaration;
        /**
         * you should only use `style`/`css` for very special cases; use classes instead
         */
        css?: Css.Node | Css.Edge;
        /**
         * an element can be in a removed state, these elements will be not part of the rendered graph
         */
        removed?: boolean;
    }

    interface ElementDataDefinition {
        /**
         * elided id => autogenerated id
         */
        id?: string;
        position?: Position;
    }

    interface EdgeDefinition extends ElementDefinition {
        group?: "edges";
        data: EdgeDataDefinition;
    }

    interface EdgeDataDefinition extends ElementDataDefinition {
        /**
         * the source node id (edge comes from this node)
         */
        source: string;
        /**
         * the target node id (edge goes to this node)
         */
        target: string;

        [key: string]: any;
    }

    interface NodeDefinition extends ElementDefinition {
        group?: "nodes";
        data: NodeDataDefinition;
    }

    interface NodeDataDefinition extends ElementDataDefinition {
        parent?: string;
        [key: string]: any;
    }

    interface CytoscapeOptions {
        ///////////////////////////////////////
        // very commonly used options:
        /**
         * A HTML DOM element in which the graph should be rendered.
         * This is optional if Cytoscape.js is run headlessly or if you initialise using jQuery (in which case your jQuery object already has an associated DOM element).
         *
         * The default is undefined.
         */
        container?: HTMLElement | null;

        /**
         * An array of [[Elements]] specified as plain objects. For convenience, this option can alternatively be specified as a promise that resolves to the elements JSON.
         */
        elements?:
            | ElementsDefinition
            | ElementDefinition[]
            | Promise<ElementsDefinition>
            | Promise<ElementDefinition[]>
           ;
        /**
         * The StylesheetJson (StylesheetJsonBlock[]) used to style the graph. For convenience, this option can alternatively be specified as a promise that resolves to the stylesheet.
         */
        style?: StylesheetJson | Promise<StylesheetJson>;
        /**
         * A plain object that specifies layout options.
         * Which layout is initially run is specified by the name field.
         * Refer to a layout's documentation for the options it supports.
         * If you want to specify your node positions yourself in your elements JSON,
         * you can use the preset layout — by default it does not set any positions,
         * leaving your nodes in their current positions
         * (e.g. specified in options.elements at initialisation time)
         */
        layout?: LayoutOptions;

        /**
         * A plain object that contains graph-level data (i.e. data that does not belong to any particular node or edge).
         */
        data?: Record<string, any>;

        ///////////////////////////////////////
        // initial viewport state:
        /**
         * The initial zoom level of the graph.
         * Make sure to disable viewport manipulation options, such as fit, in your layout so that it is not overridden when the layout is applied.
         * You can set options.minZoom and options.maxZoom to set restrictions on the zoom level.
         *
         * The default value is 1.
         */
        zoom?: number;
        /**
         * The initial panning position of the graph. Make sure to disable viewport manipulation options, such as fit,
         * in your layout so that it is not overridden when the layout is applied.
         */
        pan?: Position;

        ///////////////////////////////////////
        // interaction options?:
        /**
         * A minimum bound on the zoom level of the graph. The viewport can not be scaled smaller than this zoom level.
         *
         * The default value is 1e-50.
         */
        minZoom?: number;
        /**
         * A maximum bound on the zoom level of the graph. The viewport can not be scaled larger than this zoom level.
         *
         * The default value is 1e50.
         */
        maxZoom?: number;
        /**
         * Whether zooming the graph is enabled, both by user events and programmatically.
         *
         * The default value is true.
         */
        zoomingEnabled?: boolean;
        /**
         * Whether user events (e.g. mouse wheel, pinch-to-zoom) are allowed to zoom the graph. Programmatic changes to zoom are unaffected by this option.
         *
         * The default value is true.
         */
        userZoomingEnabled?: boolean;
        /**
         * Whether panning the graph is enabled, both by user events and programmatically.
         *
         * The default value is true.
         */
        panningEnabled?: boolean;
        /**
         * Whether user events (e.g. dragging the graph background) are allowed to pan the graph. Programmatic changes to pan are unaffected by this option.
         *
         * The default value is true.
         */
        userPanningEnabled?: boolean;
        /**
         * Whether box selection (i.e. drag a box overlay around, and release it to select) is enabled. If enabled, the user must taphold to pan the graph.
         *
         * The default value is false.
         */
        boxSelectionEnabled?: boolean;
        /**
         * A string indicating the selection behaviour from user input.
         * By default, this is set automatically for you based on the type of input device detected.
         * On touch devices, 'additive' is default — a new selection made by the user adds to the set of currenly selected elements.
         * On mouse-input devices, 'single' is default — a new selection made by the user becomes the entire set of currently selected elements (i.e. the previous elements are unselected).
         *
         * The default value is (isTouchDevice ? 'additive' : 'single').
         */
        selectionType?: SelectionType;
        /**
         * A nonnegative integer that indicates the maximum allowable distance that a user may move during a tap gesture,
         * on touch devices and desktop devices respectively.
         *
         * This makes tapping easier for users.
         * These values have sane defaults, so it is not advised to change these options unless you have very good reason for doing so.
         * Larger values will almost certainly have undesirable consequences.
         *
         * The default value is is 8.
         */
        touchTapThreshold?: number;
        /**
         * A nonnegative integer that indicates the maximum allowable distance that a user may move during a tap gesture,
         * on touch devices and desktop devices respectively.
         *
         * This makes tapping easier for users.
         * These values have sane defaults,
         * so it is not advised to change these options unless you have very good reason for doing so.
         * Larger values will almost certainly have undesirable consequences.
         *
         * The default value is 4.
         */
        desktopTapThreshold?: number;
        /**
         * Whether nodes should be locked (not draggable at all) by default (if true, overrides individual node state).
         *
         * The default value is false.
         */
        autolock?: boolean;
        /**
         * Whether nodes should be ungrabified (not grabbable by user) by default (if true, overrides individual node state).
         *
         * The default value is false.
         */
        autoungrabify?: boolean;
        /**
         * Whether nodes should be unselectified (immutable selection state) by default (if true, overrides individual element state).
         *
         * The default value is false.
         */
        autounselectify?: boolean;

        ///////////////////////////////////////
        // rendering options:
        /**
         * A convenience option that initialises the Core to run headlessly.
         * You do not need to set this in environments that are implicitly headless (e.g. Node.js).
         * However, it is handy to set headless: true if you want a headless Core in a browser.
         *
         * The default value is false.
         */
        headless?: boolean;
        /**
         * A boolean that indicates whether styling should be used.
         * For headless (i.e. outside the browser) environments,
         * display is not necessary and so neither is styling necessary — thereby speeding up your code.
         * You can manually enable styling in headless environments if you require it for a special case.
         * Note that it does not make sense to disable style if you plan on rendering the graph.
         *
         * The default value is true.
         */
        styleEnabled?: boolean;
        /**
         * When set to true, the renderer does not render edges while the viewport is being manipulated.
         * This makes panning, zooming, dragging, et cetera more responsive for large graphs.
         *
         * The default value is false.
         */
        hideEdgesOnViewport?: boolean;
        /**
         * when set to true, the renderer does not render labels while the viewport is being manipulated.
         * This makes panning, zooming, dragging, et cetera more responsive for large graphs.
         *
         * The default value is false.
         */
        hideLabelsOnViewport?: boolean;
        /**
         * When set to true, the renderer uses a texture (if supported) during panning and zooming instead of drawing the elements,
         * making large graphs more responsive.
         *
         * The default value is false.
         */
        textureOnViewport?: boolean;
        /**
         * When set to true, the renderer will use a motion blur effect to make the transition between frames seem smoother.
         * This can significantly increase the perceived performance for a large graphs.
         *
         * The default value is false.
         */
        motionBlur?: boolean;
        /**
         * When motionBlur: true, this value controls the opacity of motion blur frames.
         * Higher values make the motion blur effect more pronounced.
         *
         * The default value is 0.2.
         */
        motionBlurOpacity?: number;
        /**
         * Changes the scroll wheel sensitivity when zooming. This is a multiplicative modifier.
         * So, a value between 0 and 1 reduces the sensitivity (zooms slower), and a value greater than 1 increases the sensitivity (zooms faster).
         *
         * The default value is 1.
         */
        wheelSensitivity?: number;
        /**
         * Overrides the screen pixel ratio with a manually set value (1.0 or 0.666 recommended, if set).
         * This can be used to increase performance on high density displays by reducing the effective area that needs to be rendered.
         * If you want to use the hardware's actual pixel ratio at the expense of performance, you can set pixelRatio: 'auto'.
         *
         * The default value is 1.
         */
        pixelRatio?: number | "auto";

        /**
         * Enables the experimental WebGL mode.
         * WARNING: This is currently experimental, and may have API changes in future.
         */
        webgl?: boolean;

        /**
         * Prints debug info to the browser console.
         * (optional)
         * WARNING: This is currently experimental, and may have API changes in future.
         */
        webglDebug?: boolean;

        /**
         * The size of the WebGL texture.
         * (provisional, may change in future releases)
         * WARNING: This is currently experimental, and may have API changes in future.
         */
        webglTexSize?: number;

        /**
         * The number of rows in the WebGL texture.
         * (provisional, may change in future releases)
         * WARNING: This is currently experimental, and may have API changes in future.
         */
        webglTexRows?: number;

        /**
         * The batch size for WebGL.
         * (provisional, may change in future releases)
         * WARNING: This is currently experimental, and may have API changes in future.
         */
        webglBatchSize?: number;

        /**
         * The number of textures per batch in WebGL.
         * (provisional, may change in future releases)
         * WARNING: This is currently experimental, and may have API changes in future.
         */
        webglTexPerBatch?: number;
    }

    /**
     *  cy   --> Cy.Core
     *   The core object is your interface to a graph.
     *
     * It is your entry point to Cytoscape.js:
     * All of the library’s features are accessed through this object.
     * http://js.cytoscape.org/#core
     */
    interface Core
        extends
            CoreGraphManipulation,
            CoreData,
            CoreGraphManipulationExt,
            CoreEvents,
            CoreViewportManipulation,
            CoreAnimation,
            CoreLayout,
            CoreStyle,
            CoreExport
    {}

    /**
     * These are the principle functions used to interact with the graph model.
     *
     * http://js.cytoscape.org/#core/graph-manipulation
     */
    interface CoreGraphManipulation {
        /**
         * Add elements to the graph and return them.
         */
        add(
            eles: ElementDefinition | ElementDefinition[] | ElementsDefinition | CollectionArgument,
        ): CollectionReturnValue;

        /**
         * Remove elements in collection or match the selector from the graph and return them.
         */
        remove(eles: CollectionArgument | Selector): CollectionReturnValue;

        /**
         * Get a collection from elements in the graph matching the specified selector or from an array of elements.
         * If no parameter is specified, an empty collection will be returned
         * options The options for the collection
         * removed A truthy value that sets whether the elements are in the removed state (true) or added to the graph (false, default).
         */
        collection(
            eleObjs?: ElementDefinition[] | CollectionArgument | Selector,
            options?: {
                removed?: true;
            }
        ): CollectionReturnValue;

        /**
         * check whether the specified id is in the collection
         */
        hasElementWithId(id: string): boolean;

        /**
         * Get an element from its ID in a very performant way.
         * http://js.cytoscape.org/#cy.getElementById
         */
        getElementById(id: string): CollectionReturnValue;

        /**
         * Get an element from its ID in a very performant way.
         * http://js.cytoscape.org/#cy.getElementById
         */
        $id(id: string): CollectionReturnValue;

        /**
         * Get elements in the graph matching the specified selector.
         * http://js.cytoscape.org/#cy.$
         */
        $(selector: Selector): CollectionReturnValue;

        /**
         * Get elements in the graph matching the specified selector.
         * http://js.cytoscape.org/#cy.$
         */
        elements(selector?: Selector): CollectionReturnValue;

        /**
         * Get nodes in the graph matching the specified selector.
         */
        nodes(selector?: Selector): NodeCollection;

        /**
         * Get edges in the graph matching the specified selector.
         */
        edges(selector?: Selector): EdgeCollection;
        /**
         * Get elements in the graph matching the specified selector or filter function.
         */
        filter(
            selector: Selector | ((ele: Singular, i: number, eles: CollectionArgument) => boolean),
        ): CollectionReturnValue;

        /**
         * Allow for manipulation of elements without triggering multiple style calculations or multiple redraws.
         * http://js.cytoscape.org/#cy.batch
         *  A callback within which you can make batch updates to elements.
         */
        batch(callback: () => void): void;
        /**
         * Allow for manipulation of elements without triggering multiple style calculations or multiple redraws.
         * http://js.cytoscape.org/#cy.batch
         *
         * Starts batching manually (useful for asynchronous cases).
         */
        startBatch(): void;
        /**
         * Allow for manipulation of elements without triggering multiple style calculations or multiple redraws.
         * http://js.cytoscape.org/#cy.batch
         *
         * Ends batching manually (useful for asynchronous cases).
         */
        endBatch(): void;

        /**
         * Attaches the instance to the specified container for visualisation.
         * http://js.cytoscape.org/#cy.mount
         *
         * If the core instance is headless prior to calling cy.mount(), then
         * the instance will no longer be headless and the visualisation will
         * be shown in the specified container. If the core instance is
         * non-headless prior to calling cy.mount(), then the visualisation
         * is swapped from the prior container to the specified container.
         */
        mount(element: Element): void;

        /**
         * Remove the instance from its current container.
         * http://js.cytoscape.org/#cy.unmount
         *
         * This function sets the instance to be headless after unmounting from
         * the current container.
         */
        unmount(): void;

        /**
         * A convenience function to explicitly destroy the Core.
         * http://js.cytoscape.org/#cy.destroy
         */
        destroy(): void;

        /**
         * Get whether the instance of Cytoscape.js has been destroyed or not.
         * https://js.cytoscape.org/#cy.destroyed
         */
        destroyed(): boolean;
    }

    /**
     * https://js.cytoscape.org/#core/data
     */
    interface CoreData {
        /**
         * Read and write developer-defined data associated with the graph.
         * http://js.cytoscape.org/#cy.data
         */
        /**
         * Get the entire data object or a particular data field.
         * @alias attr
         *
         * @param name The name of the field to get.
         */
        data(name?: string): any;
        /**
         * Set a particular data field.
         * @alias attr
         *
         * @param name The name of the field to set.
         * @param value The value to set for the field (must be JSON-serializable).
         */
        data(name: string, value: any): this;
        /**
         * Update multiple data fields at once via an object.
         * @alias attr
         *
         * @param obj The object containing name-value pairs to update data fields (must be JSON-serializable).
         */
        data(obj: Record<string, any>): this;
        /**
         * Get the entire data object or a particular data field.
         *
         * @param name The name of the field to get. Get the entire data object
         */
        attr(name?: string): any;
        /**
         * Set a particular data field.
         *
         * @param name The name of the field to set.
         * @param value The value to set for the field  (must be JSON-serializable).
         */
        attr(name: string, value: any): this;
        /**
         * Update multiple data fields at once via an object.
         *
         * @param obj The object containing name-value pairs to update data fields.
         */
        attr(obj: Record<string, any>): this;

        /**
         * Remove developer-defined data associated with the elements.
         * https://js.cytoscape.org/#cy.removeData
         * @alias removeAttr
         *
         * @param names A space-separated list of fields to delete.
         */
        removeData(names?: string): this;
        /**
         * Remove developer-defined data associated with the elements.
         * https://js.cytoscape.org/#cy.removeData
         *
         * @param names A space-separated list of fields to delete.
         */
        removeAttr(names?: string): this;
    }

    /**
     * http://js.cytoscape.org/#core/graph-manipulation
     * http://js.cytoscape.org/#extensions
     * These functions are intended for use in extensions.
     */
    interface CoreGraphManipulationExt {
        /**
         * Set the scratchpad at a particular namespace,
         * where temporary or non-JSON data can be stored.
         * App-level scratchpad data should use namespaces prefixed with underscore, like '_foo'.
         *
         * If no parameter provided, the entire scratchpad will be returned.
         * If only namespace provided, the scratchpad with the namespace will be returned.
         *
         * @param namespace A namespace string.
         * @param value The value to set at the specified namespace.
         */
        scratch(namespace?: string): Scratchpad;
        scratch(namespace: string, value: any): this;

        /**
         * Remove scratchpad data. You should remove scratchpad data only at your own namespaces.
         * http://js.cytoscape.org/#cy.removeScratch
         *
         * @param namespace A namespace string.
         */
        removeScratch(namespace: string): this;
    }

    /**
     * The principle events from the graph model.
     *  http://js.cytoscape.org/#core/events
     */
    interface CoreEvents {
        /**
         * Bind to events that occur in the graph.
         *
         * @param events A space separated list of event names.
         * @param handler The handler function that is called when one of the specified events occurs.
         * @param selector A selector to specify elements for which the handler is triggered.
         * @param data A plain object which is passed to the handler in the event object argument.
         * @param eventsMap A map of event names to handler functions.
         */

        on(events: EventNames, handler: EventHandler): this;
        on(events: EventNames, selector: Selector, handler: EventHandler): this;
        on(events: EventNames, selector: Selector, data: any, handler: EventHandler): this;
        on(eventsMap: { [value: string]: EventHandler }, selector?: Selector, data?: any): this;

        bind(events: EventNames, handler: EventHandler): this;
        bind(events: EventNames, selector: Selector, handler: EventHandler): this;
        bind(events: EventNames, selector: Selector, data: any, handler: EventHandler): this;
        bind(eventsMap: { [value: string]: EventHandler }, selector?: Selector, data?: any): this;

        listen(events: EventNames, handler: EventHandler): this;
        listen(events: EventNames, selector: Selector, handler: EventHandler): this;
        listen(events: EventNames, selector: Selector, data: any, handler: EventHandler): this;
        listen(eventsMap: { [value: string]: EventHandler }, selector?: Selector, data?: any): this;

        addListener(events: EventNames, handler: EventHandler): this;
        addListener(events: EventNames, selector: Selector, handler: EventHandler): this;
        addListener(events: EventNames, selector: Selector, data: any, handler: EventHandler): this;
        addListener(eventsMap: { [value: string]: EventHandler }, selector?: Selector, data?: any): this;

        /**
         * Get a promise that is resolved with the first
         * of any of the specified events triggered on the graph.
         * @param events A space separated list of event names.
         * @param selector [optional] A selector to specify elements for which the handler is triggered.
         */
        promiseOn(events: EventNames, selector?: Selector): Promise<EventHandler>;
        pon(events: EventNames, selector?: Selector): Promise<EventHandler>;
        /**
         * Bind to events that occur in the graph, and trigger the handler only once.
         *
         * @param events A space separated list of event names.
         * @param handler The handler function that is called when one of the specified events occurs.
         */
        one(events: EventNames, handler: EventHandler): this;
        /**
         * Bind to events that occur in the graph, and trigger the handler only once.
         *
         * @param events A space separated list of event names.
         * @param handler The handler function that is called when one of the specified events occurs.
         * @param selector A selector to specify elements for which the handler is triggered.
         */
        one(events: EventNames, selector: Selector, handler: EventHandler): this;
        /**
         * Bind to events that occur in the graph, and trigger the handler only once.
         *
         * @param events A space separated list of event names.
         * @param handler The handler function that is called when one of the specified events occurs.
         * @param selector A selector to specify elements for which the handler is triggered.
         * @param data A plain object which is passed to the handler in the event object argument.
         */
        one(events: EventNames, selector: Selector, data: any, handler: EventHandler): this;
        /**
         * Bind to events that occur in the graph, and trigger the handler only once.
         *
         * @param eventsMap A map of event names to handler functions.
         * @param selector A selector to specify elements for which the handler is triggered.
         * @param data A plain object which is passed to the handler in the event object argument.
         */
        one(eventsMap: { [value: string]: EventHandler }, selector?: Selector, data?: any): this;

        /**
         * Remove event handlers.
         *  http://js.cytoscape.org/#cy.off
         *
         * @param events A space separated list of event names.
         * @param selector [optional] The same selector used to bind to the events.
         * @param handler [optional] A reference to the handler function to remove.
         * @param eventsMap A map of event names to handler functions to remove.
         */
        off(events: EventNames, handler?: EventHandler): this;
        off(events: EventNames, selector: Selector, handler?: EventHandler): this;
        off(eventsMap: { [value: string]: EventHandler }, selector?: Selector): this;

        unbind(events: EventNames, handler?: EventHandler): this;
        unbind(events: EventNames, selector: Selector, handler?: EventHandler): this;
        unbind(eventsMap: { [value: string]: EventHandler }, selector?: Selector): this;

        unlisten(events: EventNames, handler?: EventHandler): this;
        unlisten(events: EventNames, selector: Selector, handler?: EventHandler): this;
        unlisten(eventsMap: { [value: string]: EventHandler }, selector?: Selector): this;

        removeListener(events: EventNames, handler?: EventHandler): this;
        removeListener(events: EventNames, selector: Selector | undefined, handler?: EventHandler): this;
        removeListener(eventsMap: { [value: string]: EventHandler }, selector?: Selector): this;

        /**
         * Remove all event handlers.
         * https://js.cytoscape.org/#cy.removeAllListeners
         */
        removeAllListeners(): this;

        /**
         * Trigger one or more events.
         *
         * @param events A space separated list of event names to trigger.
         * @param extraParams [optional] An array of additional parameters to pass to the handler.
         */
        trigger(events: EventNames, extraParams?: any[]): this;
        emit(events: EventNames, extraParams?: any[]): this;

        /**
         * Run a callback as soon as the graph becomes ready. If the graph is already ready, then the callback is called immediately.
         * @param fn The callback run as soon as the graph is ready, inside which this refers to the core (cy).
         */
        ready(fn: EventHandler): this;
    }

    interface ZoomOptionsModel {
        /** The position about which to zoom. */
        position: Position;
    }
    interface ZoomOptionsRendered {
        /** The rendered position about which to zoom. */
        renderedPosition: Position;
    }
    interface ZoomOptionsLevel {
        /** The zoom level to set. */
        level: number;
    }
    type ZoomOptions = number | (ZoomOptionsLevel & (ZoomOptionsModel | ZoomOptionsRendered));

    /**
     * http://js.cytoscape.org/#core/viewport-manipulation
     */
    interface CoreViewportManipulation {
        /**
         * Get the HTML DOM element in which the graph is visualised.
         * A null value is returned if the Core is headless.
         */
        container(): HTMLElement | null;

        /**
         * Pan the graph to the centre of a collection.
         *
         * @param eles The collection to centre upon.
         */
        center(eles?: CollectionArgument): this;

        /**
         * Pan the graph to the centre of a collection.
         *
         * @param eles The collection to centre upon.
         */
        centre(eles?: CollectionArgument): this;

        /**
         * Pan and zooms the graph to fit to a collection.
         * http://js.cytoscape.org/#cy.fit
         *
         * @param eles [optional] The collection to fit to.
         * @param padding [optional] An amount of padding (in pixels) to have around the graph
         */
        fit(eles?: CollectionArgument | Selector, padding?: number): this;

        /**
         * Reset the graph to the default zoom level and panning position.
         * http://js.cytoscape.org/#cy.reset
         */
        reset(): this;

        /**
         * Get the panning position of the graph.
         * http://js.cytoscape.org/#cy.pan
         */
        pan(): Position;

        /**
         * Set the panning position of the graph.
         * http://js.cytoscape.org/#cy.pan
         *
         * @param renderedPosition The rendered position to pan the graph to.
         */
        pan(renderedPosition?: Position): this;

        /**
         * Relatively pan the graph by a specified rendered position vector.
         * http://js.cytoscape.org/#cy.panBy
         *
         * @param renderedPosition The rendered position vector to pan the graph by.
         */
        panBy(renderedPosition: Position): this;

        /**
         * Get whether panning is enabled.
         * If cy.boxSelectionEnabled() === true, then the user
         * must taphold to initiate panning.
         * http://js.cytoscape.org/#cy.panningEnabled
         */
        panningEnabled(): boolean;

        /**
         * Set whether panning is enabled. If cy.boxSelectionEnabled() === true, then the user must taphold to initiate panning.
         * http://js.cytoscape.org/#cy.panningEnabled
         *
         * @param bool A truthy value enables panning; a falsey value disables it.
         */
        panningEnabled(bool?: boolean): this;

        /**
         * Get whether panning by user events (e.g. dragging the graph background) is enabled. If cy.boxSelectionEnabled() === true, then the user must taphold to initiate panning.
         * http://js.cytoscape.org/#cy.userPanningEnabled
         */
        userPanningEnabled(): boolean;

        /**
         * Set whether panning by user events (e.g. dragging the graph background) is enabled. If cy.boxSelectionEnabled() === true, then the user must taphold to initiate panning.
         * http://js.cytoscape.org/#cy.userPanningEnabled
         *
         * @param bool A truthy value enables user panning; a falsey value disables it.
         */
        userPanningEnabled(bool?: boolean): this;
        /**
         * Get the zoom level.
         * http://js.cytoscape.org/#cy.zoom
         */
        zoom(): number;
        /**
         * Set the zoom level.
         * http://js.cytoscape.org/#cy.zoom
         *
         * @param level The zoom level to set.
         * @param options The options for zooming.
         */
        zoom(level?: number | ZoomOptions): this;

        /**
         * Set or get whether zooming is enabled. Get if no parameter provided.
         * http://js.cytoscape.org/#cy.zoomingEnabled
         *
         * @param bool A truthy value enables zooming; a falsey value disables it.
         */
        zoomingEnabled(bool?: boolean): this;

        /**
         * Get whether zooming by user events (e.g. mouse wheel, pinch-to-zoom)
         * is enabled.
         * http://js.cytoscape.org/#cy.userZoomingEnabled
         */
        userZoomingEnabled(): boolean;
        /**
         * Get or set whether zooming by user events get if no parameter provided
         * (e.g. mouse wheel, pinch-to-zoom) is enabled.
         * http://js.cytoscape.org/#cy.userZoomingEnabled
         *
         * @param bool A truthy value enables user zooming; a falsey value disables it.
         */
        userZoomingEnabled(bool?: boolean): this;

        /**
         * Get the minimum zoom level.
         * http://js.cytoscape.org/#cy.minZoom
         */
        minZoom(): number;
        /**
         * Set the minimum zoom level.
         * http://js.cytoscape.org/#cy.minZoom
         *
         * @param zoom The new minimum zoom level to use.
         */
        minZoom(zoom: number): this;

        /**
         * Get the maximum zoom level.
         * http://js.cytoscape.org/#cy.maxZoom
         */
        maxZoom(): number;
        /**
         * Set the maximum zoom level.
         * http://js.cytoscape.org/#cy.maxZoom
         *
         * @param zoom The new maximum zoom level to use.
         */
        maxZoom(zoom: number): this;

        /**
         * Set the viewport state (pan & zoom) in one call.
         * http://js.cytoscape.org/#cy.viewport
         *
         * @param options The viewport options.
         * @param options.zoom The zoom level to set.
         * @param options.pan The pan to set (a rendered position).
         */
        viewport(options: { zoom: number; pan: Position }): this;

        /**
         * gets the viewport state (pan & zoom) in one call.
         * http://js.cytoscape.org/#cy.viewport
         *
         */
        getFitViewport(): {
            zoom: number;
            pan: Position;
        };

        /**
         * Get whether box selection is enabled.
         * If enabled, the user must hold left-click to initiate panning.
         * http://js.cytoscape.org/#cy.boxSelectionEnabled
         */
        boxSelectionEnabled(): boolean;
        /**
         * Set whether box selection is enabled.
         * If enabled, the user must hold left-click to initiate panning.
         * http://js.cytoscape.org/#cy.boxSelectionEnabled
         *
         * @param bool A truthy value enables box selection; a falsey value disables it.
         */
        boxSelectionEnabled(bool?: boolean): this;

        /**
         * Get the selection type.
         * http://js.cytoscape.org/#cy.selectionType
         */
        selectionType(): SelectionType;
        /**
         * Set the selection type.
         * http://js.cytoscape.org/#cy.selectionType
         *
         * @param type The selection type string; one of 'single' (default) or 'additive'.
         */
        selectionType(type: SelectionType): this;

        /**
         * Get the on-screen width of the viewport in pixels.
         * http://js.cytoscape.org/#cy.width
         */
        width(): number;

        /**
         * Get the on-screen height of the viewport in pixels.
         * http://js.cytoscape.org/#cy.height
         */
        height(): number;

        /**
         * Get the extent of the viewport, a bounding box in model
         * coordinates that lets you know what model
         * positions are visible in the viewport.
         * http://js.cytoscape.org/#cy.extent
         */
        extent(): BoundingBox;

        /**
         * Get the rendered extent of the viewport, a bounding box in rendered
         * coordinates that lets you know what rendered
         * positions are visible in the viewport.
         * http://js.cytoscape.org/#cy.renderedExtent
         */
        renderedExtent(): BoundingBox;

        /**
         * Get whether nodes are automatically locked
         * (i.e. if true, nodes are locked despite their individual state).
         * http://js.cytoscape.org/#cy.autolock
         */
        autolock(): boolean;
        /**
         * Set whether nodes are automatically locked
         * (i.e. if true, nodes are locked despite their individual state).
         * http://js.cytoscape.org/#cy.autolock
         *
         * @param bool A truthy value enables autolocking; a falsey value disables it.
         */
        autolock(bool?: boolean): this;

        /**
         * Get whether nodes are automatically ungrabified
         * (i.e. if true, nodes are ungrabbale despite their individual state).
         * http://js.cytoscape.org/#cy.autoungrabify
         */
        autoungrabify(): boolean;
        /**
         * Set whether nodes are automatically ungrabified
         * (i.e. if true, nodes are ungrabbale despite their individual state).
         * http://js.cytoscape.org/#cy.autoungrabify
         *
         * @param bool A truthy value enables autolocking; a falsey value disables it.
         */
        autoungrabify(bool?: boolean): this;

        /**
         * Get whether nodes are automatically unselectified
         * (i.e. if true, nodes are unselectable despite their individual state).
         * http://js.cytoscape.org/#cy.autounselectify
         */
        autounselectify(): boolean;
        /**
         * Set whether nodes are automatically unselectified
         * (i.e. if true, nodes are unselectable despite their individual state).
         * http://js.cytoscape.org/#cy.autounselectify
         *
         * @param bool A truthy value enables autolocking; a falsey value disables it.
         */
        autounselectify(bool?: boolean): this;

        /**
         * Force the renderer to redraw (i.e. draw a new frame).
         *
         * This function forces the renderer to draw a new frame.
         * It is useful for very specific edgecases, such as in certain UI plugins,
         * but it should not be needed for most developers.
         * http://js.cytoscape.org/#cy.forceRender
         */
        forceRender(): this;

        /**
         * Force the renderer to recalculate the viewport bounds.
         *
         * If your code resizes the graph's dimensions or position
         * (i.e. by changing the style of the HTML DOM element that holds the graph),
         * you will want to call cy.resize() to have the graph resize and redraw itself.
         *
         * Cytoscape.js can not automatically monitor the bounding box of the viewport,
         * as querying the DOM for those dimensions can be expensive.
         * Although cy.resize() is automatically called for you on the window's resize event,
         * there is no resize or style event for arbitrary DOM elements.
         * http://js.cytoscape.org/#cy.resize
         */
        resize(): this;
        invalidateDimensions(): this;
    }

    /**
     * http://js.cytoscape.org/#core/animation
     */
    interface AnimationFitOptions {
        eles: CollectionArgument | Selector; // to which the viewport will be fitted.
        padding: number; //  Padding to use with the fitting.
    }
    interface CenterOptions {
        eles: CollectionArgument | Selector; // to which the viewport will be selected.
    }
    interface AnimationOptions {
        /** A zoom level to which the graph will be animated. */
        zoom?: ZoomOptions;
        /** A panning position to which the graph will be animated. */
        pan?: Position;
        /** A relative panning position to which the graph will be animated. */
        panBy?: Position;
        /** An object containing fitting options from which the graph will be animated. */
        fit?: AnimationFitOptions;
        /** An object containing centring options from which the graph will be animated. */
        center?: CenterOptions;
        /** easing - A transition-timing-function easing style string that shapes the animation progress curve. */
        easing?: Css.TransitionTimingFunction;

        /** duration - The duration of the animation in milliseconds. */
        duration?: number;
    }
    interface AnimateOptions extends AnimationOptions {
        /** queue - A boolean indicating whether to queue the animation. */
        queue?: boolean;
        /** complete - A function to call when the animation is done. */
        complete?(): void;
        /** step - A function to call each time the animation steps. */
        step?(): void;
    }

    interface CoreAnimation {
        /**
         * Get whether the viewport is currently being animated.
         * http://js.cytoscape.org/#cy.animated
         */
        animated(): boolean;

        /**
         * Animate the viewport.
         * http://js.cytoscape.org/#cy.animate
         *
         * @param anis An object containing the details of the animation.
         *
         * @param options An object containing animation options.
         */
        animate(anis: AnimateOptions, options?: AnimateOptions): Core;

        /**
         * Get an animation of the viewport.
         * http://js.cytoscape.org/#cy.animation
         */
        animation(options: AnimationOptions): AnimationManipulation;

        /**
         * Add a delay between animations for the viewport.
         *
         * @param duration How long the delay should be in milliseconds.
         * @param complete A function to call when the delay is complete.
         */
        delay(duration: number, complete?: () => void): Core;

        /**
         * Get a delay animation of the viewport.
         * http://js.cytoscape.org/#cy.delayAnimation
         */
        delayAnimation(duration: number): AnimationManipulation;

        /**
         * Stop all viewport animations that are currently running.
         * http://js.cytoscape.org/#cy.stop
         *
         * @param clearQueue A boolean, indicating whether the queue of animations should be emptied.
         * @param jumpToEnd A boolean, indicating whether the currently-running animations should jump to their ends rather than just stopping midway.
         */
        stop(clearQueue?: boolean, jumpToEnd?: boolean): Core;

        /**
         * Remove all queued animations for the viewport.
         * http://js.cytoscape.org/#cy.clearQueue
         */
        clearQueue(): Core;
    }

    /**
     * http://js.cytoscape.org/#core/layout
     */
    interface CoreLayout {
        /**
         * Run a layout, which algorithmically positions the nodes in the graph.
         * For layouts included with Cytoscape.js, you can find their
         * options documented in the Layouts section.
         * For external layouts, please refer to their accompanying documentation.
         *
         * An analogue to run a layout on a subset of the graph exists as eles.layout().
         * http://js.cytoscape.org/#cy.layout
         */
        layout(layout: LayoutOptions): Layouts;
        /**
         * Get a new layout, which can be used to algorithmically
         * position the nodes in the graph.
         *
         * You must specify options.name with the name of the layout you wish to use.
         *
         * This function creates and returns a layout object.
         * You may want to keep a reference to the layout for more advanced usecases,
         * such as running multiple layouts simultaneously.
         * Note that you must call layout.run() in order for it to affect the graph.
         * An analogue to make a layout on a subset of the graph exists as eles.makeLayout().
         */
        makeLayout(options: LayoutOptions): Layouts;
        createLayout(options: LayoutOptions): Layouts;
    }

    /**
     * Get the entry point to modify the visual style of the graph after initialisation.
     * http://js.cytoscape.org/#core/style
     */
    interface ElementStylesheetStyle extends StylesheetStyle {
        json(): any;
    }
    interface ElementStylesheetCSS extends StylesheetCSS {
        json(): any;
    }

    interface CoreStyle {
        /**
         * Assign a new stylesheet to replace the existing one (if provided)
         * and return the style.
         */
        style(sheet?: StylesheetJsonBlock | StylesheetJsonBlock[] | string): Style;
    }

    interface Style {
        /**
         * Add a rule to the stylesheet.
         */
        append(style: string | StylesheetJsonBlock | StylesheetJsonBlock[]): this;

        /**
         * Remove all styles, including default styles.
         */
        clear(): this;

        /**
         * Set the style from JSON data.
         * @example
         * style.fromJson([
         *   {
         *     selector: 'node',
         *     style: {
         *       'background-color': 'red'
         *     }
         *   }
         * ]);
         */
        fromJson(json: any): this;

        /**
         * Set the style from a string.
         * @example
         * style.fromString('node { background-color: blue; }');
         */
        fromString(style: string): this;

        /**
         * Resets to the default stylesheet.
         */
        resetToDefault(): this;

        /**
         * Sets the selector context for defining styles.
         * @example
         * style.selector('foo').style('color', 'black');
         */
        selector(s: string): this;

        /**
         * Sets a style for the current selected selector.
         * @example
         * style.selector('foo').style('color', 'black');
         */
        style(key: string, value: string | number): this;

        /**
         * Sets a style for the current selected selector.
         * @example
         * style.selector('foo').style({color: 'black'});
         */
        style(css: Css.Node | Css.Edge): this;

        /**
         * Makes the changes active.
         */
        update(): void;
    }

    /**
     * http://js.cytoscape.org/#cy.style
     */
    type StylesheetJsonBlock = StylesheetStyle | StylesheetCSS;
    type StylesheetJson = StylesheetJsonBlock[];

    interface StylesheetStyle {
        selector: string;
        style: Css.Node | Css.Edge | Css.Core;
    }

    /**
     * http://js.cytoscape.org/#cy.style
     */
    interface StylesheetCSS {
        selector: string;
        css: Css.Node | Css.Edge | Css.Core;
    }

    /**
     * http://js.cytoscape.org/#core/export
     */
    interface ExportOptions {
        /**
         * The background colour of the image (transparent by default).
         */
        bg?: string;
        /**
         * Whether to export the current viewport view (false, default) or the entire graph (true).
         */
        full?: boolean;
        /**
         * This value specifies a positive number that scales the size of the resultant image.
         */
        scale?: number;
        /**
         * Specifies the scale automatically in combination with maxHeight such that the resultant image is no wider than maxWidth.
         */
        maxWidth?: number;
        /**
         * Specifies the scale automatically in combination with maxWidth such that the resultant image is no taller than maxHeight.
         */
        maxHeight?: number;
    }
    interface ExportStringOptions extends ExportOptions {
        /**
         * output Whether the output should be 'base64uri' (default), 'base64', or 'blob'.
         */
        output?: "base64uri" | "base64";
    }
    interface ExportBlobOptions extends ExportOptions {
        /**
         * output Whether the output should be 'base64uri' (default), 'base64', or 'blob'.
         */
        output?: "blob";
    }

    interface ExportBlobPromiseOptions extends ExportOptions {
        /**
         * output Whether the output should be 'base64uri' (default), 'base64', 'blob', or 'blob-promise'.
         */
        output?: "blob-promise";
    }

    interface ExportJpgOptions extends ExportOptions {
        /**
         * quality Specifies the quality of the image from 0
         * (low quality, low filesize) to 1 (high quality, high filesize).
         * If not set, the browser's default quality value is used.
         */
        quality?: number;
    }

    interface ExportJpgStringOptions extends ExportJpgOptions, ExportStringOptions {}

    interface ExportJpgBlobOptions extends ExportJpgOptions, ExportBlobOptions {}

    interface ExportJpgBlobPromiseOptions extends ExportJpgOptions, ExportBlobPromiseOptions {}

    interface CoreExport {
        /**
         * Export the current graph view as a PNG image in Base64 representation.
         */
        png(options?: ExportStringOptions): string;
        png(options?: ExportBlobOptions): Blob;
        png(options?: ExportBlobPromiseOptions): Promise<Blob>;

        /**
         * Export the current graph view as a JPG image in Base64 representation.
         */
        jpg(options?: ExportJpgStringOptions): string;
        jpg(options?: ExportJpgBlobOptions): Blob;
        jpg(options?: ExportJpgBlobPromiseOptions): Promise<Blob>;

        /**
         * Export the current graph view as a JPG image in Base64 representation.
         */
        jpeg(options?: ExportJpgStringOptions): string;
        jpeg(options?: ExportJpgBlobOptions): Blob;
        jpeg(options?: ExportJpgBlobPromiseOptions): Promise<Blob>;

        /**
         * Export the graph as JSON, the same format used at initialisation.
         */
        json(): {
            elements: {
                nodes?: ElementDefinition[];
                edges?: ElementDefinition[];
            };
        } & Record<string, any>;

        json(
            json: {
                elements:
                    | {
                    nodes?: ElementDefinition[];
                    edges?: ElementDefinition[];
                }
                    | ElementDefinition[];
            } & Record<string, any>
        ): this;
    }

    /**
     * eles --> Cy.Collection
     *  a collection of one or more elements (nodes and edges)
     *
     * The input can be any element (node and edge) collection.
     * http://js.cytoscape.org/#collection
     */
    interface Collection<TOut = SingularElementReturnValue, TIn = SingularElementArgument>
        extends
            CollectionGraphManipulation,
            CollectionEvents,
            CollectionData,
            CollectionPosition,
            CollectionTraversing,
            CollectionLayout,
            CollectionSelection,
            CollectionStyle,
            CollectionAnimation,
            CollectionComparision,
            CollectionIteration<TIn, TOut>,
            CollectionBuildingFiltering<TIn, TOut>,
            CollectionAlgorithms
    {}

    /**
     * ele  --> Cy.Singular
     * a collection of a single element (node or edge)
     * NB: every singular collection is a general collection too (but not vice versa)!
     */
    interface Singular<TOut = SingularElementReturnValue, TIn = SingularElementArgument>
        extends
            Collection<TOut, TIn>,
            SingularGraphManipulation,
            SingularData,
            SingularPosition,
            SingularSelection,
            SingularStyle,
            SingularAnimation
    {}

    interface ElementsDefinition {
        nodes: NodeDefinition[];
        edges: EdgeDefinition[];
    }

    type EventHandler = (event: EventObject, ...extraParams: any) => void;

    /**
     * The output is a collection of node and edge elements OR single element.
     */
    type CollectionArgument = Collection | EdgeCollection | NodeCollection | SingularElementArgument;
    type CollectionReturnValue = Collection & EdgeCollection & NodeCollection & SingularElementReturnValue;

    /**
     * edges -> Cy.EdgeCollection
     *  a collection of one or more edges
     *
     * The output is a collection of edge elements OR single edge.
     */
    interface EdgeCollection extends Collection<EdgeSingular, EdgeSingular>, EdgeCollectionTraversing {}
    /**
     *  nodes -> Cy.NodeCollection
     *  a collection of one or more nodes
     *
     * The output is a collection of node elements OR single node.
     */
    interface NodeCollection
        extends
            Collection<NodeSingular, NodeSingular>,
            NodeCollectionMetadata,
            NodeCollectionPosition,
            NodeCollectionTraversing,
            NodeCollectionCompound,
            NodeCollectionLayout
    {}

    type SingularElementArgument = EdgeSingular | NodeSingular;
    type SingularElementReturnValue = EdgeSingular & NodeSingular;
    /**
     *  edge --> Cy.EdgeSingular
     *  a collection of a single edge
     */
    interface EdgeSingular
        extends
            Singular<EdgeSingular, EdgeSingular>,
            EdgeCollection,
            EdgeSingularData,
            EdgeSingularPoints,
            EdgeSingularTraversing
    {}

    /**
     *  node --> Cy.NodeSingular
     *  a collection of a single node
     */
    interface NodeSingular
        extends
            Singular<NodeSingular, NodeSingular>,
            NodeCollection,
            NodeSingularMetadata,
            NodeSingularPosition,
            NodeSingularCompound,
            NodeSingularLayout
    {}

    /**
     * http://js.cytoscape.org/#collection/graph-manipulation
     */
    interface CollectionGraphManipulation {
        /**
         * Remove the elements from the graph.
         * http://js.cytoscape.org/#eles.remove
         */
        remove(): CollectionReturnValue;

        /**
         * Put removed elements back into the graph.
         * http://js.cytoscape.org/#eles.restore
         */
        restore(): CollectionReturnValue;

        /**
         * Get a new collection containing clones (i.e. copies) of the elements in the calling collection.
         * http://js.cytoscape.org/#eles.clone
         */
        clone(): CollectionReturnValue;
        /**
         * Get a new collection containing clones (i.e. copies) of the elements in the calling collection.
         * http://js.cytoscape.org/#eles.clone
         */
        copy(): CollectionReturnValue;

        /**
         * Effectively move edges to different nodes. The modified (actually new) elements are returned.
         * http://js.cytoscape.org/#eles.move
         */
        move(location: { source?: string; target?: string }): EdgeCollection;
        /**
         * Effectively move nodes to different parent node. The modified (actually new) elements are returned.
         * http://js.cytoscape.org/#eles.move
         */
        move(location: { parent: string | null }): NodeCollection;
    }

    /**
     * http://js.cytoscape.org/#collection/graph-manipulation
     */
    interface SingularGraphManipulation {
        /**
         * Get the core instance that owns the element.
         */
        cy(): Core;
        /**
         * Get whether the element has been removed from the graph.
         * http://js.cytoscape.org/#ele.removed
         */
        removed(): boolean;
        /**
         * Get whether the element is inside the graph (i.e. not removed).
         * http://js.cytoscape.org/#ele.inside
         */
        inside(): boolean;
    }

    /**
     * http://js.cytoscape.org/#collection/events
     */
    interface CollectionEvents {
        /**
         * http://js.cytoscape.org/#eles.on
         * @param events A space separated list of event names.
         * @param selector [optional] A delegate selector to specify child elements for which the handler runs.
         * @param data  extra data given to the handler.
         * @param handler The handler function called when one of the specified events occurs. Takes the event object as a parameter.
         */
        on(events: EventNames, selector: string, data: any, handler: EventHandler): this;
        on(events: EventNames, selector: string, handler: EventHandler): this;
        on(events: EventNames, handler: EventHandler): this;
        bind(events: EventNames, selector: string, data: any, handler: EventHandler): this;
        bind(events: EventNames, selector: string, handler: EventHandler): this;
        bind(events: EventNames, handler: EventHandler): this;
        listen(events: EventNames, selector: string, data: any, handler: EventHandler): this;
        listen(events: EventNames, selector: string, handler: EventHandler): this;
        listen(events: EventNames, handler: EventHandler): this;
        addListener(events: EventNames, selector: string, data: any, handler: EventHandler): this;
        addListener(events: EventNames, selector: string, handler: EventHandler): this;
        addListener(events: EventNames, handler: EventHandler): this;

        /**
         * http://js.cytoscape.org/#eles.promiseOn
         * @alias pon
         */
        promiseOn(events: EventNames, selector?: string): Promise<EventHandler>;
        pon(events: EventNames, selector?: string): Promise<EventHandler>;

        /**
         * @param events A space separated list of event names.
         * @param selector [optional] A delegate selector to specify child elements for which the handler is triggered.
         * @param data [optional] A plain object which is passed to the handler in the event object argument.
         * @param function(event) The handler function that is called when one of the specified events occurs.
         * @param event The event object.
         * http://js.cytoscape.org/#eles.one
         */
        one(events: EventNames, selector: string, data: any, handler: EventHandler): this;
        one(events: EventNames, selector: string, handler: EventHandler): this;
        one(events: EventNames, handler: EventHandler): this;
        /**
         * http://js.cytoscape.org/#eles.once
         */
        once(events: EventNames, selector: string, data: any, handler: EventHandler): this;
        once(events: EventNames, selector: string, handler: EventHandler): this;
        once(events: EventNames, handler: EventHandler): this;
        /**
         * http://js.cytoscape.org/#eles.off
         * @alias unbind, unlisten, removeListener
         */
        off(events: EventNames, selector?: string, handler?: EventHandler): this;
        unbind(events: EventNames, selector?: string, handler?: EventHandler): this;
        unlisten(events: EventNames, selector?: string, handler?: EventHandler): this;
        removeListener(events: EventNames, selector?: string, handler?: EventHandler): this;
        /**
         * https://js.cytoscape.org/#eles.removeAllListeners
         */
        removeAllListeners(): this;
        /**
         * http://js.cytoscape.org/#eles.trigger
         * @alias emit
         */
        trigger(events: EventNames, extra?: unknown[]): this;
        emit(events: EventNames, extra?: unknown[]): this;
    }

    /**
     * http://js.cytoscape.org/#collection/data
     *
     * The following fields are immutable:
     * id: The id field is used to uniquely identify an element in the graph.
     * source & target : These fields define an edge's relationship to nodes, and this relationship can not be changed after creation.
     * parent: The parent field defines the parent (compound) node.
     */
    interface CollectionData {
        /**
         * Read and write developer-defined data associated with the elements
         * http://js.cytoscape.org/#eles.data
         */

        /**
         * Get a particular data field for the element.
         * @param name The name of the field to get.
         */
        data(name?: string): any;
        /**
         * Set a particular data field for the element.
         * @param name The name of the field to set.
         * @param value The value to set for the field  (must be JSON-serializable).
         */
        data(name: string, value: any): this;
        /**
         * Update multiple data fields at once via an object.
         * @param obj The object containing name- value pairs to update data fields  (must be JSON-serializable).
         */
        data(obj: any): this;
        /**
         * Get a particular data field for the element.
         * @param name The name of the field to get.
         */
        attr(name?: string): any;
        /**
         * Set a particular data field for the element.
         * @param name The name of the field to set.
         * @param value The value to set for the field  (must be JSON-serializable).
         */
        attr(name: string, value: any): this;
        /**
         * Update multiple data fields at once via an object.
         * @param obj The object containing name- value pairs to update data fields.
         */
        attr(obj: any): this;

        /**
         * Remove developer-defined data associated with the elements.
         * http://js.cytoscape.org/#eles.removeData
         * @param names A space-separated list of fields to delete.
         */
        removeData(...names: string[]): CollectionReturnValue;
        removeAttr(...names: string[]): CollectionReturnValue;

        /**
         * Get an array of the plain JavaScript object
         * representation of all elements in the collection.
         */
        jsons(): Record<string, any>[];
    }
    /**
     * http://js.cytoscape.org/#collection/data
     */
    interface SingularData {
        /**
         * Get or set the scratchpad at a particular namespace,
         * where temporary or non-JSON data can be stored.
         * Get scratchpad if one or no parameter provided.
         * App-level scratchpad data should use namespaces
         * prefixed with underscore, like '_foo'.
         * http://js.cytoscape.org/#ele.scratch
         * @param namespace A namespace string.
         * @param value The value to set at the specified namespace.
         */
        scratch(namespace?: string): Scratchpad;
        scratch(namespace: string, value: any): this;

        /**
         * Remove scratchpad data.
         * You should remove scratchpad data only at your own namespaces.
         * http://js.cytoscape.org/#ele.removeScratch
         * @param namespace A namespace string.
         */
        removeScratch(namespace: string): this;

        /**
         * A shortcut to get the ID of an element.
         * http://js.cytoscape.org/#ele.id
         */
        id(): string;

        /**
         * Get the or set with element's plain JavaScript object representation
         * http://js.cytoscape.org/#ele.json
         */
        json(obj?: Record<string, any>): Record<string, any>;

        /**
         * Get the group string that defines the type of the element.
         *
         * The group strings are 'nodes' for nodes and 'edges' for edges.
         * In general, you should be using ele.isEdge()
         * and ele.isNode() instead of ele.group().
         * http://js.cytoscape.org/#ele.group
         */
        group(): ElementGroup;

        /**
         * Get whether the element is a node.
         * http://js.cytoscape.org/#ele.isNode
         */
        isNode(): this is NodeSingular;

        /**
         * Get whether the element is an edge.
         * http://js.cytoscape.org/#ele.isEdge
         */
        isEdge(): this is EdgeSingular;

        /**
         * Get the connected component for the calling element.
         * The component considers all elements in the graph.
         * http://js.cytoscape.org/#ele.component
         */
        component(): CollectionReturnValue;
    }
    /**
     * http://js.cytoscape.org/#collection/data
     */
    interface EdgeSingularData {
        /**
         * Get whether the edge is a loop (i.e. source same as target).
         * http://js.cytoscape.org/#edge.isLoop
         */
        isLoop(): boolean;

        /**
         * Get whether the edge is simple (i.e. source different than target).
         * http://js.cytoscape.org/#edge.isSimple
         */
        isSimple(): boolean;
    }

    /**
     * http://js.cytoscape.org/#collection/metadata
     */
    interface NodeSingularMetadata {
        /**
         * Get the degree of a node.
         * @param includeLoops A boolean, indicating whether loops are to be included in degree calculations.
         */
        degree(includeLoops?: boolean): number;
        /**
         * Get the indegree of a node.
         * @param includeLoops A boolean, indicating whether loops are to be included in degree calculations.
         */
        indegree(includeLoops?: boolean): number;
        /**
         * Get the outdegree of a node.
         * @param includeLoops A boolean, indicating whether loops are to be included in degree calculations.
         */
        outdegree(includeLoops?: boolean): number;
    }

    /**
     * http://js.cytoscape.org/#collection/metadata
     */
    interface NodeCollectionMetadata {
        /**
         * Get the total degree of a collection of nodes.
         * @param includeLoops A boolean, indicating whether loops are to be included in degree calculations.
         */
        totalDegree(includeLoops?: boolean): number;

        /**
         * Get the minimum degree of the nodes in the collection.
         * @param includeLoops A boolean, indicating whether loops are to be included in degree calculations.
         */
        minDegree(includeLoops?: boolean): number;

        /**
         * Get the maximum degree of the nodes in the collection.
         * @param includeLoops A boolean, indicating whether loops are to be included in degree calculations.
         */
        maxDegree(includeLoops?: boolean): number;

        /**
         * Get the minimum indegree of the nodes in the collection.
         * @param includeLoops A boolean, indicating whether loops are to be included in degree calculations.
         */
        minIndegree(includeLoops?: boolean): number;

        /**
         * Get the maximum indegree of the nodes in the collection.
         * @param includeLoops A boolean, indicating whether loops are to be included in degree calculations.
         */
        maxIndegree(includeLoops?: boolean): number;

        /**
         * Get the minimum outdegree of the nodes in the collection.
         * @param includeLoops A boolean, indicating whether loops are to be included in degree calculations.
         */
        minOutdegree(includeLoops?: boolean): number;

        /**
         * Get the maximum outdegree of the nodes in the collection.
         * @param includeLoops A boolean, indicating whether loops are to be included in degree calculations.
         */
        maxOutdegree(includeLoops?: boolean): number;
    }

    /**
     * http://js.cytoscape.org/#collection/position--dimensions
     */
    interface NodeSingularPosition {
        /**
         * Get the (model) position of a node.
         */
        position(): Position;
        /**
         * Get the value of a specified position dimension.
         * @param dimension The position dimension to set.
         * @param value The value to set to the dimension.
         */
        position(dimension: PositionDimension): number;
        /**
         * Set the value of a specified position dimension.
         * @param dimension The position dimension to set.
         * @param value The value to set to the dimension.
         */
        position(dimension: PositionDimension, value: number): this;
        /**
         * Set the position using name-value pairs in the specified object.
         * @param pos An object specifying name-value pairs representing dimensions to set.
         */
        position(pos: Position): this;
        /**
         * Get the (model) position of a node.
         */
        modelPosition(): Position;
        /**
         * Get the value of a specified position dimension.
         * @param dimension The position dimension to set.
         * @param value The value to set to the dimension.
         */
        modelPosition(dimension: PositionDimension): number;
        /**
         * Set the value of a specified position dimension.
         * @param dimension The position dimension to set.
         * @param value The value to set to the dimension.
         */
        modelPosition(dimension: PositionDimension, value: number): this;
        /**
         * Set the position using name-value pairs in the specified object.
         * @param pos An object specifying name-value pairs representing dimensions to set.
         */
        modelPosition(pos: Position): this;
        /**
         * Get the (model) position of a node.
         */
        point(): Position;
        /**
         * Get the value of a specified position dimension.
         * @param dimension The position dimension to set.
         * @param value The value to set to the dimension.
         */
        point(dimension: PositionDimension): number;
        /**
         * Set the value of a specified position dimension.
         * @param dimension The position dimension to set.
         * @param value The value to set to the dimension.
         */
        point(dimension: PositionDimension, value: number): this;
        /**
         * Set the position using name-value pairs in the specified object.
         * @param pos An object specifying name-value pairs representing dimensions to set.
         */
        point(pos: Position): this;

        /**
         * Get or set the rendered (on-screen) position of a node.
         * http://js.cytoscape.org/#node.renderedPosition
         */
        /**
         * Get the value of a specified rendered position dimension.
         * @param dimension The position dimension to get.
         * @param value The value to set to the dimension.
         * @param pos An object specifying name-value pairs representing dimensions to set.
         */
        renderedPosition(dimension?: PositionDimension): Position;
        renderedPosition(dimension: PositionDimension, value: Position): this;
        renderedPosition(pos: { [name: string]: number }): this;

        /**
         * Set the value of a specified rendered position dimension.
         * @param dimension The position dimension to set.
         * @param value The value to set to the dimension.
         * @param pos An object specifying name-value pairs representing dimensions to set.
         */
        renderedPoint(dimension?: PositionDimension): Position;
        renderedPoint(dimension: PositionDimension, value: Position): this;
        renderedPoint(pos: { [name: string]: number }): this;

        /**
         * http://js.cytoscape.org/#node.relativePosition
         */
        /**
         * Get the value of a specified relative position dimension.
         * @param dimension The position dimension to get.
         * @param value The value to set to the dimension.
         * @param pos An object specifying name-value pairs representing dimensions to set.
         */
        relativePosition(dimension?: PositionDimension): Position;
        relativePosition(dimension: PositionDimension, value: Position): this;
        relativePosition(pos: { [name: string]: number }): this;

        /**
         * Get the value of a specified relative position dimension.
         * @param dimension The position dimension to get.
         * @param value The value to set to the dimension.
         * @param pos An object specifying name-value pairs representing dimensions to set.
         */
        relativePoint(dimension?: PositionDimension): Position;
        relativePoint(dimension: PositionDimension, value: Position): this;
        relativePoint(pos: { [name: string]: number }): this;

        /**
         * Get whether a node is currently grabbed, meaning the user has hold of the node.
         * http://js.cytoscape.org/#node.grabbed
         */
        grabbed(): boolean;
        /**
         * Get whether the user can grab a node.
         * http://js.cytoscape.org/#node.grabbable
         */
        grabbable(): boolean;
        /**
         * Get whether a node is locked, meaning that its position can not be changed.
         * http://js.cytoscape.org/#node.locked
         */
        locked(): boolean;
    }

    /**
     * @param ele The element being iterated over for which the function should return a position to set.
     * @param ix The index of the element when iterating over the elements in the collection.
     */
    type ElementPositionFunction = (ele: NodeSingular, ix: number) => Position;
    type ElementCollectionFunction = (ele: NodeSingular, ix: number, eles: CollectionArgument) => Position;

    /**
     * http://js.cytoscape.org/#collection/position--dimensions
     */
    interface NodeCollectionPosition {
        /**
         * Shift the positions of the nodes by a given model position vector.
         * @param dimension The position dimension to shift.
         * @param value The value to shift the dimension.
         */
        shift(dimension: PositionDimension, value?: number): this;
        /**
         * Shift the positions of the nodes by a given model position vector.
         * @param pos An object specifying name-value pairs representing dimensions to shift.
         */
        shift(pos: Position): this;

        /**
         * Set the positions via a function.
         * @param handler A callback function that returns the position to set for each element.
         * @param pos An object specifying name-value pairs representing dimensions to set.
         * http://js.cytoscape.org/#nodes.positions
         */
        positions(handler: ElementPositionFunction | Position): this;
        modelPositions(handler: ElementPositionFunction | Position): this;
        points(handler: ElementPositionFunction | Position): this;

        /**
         * Allow the user to grab the nodes.
         * http://js.cytoscape.org/#nodes.grabify
         */
        grabify(): this;
        /**
         * Disallow the user to grab the nodes.
         * http://js.cytoscape.org/#nodes.ungrabify
         */
        ungrabify(): this;
        /**
         * Lock the nodes such that their positions can not be changed.
         * http://js.cytoscape.org/#nodes.lock
         */
        lock(): this;
        /**
         * Unlock the nodes such that their positions can be changed.
         * http://js.cytoscape.org/#nodes.unlock
         */
        unlock(): this;

        /**
         * Gets whether the element allows passthrough panning.
         * http://js.cytoscape.org/#ele.pannable
         */
        pannable(): boolean;

        /**
         * Enables passthrough panning on the elements.
         * http://js.cytoscape.org/#eles.panify
         */
        panify(): this;

        /**
         * Disables passthrough panning on the elements.
         * http://js.cytoscape.org/#eles.unpanify
         */
        unpanify(): this;
    }
    /**
     * http://js.cytoscape.org/#collection/position--dimensions
     */
    interface SingularPosition {
        /**
         * Get the width of the element.
         */
        width(): number;
        /**
         * Get the outer width of the element (includes width, padding, & border).
         */
        outerWidth(): number;

        /**
         * Get the width of the element in rendered dimensions.
         */
        renderedWidth(): number;

        /**
         * Get the outer width of the element (includes width, padding, & border) in rendered dimensions.
         */
        renderedOuterWidth(): number;

        /**
         * Get the height of the element.
         */
        height(): number;
        /**
         * Get the outer height of the element (includes height, padding, & border).
         */
        outerHeight(): number;
        /**
         * Get the height of the element in rendered dimensions.
         */
        renderedHeight(): number;

        /**
         * Get the outer height of the element (includes height, padding, & border) in rendered dimensions.
         */
        renderedOuterHeight(): number;
        /**
         * Gets whether the element is active (e.g. on user tap, grab, etc).
         * http://js.cytoscape.org/#ele.active
         */
        active(): boolean;
    }

    interface BoundingBoxOptions {
        /** A boolean indicating whether to include nodes in the bounding box (default true). */
        includeNodes?: boolean;
        /** A boolean indicating whether to include edges in the bounding box (default true). */
        includeEdges?: boolean;
        /** A boolean indicating whether to include labels in the bounding box (default true). */
        includeLabels?: boolean;
        /** A boolean indicating whether to include main (node or edge) labels in the bounding box (default true). */
        includeMainLabels?: boolean;
        /** A boolean indicating whether to include (edge) source-labels in the bounding box (default true). */
        includeSourceLabels?: boolean;
        /** A boolean indicating whether to include (edge) target-labels in the bounding box (default true). */
        includeTargetLabels?: boolean;
        /** A boolean indicating whether to include overlays (such as the one which appears when a node is clicked) in the bounding box (default true). */
        includeOverlays?: boolean;
        /** A boolean indicating whether to include underlays in the bounding box (default: true). */
        includeUnderlays?: boolean;
    }
    /**
     * http://js.cytoscape.org/#collection/position--dimensions
     */
    interface CollectionPosition {
        /**
         * Get the bounding box of the elements in model coordinates.
         * @param options An object containing options for the function.
         * http://js.cytoscape.org/#eles.boundingBox
         */
        boundingBox(options?: BoundingBoxOptions): BoundingBox12 & BoundingBoxWH;
        boundingbox(options?: BoundingBoxOptions): BoundingBox12 & BoundingBoxWH;
        /**
         * Get the bounding box of the elements in rendered coordinates.
         * @param options An object containing options for the function.
         */
        renderedBoundingBox(options?: BoundingBoxOptions): BoundingBox12 & BoundingBoxWH;
        renderedBoundingbox(options?: BoundingBoxOptions): BoundingBox12 & BoundingBoxWH;
    }

    /**
     * http://js.cytoscape.org/#collection/layout
     */
    interface CollectionLayout {
        /**
         * Get a new layout, which can be used to algorithmically position the nodes in the collection.
         * This function is useful for running a layout on a subset of the elements in the graph, perhaps in parallel to other layouts.
         *
         * You must specify options.name with the name of the layout you wish to use.
         *
         * Note: that you must call layout.run() in order for it to affect the graph.
         *
         * @param options The layout options.
         */
        layout(options: LayoutOptions): Layouts;
        makeLayout(options: LayoutOptions): Layouts;
        createLayout(options: LayoutOptions): Layouts;
    }

    /**
     * http://js.cytoscape.org/#collection/layout
     */
    interface LayoutPositionOptions {
        // whether to animate changes to the layout
        animate?: boolean;
        // duration of animation in ms, if enabled
        animationDuration?: number;
        // easing of animation, if enabled
        animationEasing?: Css.TransitionTimingFunction;
        // collection of elements involved in the layout; set by cy.layout() or eles.layout(s)
        eles: CollectionArgument;
        // whether to fit the viewport to the graph
        fit?: boolean;
        // padding to leave between graph and viewport
        padding?: number;
        // pan the graph to the provided position, given as { x, y }
        pan?: Position;
        // callback for the layoutready event
        ready?: undefined;
        // callback for the layoutstop event
        stop?: undefined;
        // a positive value which adjusts spacing between nodes (>1 means greater than usual spacing)
        spacingFactor?: number;
        // zoom level as a positive number to set after animation
        zoom?: number;
    }
    interface NodeCollectionLayout {
        /**
         * Position the nodes for a discrete/synchronous layout.
         * http://js.cytoscape.org/#nodes.layoutPositions
         * @param layout The layout.
         * @param options The layout options object.
         */
        layoutPositions(layout: string, options: LayoutPositionOptions, handler: ElementPositionFunction): void;
    }
    /**
     * http://js.cytoscape.org/#collection/layout
     */
    interface LayoutDimensionOptions {
        // Boolean which changes whether label dimensions are included when calculating node dimensions
        nodeDimensionsIncludeLabels?: boolean;
    }

    /**
     * https://js.cytoscape.org/#node.layoutDimensions
     */
    interface NodeSingularLayout {
        /**
         * Returns the node width and height.
         * Meant for use in layout positioning to do overlap detection.
         * @param options The layout options object.
         */
        layoutDimensions(options: LayoutDimensionOptions): { w: number; h: number };
    }

    /**
     * http://js.cytoscape.org/#collection/selection
     */
    interface SingularSelection {
        /**
         * Get whether the element is selected.
         * http://js.cytoscape.org/#ele.selected
         */
        selected(): boolean;

        /**
         * Get whether the element's selection state is mutable.
         * http://js.cytoscape.org/#ele.selectable
         */
        selectable(): boolean;
    }
    /**
     * https://js.cytoscape.org/#collection/selection
     */
    interface CollectionSelection {
        /**
         * Make the elements selected (NB other elements outside the collection are not affected).
         * http://js.cytoscape.org/#eles.select
         */
        select(): this;
        /**
         * Make the elements not selected (NB other elements outside the collection are not affected).
         * http://js.cytoscape.org/#eles.unselect
         */
        unselect(): this;
        deselect(): this;
        /**
         * Make the selection states of the elements mutable.
         * http://js.cytoscape.org/#eles.selectify
         */
        selectify(): this;
        /**
         * Make the selection states of the elements immutable.
         * http://js.cytoscape.org/#eles.unselectify
         */
        unselectify(): this;
    }

    /**
     * http://js.cytoscape.org/#collection/style
     */
    type ClassName = string;
    /** A space-separated list of class names or an array */
    type ClassNames = string | ClassName[];

    interface CollectionStyle {
        /**
         * Add classes to elements.
         * http://js.cytoscape.org/#eles.addClass
         * @param classes A space-separated list of class names to add to the elements.
         */
        addClass(classes: ClassNames): this;
        /**
         * Remove classes from elements.
         * @param classes A space-separated list of class names to remove from the elements.
         * http://js.cytoscape.org/#eles.removeClass
         */
        removeClass(classes: ClassNames): this;
        /**
         * Toggle whether the elements have the specified classes.
         * @param classes A space-separated list of class names to toggle on the elements.
         * @param toggle [optional] Instead of automatically toggling, adds the classes on truthy values or removes them on falsey values.
         * http://js.cytoscape.org/#eles.toggleClass
         */
        toggleClass(classes: ClassNames, toggle?: boolean): this;
        /**
         * Replace the current list of classes on the elements with the specified list.
         * @param classes A space-separated list or array of class names that replaces the current class list.
         * http://js.cytoscape.org/#eles.classes
         * Note: can be used to clear all classes (empty string or array).
         */
        classes(classes: ClassNames): this;
        classes(classes: ClassNames): this | string[];
        classes(): string[];
        /**
         * Add classes to the elements, and then remove the classes after a specified duration.
         * @param classes A space-separated list of class names to flash on the elements.
         * @param duration [optional] The duration in milliseconds that the classes should be added on the elements. After the duration, the classes are removed.
         * http://js.cytoscape.org/#eles.flashClass
         */
        flashClass(classes: ClassNames, duration?: number): this;

        /**
         * Set a particular style property value.
         * @param name The name of the visual style property to set.
         * @param value The value to which the property is set.
         */
        style(name: string, value: any): this;
        /**
         * Get a particular style property value.
         * @param name The name of the visual style property to get.
         */
        style(name: string): any;
        /**
         * Set several particular style property values.
         * @param obj An object of style property name-value pairs to set.
         */
        style(obj: object): this;
        /**
         * Get a name-value pair object containing visual style properties and their values for the element.
         */
        style(): { [index: string]: any };
        /**
         * Set a particular style property value.
         * @param name The name of the visual style property to set.
         * @param value The value to which the property is set.
         */
        css(name: string, value: any): this;
        /**
         * Get a particular style property value.
         * @param name The name of the visual style property to get.
         */
        css(name: string): any;
        /**
         * Set several particular style property values.
         * @param obj An object of style property name-value pairs to set.
         */
        css(obj: object): this;
        /**
         * Get a name-value pair object containing visual style properties and their values for the element.
         */
        css(): { [index: string]: any };
        /**
         * Remove all or specific style overrides.
         * @param names A space-separated list of property names to remove overrides
         */
        removeStyle(names?: string): this;
    }

    /**
     * http://js.cytoscape.org/#collection/style
     */
    interface SingularStyle {
        /**
         * Get whether an element has a particular class.
         * @param className The name of the class to test for.
         * http://js.cytoscape.org/#ele.hasClass
         */
        hasClass(className: ClassName): boolean;

        /**
         * Get a name-value pair object containing rendered visual
         * style properties and their values for the element.
         * @param name The name of the visual style property to get.
         */
        renderedStyle(): { [name: string]: any };
        renderedStyle(name: string): any;

        renderedCss(): { [name: string]: any };
        renderedCss(name: string): any;

        /**
         * Get the numeric value of a style property in
         * preferred units that can be used for calculations.
         * @param name The name of the style property to get.
         * http://js.cytoscape.org/#ele.numericStyle
         */
        numericStyle(name: string): any;

        /**
         * Get the units that ele.numericStyle() is expressed in, for a particular property.
         * @param name The name of the style property to get.
         * http://js.cytoscape.org/#ele.numericStyleUnits
         */
        numericStyleUnits(name: string): any;
        /**
         * Get whether the element is visible.
         * http://js.cytoscape.org/#ele.visible
         */
        visible(): boolean;
        /**
         * Get whether the element is hidden.
         * http://js.cytoscape.org/#ele.visible
         */
        hidden(): boolean;
        /**
         * Get the effective opacity of the element
         *  (i.e. on-screen opacity),
         * which takes into consideration parent node opacity.
         * http://js.cytoscape.org/#ele.effectiveOpacity
         */
        effectiveOpacity(): number;
        /**
         * Get whether the element's effective opacity is completely transparent,
         * which takes into consideration parent node opacity.
         * http://js.cytoscape.org/#ele.transparent
         */
        transparent(): number;
    }

    /**
     * http://js.cytoscape.org/#collection/animation
     */
    interface ElementAnimateOptionsBase {
        /** An object containing name-value pairs of style properties to animate. */
        style?: { [name: string]: any };
        /** The duration of the animation in milliseconds. */
        duration?: number;
        /** A boolean indicating whether to queue the animation. */
        queue?: boolean;
        /** A function to call when the animation is done. */
        complete?(): void;
        /** A function to call each time the animation steps. */
        step?(): void;
        /** A transition-timing-function easing style string that shapes the animation progress curve. */
        easing?: Css.TransitionTimingFunction;
    }
    interface ElementAnimateOptionPos extends ElementAnimateOptionsBase {
        /** A position to which the elements will be animated. */
        position?: Position;
    }
    interface ElementAnimateOptionRen extends ElementAnimateOptionsBase {
        /** A rendered position to which the elements will be animated. */
        renderedPosition?: Position;
    }
    interface CollectionAnimation {
        /**
         * Animate the elements.
         * @param options An object containing the details of the animation.
         * http://js.cytoscape.org/#eles.animate
         */
        animate(options: ElementAnimateOptionPos | ElementAnimateOptionRen, params?: ElementAnimateOptionsBase): this;
        /**
         * Add a delay between animations for the elements.
         * @param duration How long the delay should be in milliseconds.
         * @param complete A function to call when the delay is complete.
         * http://js.cytoscape.org/#eles.delay
         */
        delay(duration: number, complete?: () => void): this;
        /**
         * Stop all animations that are currently running.
         * @param clearQueue A boolean, indicating whether the queue of animations should be emptied.
         * @param jumpToEnd A boolean, indicating whether the currently-running animations should jump to their ends rather than just stopping midway.
         * http://js.cytoscape.org/#eles.stop
         */
        stop(clearQueue?: boolean, jumpToEnd?: boolean): this;
        /**
         * Remove all queued animations for the elements.
         * http://js.cytoscape.org/#eles.clearQueue
         */
        clearQueue(): this;
    }
    interface SingularAnimationOptionsBase {
        /** A position to which the elements will be animated. */
        position: Position;
        /** A rendered position to which the elements will be animated. */
        renderedPosition: Position;
        /** An object containing name-value pairs of style properties to animate. */
        style: any;
        /** The duration of the animation in milliseconds. */
        duration: number;
        /** A transition-timing-function easing style string that shapes the animation progress curve. */
        easing: Css.TransitionTimingFunction;
    }
    interface SingularAnimationOptionsPos extends SingularAnimationOptionsBase {
        /** A position to which the elements will be animated. */
        position: Position;
    }
    interface SingularAnimationOptionsRen extends SingularAnimationOptionsBase {
        /** A rendered position to which the elements will be animated. */
        renderedPosition: Position;
    }
    interface SingularAnimation {
        /**
         * Get whether the element is currently being animated.
         */
        animated(): boolean;
        /**
         *  Get an animation for the element.
         * @param options An object containing the details of the animation.
         */
        animation(options: SingularAnimationOptionsRen | SingularAnimationOptionsPos): AnimationManipulation;

        /**
         * Get a delay animation for the element.
         * @param duration How long the delay should be in milliseconds.
         * http://js.cytoscape.org/#ele.delayAnimation
         */
        delayAnimation(duration: number): AnimationManipulation;
    }

    /**
     * http://js.cytoscape.org/#collection/comparison
     */
    interface CollectionComparision {
        /**
         * Determine whether this collection contains exactly the same elements as another collection.
         * @param eles The other elements to compare to.
         */
        same(eles: CollectionArgument): boolean;

        /**
         * Determine whether this collection contains any of the same elements as another collection.
         * @param eles The other elements to compare to.
         */
        anySame(eles: CollectionArgument): boolean;

        /**
         * Determine whether this collection contains all of the elements of another collection.
         */
        contains(eles: CollectionArgument): boolean;
        has(eles: CollectionArgument): boolean;

        /**
         * Determine whether all elements in the specified collection are in the neighbourhood of the calling collection.
         * @param eles The other elements to compare to.
         */
        allAreNeighbors(eles: CollectionArgument): boolean;
        allAreNeighbours(eles: CollectionArgument): boolean;

        /**
         * Determine whether any element in this collection matches a selector.
         *
         * @param selector The selector to match against.
         */
        is(selector: Selector): boolean;

        /**
         * Determine whether all elements in the collection match a selector.
         * @param selector The selector to match against.
         */
        allAre(selector: Selector): boolean;

        /**
         * Determine whether any element in this collection satisfies the specified test function.
         *
         * @param test The test function that returns truthy values for elements that satisfy the test and falsey values for elements that do not satisfy the test.
         * ele - The current element.
         * i - The index of the current element.
         * eles - The collection of elements being tested.
         * @param thisArg [optional] The value for this within the test function.
         */
        some(test: (ele: CollectionArgument, i: number, eles: CollectionArgument) => boolean, thisArg?: any): boolean;

        /**
         * Determine whether all elements in this collection satisfy the specified test function.
         *
         * @param test The test function that returns truthy values for elements that satisfy the test and falsey values for elements that do not satisfy the test.
         * ele - The current element.
         * i - The index of the current element.
         * eles - The collection of elements being tested.
         * @param thisArg [optional] The value for this within the test function.
         */
        every(test: (ele: CollectionArgument, i: number, eles: CollectionArgument) => boolean, thisArg?: any): boolean;
    }

    /**
     * http://js.cytoscape.org/#collection/iteration
     */
    interface CollectionIteration<TOut, TIn> {
        /**
         * Get the number of elements in the collection.
         */
        size(): number;
        /**
         * Get the number of elements in the collection.
         */
        length: number;

        /**
         * Get whether the collection is empty, meaning it has no elements.
         */
        empty(): boolean;
        /**
         * Get whether the collection is nonempty, meaning it has elements.
         */
        nonempty(): boolean;

        /**
         * Iterate over the elements in the collection using an implementation like the native array function namesake.
         *
         * This function behaves like Array.prototype.forEach() with minor changes for convenience:
         * You can exit the iteration early by returning false in the iterating function.
         * The Array.prototype.forEach() implementation does not support this, but it is included anyway on account of its utility.
         *
         * @param each The function executed each iteration.
         * ele - The current element.
         * i - The index of the current element.
         * eles - The collection of elements being iterated.
         * @param thisArg [optional] The value for this within the iterating function.
         */
        // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
        each(each: (ele: TIn, i: number, eles: this) => void | boolean, thisArg?: any): this;
        // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
        forEach(each: (ele: TIn, i: number, eles: this) => void | boolean, thisArg?: any): this;

        /**
         * Get an element at a particular index in the collection.
         *
         * You may use eles[i] in place of eles.eq(i) as a more performant alternative.
         *
         * @param index The index of the element to get.
         */
        eq(index: number): TOut;
        /**
         * Get an element at a particular index in the collection.
         *
         * @param index The index of the element to get.
         */
        [index: number]: TOut;
        /**
         * Get the first element in the collection.
         */
        first(): TOut;
        /**
         * Get the last element in the collection.
         */
        last(): TOut;

        /**
         * Get a subset of the elements in the collection based on specified indices.
         *
         * @param start [optional] An integer that specifies where to start the selection.
         *              The first element has an index of 0.
         *              Use negative numbers to select from the end of an array.
         * @param end [optional] An integer that specifies where to end the selection.
         *            If omitted, all elements from the start position and to the end of the array will be selected.
         *            Use negative numbers to select from the end of an array.
         */
        slice(start?: number, end?: number): this;

        /**
         * Get the collection as an array, maintaining the order of the elements.
         */
        toArray(): TOut[];

        [Symbol.iterator](): Iterator<TOut>;
    }

    /**
     * http://js.cytoscape.org/#collection/building--filtering
     */
    /**
     * Get a new collection, resulting from adding the collection with another one
     *
     * @param eles The elements or array of elements to add or elements in the graph matching the selector.
     * http://js.cytoscape.org/#eles.union
     */
    type CollectionBuildingUnionFunc = (
        eles: CollectionArgument | CollectionArgument[] | Selector,
    ) => CollectionReturnValue;

    /**
     * Get a new collection, resulting from the collection without some specified elements.
     * http://js.cytoscape.org/#eles.difference
     * @param eles The elements that will not be in the resultant collection.
     *             Elements from the calling collection matching this selector will not be in the resultant collection.
     */
    type CollectionBuildingDifferenceFunc = (eles: CollectionArgument | Selector) => CollectionReturnValue;

    /**
     * Get the elements in both this collection and another specified collection.
     * http://js.cytoscape.org/#eles.intersection
     * @param eles The elements to intersect with.
     *             A selector representing the elements to intersect with.
     *             All elements in the graph matching the selector are used as the passed collection.
     */
    type CollectionBuildingIntersectionFunc = (eles: CollectionArgument | Selector) => CollectionReturnValue;

    /**
     * Get the elements that are in the calling collection or the passed collection but not in both.
     * http://js.cytoscape.org/#eles.symmetricDifference
     * @param eles The elements to apply the symmetric difference with.
     *             A selector representing the elements to apply the symmetric difference with.
     *             All elements in the graph matching the selector are used as the passed collection.
     */
    type CollectionSymmetricDifferenceFunc = (eles: CollectionArgument | Selector) => CollectionReturnValue;
    /**
     * http://js.cytoscape.org/#collection/building--filtering
     */
    interface CollectionBuildingFiltering<TIn, TOut> {
        /**
         * Get an element in the collection from its ID in a very performant way.
         * @param id The ID of the element to get.
         */
        getElementById(id: string): TOut;
        /**
         * Get an element in the collection from its ID in a very performant way.
         * @param id The ID of the element to get.
         */
        $id(id: string): TOut;

        /**
         * Get a new collection, resulting from adding the collection with another one
         * http://js.cytoscape.org/#eles.union
         */
        union: CollectionBuildingUnionFunc;
        u: CollectionBuildingUnionFunc;
        add: CollectionBuildingUnionFunc;
        "+": CollectionBuildingUnionFunc;
        or: CollectionBuildingUnionFunc;
        "|": CollectionBuildingUnionFunc;

        /**
         * Get a new collection, resulting from the collection without some specified elements.
         * http://js.cytoscape.org/#eles.difference
         */
        difference: CollectionBuildingDifferenceFunc;
        subtract: CollectionBuildingDifferenceFunc;
        "\\": CollectionBuildingDifferenceFunc;
        not: CollectionBuildingDifferenceFunc;
        "!": CollectionBuildingDifferenceFunc;
        relativeComplement: CollectionBuildingDifferenceFunc;
        "-": CollectionBuildingDifferenceFunc;

        /**
         * Get all elements in the graph that are not in the calling collection.
         * http://js.cytoscape.org/#eles.absoluteComplement
         */
        absoluteComplement(): CollectionReturnValue;
        abscomp(): CollectionReturnValue;
        complement(): CollectionReturnValue;

        /**
         * Get the elements in both this collection and another specified collection.
         * http://js.cytoscape.org/#eles.intersection
         */
        intersection: CollectionBuildingIntersectionFunc;
        intersect: CollectionBuildingIntersectionFunc;
        and: CollectionBuildingIntersectionFunc;
        n: CollectionBuildingIntersectionFunc;
        "&": CollectionBuildingIntersectionFunc;
        ".": CollectionBuildingIntersectionFunc;

        /**
         * Get the elements that are in the calling collection
         * or the passed collection but not in both.
         * http://js.cytoscape.org/#eles.symmetricDifference
         */
        symmetricDifference: CollectionSymmetricDifferenceFunc;
        symdiff: CollectionSymmetricDifferenceFunc;
        xor: CollectionSymmetricDifferenceFunc;
        "^": CollectionSymmetricDifferenceFunc;
        "(+)": CollectionSymmetricDifferenceFunc;
        "(-)": CollectionSymmetricDifferenceFunc;

        /**
         * Perform a traditional left/right diff on the two collections.
         *
         * @param selector
         *    A selector representing the elements on the right side of the diff. All elements in the graph matching the selector are used as the passed collection.
         *    The elements on the right side of the diff.
         * @return This function returns a plain object of the form { left, right, both } where
         * left - is the set of elements only in the calling (i.e. left) collection,
         * right - is the set of elements only in the passed (i.e. right) collection, and
         * both - is the set of elements in both collections.
         * http://js.cytoscape.org/#eles.diff
         */
        diff(selector: Selector | CollectionArgument): {
            left: CollectionReturnValue;
            right: CollectionReturnValue;
            both: CollectionReturnValue;
        };

        /**
         * Perform a in-place merge of the given elements into the calling collection.
         * @param eles The elements to merge in-place or a selector representing the elements to merge.
         * All elements in the graph matching the selector are used as the passed collection.
         *
         * This function modifies the calling collection instead of returning a new one.
         * Use of this function should be considered for performance in some cases, but otherwise should be avoided. Consider using eles.union() instead.
         * Use this function only on new collections that you create yourself, using cy.collection().
         * This ensures that you do not unintentionally modify another collection.
         *
         * Examples
         * With a collection:
         * @example
         * var col = cy.collection(); // new, empty collection
         * var j = cy.$('#j');
         * var e = cy.$('#e');
         * col.merge( j ).merge( e );
         *
         * With a selector:
         * @example
         * var col = cy.collection(); // new, empty collection
         * col.merge('#j').merge('#e');
         */
        merge(eles: CollectionArgument | Selector): this;
        /**
         * Perform an in-place operation on the calling collection to remove the given elements.
         * @param eles The elements to remove  in-place or a selector representing the elements to remove .
         * All elements in the graph matching the selector are used as the passed collection.
         *
         * This function modifies the calling collection instead of returning a new one.
         * Use of this function should be considered for performance in some cases, but otherwise should be avoided. Consider using eles.filter() or eles.remove() instead.
         * Use this function only on new collections that you create yourself, using cy.collection().
         * This ensures that you do not unintentionally modify another collection.
         *
         * Examples
         * With a collection:
         * @example
         * var col = cy.collection(); // new, empty collection
         * var e = cy.$('#e');
         * col.merge( cy.nodes() );
         * col.unmerge( e );
         *
         * With a selector:
         * @example
         * var col = cy.collection(); // new, empty collection
         * col.merge( cy.nodes() );
         * col.unmerge('#e');
         */
        unmerge(eles: CollectionArgument | Selector): this;

        /**
         * Get a new collection containing elements that are accepted by the specified filter.
         *
         * @param selector The selector to match against.
         * @param filter selector The filter function that returns true for elements to include.
         * i - The index of the current element being considered.
         * ele - The element being considered.
         * http://js.cytoscape.org/#eles.filter
         */
        filter(
            selector: Selector | ((ele: TIn, i: number, eles: CollectionArgument) => boolean),
        ): CollectionReturnValue;
        /**
         * Get the nodes that match the specified selector.
         *
         * @param selector The selector to match against.
         * http://js.cytoscape.org/#eles.filter
         */
        nodes(selector?: Selector): NodeCollection;
        /**
         * Get the edges that match the specified selector.
         *
         * @param selector The selector to match against.
         * http://js.cytoscape.org/#eles.filter
         */
        edges(selector?: Selector): EdgeCollection;

        /**
         * Get a new collection containing the elements sorted by the
         * specified comparison function.
         *
         * @param sort The sorting comparison function that returns a negative number
         * for ele1 before ele2, 0 for ele1 same as ele2,
         * or a positive number for ele1 after ele2.
         *
         * http://js.cytoscape.org/#eles.sort
         */
        sort(sort: (ele1: TIn, ele2: TIn) => number): CollectionReturnValue;

        /**
         * Get an array containing values mapped from the collection.
         *
         * @param fn The function that returns the mapped value for each element.
         * ele - The current element.
         * i - The index of the current element.
         * eles - The collection of elements being mapped.
         * @param thisArg [optional] The value for this within the iterating function.
         *
         * http://js.cytoscape.org/#eles.map
         */
        map<T>(fn: (ele: TIn, i: number, eles: CollectionArgument) => T, thisArg?: any): T[];

        /**
         * Reduce a single value by applying a
         * function against an accumulator and each value of the collection.
         *
         * @param fn The function that returns the accumulated value
         * given the previous value and the current element.
         * prevVal The value accumulated from previous elements.
         * ele The current element.
         * i The index of the current element.
         * eles The collection of elements being reduced.
         * @param initialValue The initial value for reducing
         * It is used also for type inference of output, but the type can be
         * also stated explicitly as generic
         * http://js.cytoscape.org/#eles.reduce
         */
        reduce<T>(fn: (prevVal: T, ele: TIn, i: number, eles: CollectionArgument) => T, initialValue: T): T;

        /**
         * Find a minimum value in a collection.
         *
         * @param fn The function that returns the value to compare for each element.
         * ele - The current element.
         * i - The index of the current element.
         * eles - The collection of elements being mapped.
         * @param thisArg [optional] The value for this within the iterating function.
         *
         * http://js.cytoscape.org/#eles.min
         */
        min<T>(
            fn: (ele: TIn, i: number, eles: CollectionArgument) => T,
            thisArg?: any,
        ): {
            /**
             * The minimum value found.
             */
            value: T;
            /**
             * The element that corresponds to the minimum value.
             */
            ele: SingularElementReturnValue;
        };

        /**
         * Find a maximum value and the corresponding element.
         *
         * @param fn The function that returns the value to compare for each element.
         * ele - The current element.
         * i - The index of the current element.
         * eles - The collection of elements being mapped.
         * @param thisArg [optional] The value for this within the iterating function.
         *
         * http://js.cytoscape.org/#eles.max
         */
        max<T>(
            fn: (ele: TIn, i: number, eles: CollectionArgument) => T,
            thisArg?: any,
        ): {
            /**
             * The minimum value found.
             */
            value: T;
            /**
             * The element that corresponds to the minimum value.
             */
            ele: SingularElementReturnValue;
        };
    }

    /**
     * http://js.cytoscape.org/#collection/traversing
     */

    type MinumumSpanningTree = any;

    interface CollectionTraversing {
        // http://js.cytoscape.org/#collection/traversing

        /**
         * Get the open neighbourhood of the elements.
         *
         * The neighbourhood returned by this function is a bit different than the traditional definition of a "neighbourhood":
         * This returned neighbourhood includes the edges connecting the collection to the neighbourhood. This gives you more flexibility.
         * An open neighbourhood is one that does not include the original set of elements. If unspecified, a neighbourhood is open by default.
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        neighborhood(selector?: Selector): CollectionReturnValue;

        /**
         * Get the open neighbourhood of the elements.
         *
         * The neighbourhood returned by this function is a bit different than the traditional definition of a "neighbourhood":
         * This returned neighbourhood includes the edges connecting the collection to the neighbourhood. This gives you more flexibility.
         * An open neighbourhood is one that does not include the original set of elements. If unspecified, a neighbourhood is open by default.
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        openNeighborhood(selector?: Selector): CollectionReturnValue;
        /**
         * Get the closed neighbourhood of the elements.
         *
         * The neighbourhood returned by this function is a bit different than the traditional definition of a "neighbourhood":
         * This returned neighbourhood includes the edges connecting the collection to the neighbourhood. This gives you more flexibility.
         * A closed neighbourhood is one that does include the original set of elements.
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        closedNeighborhood(selector?: Selector): CollectionReturnValue;

        /**
         * Get the connected components, considering only the elements in the calling collection.
         * An array of collections is returned, with each collection representing a component.
         */
        components(): CollectionReturnValue[];

        /**
         * Get the connected components to which the passed elements belong.
         * The components consider only the subgraph made by the elements in the calling collection.
         * An array of collections is returned, with each collection representing a component.
         * http://js.cytoscape.org/#eles.componentsOf
         * @param root The components that contain these elements are returned.
         */
        componentsOf(root: Selector): CollectionReturnValue[];
    }
    /**
     * http://js.cytoscape.org/#collection/edge-points
     */
    interface EdgeSingularPoints {
        /**
         * Get an array of control point model positions for a {@code curve-style: bezier) or {@code curve-style: unbundled-bezier} edge.
         *
         * While the control points may be specified relatively in the CSS,
         * this function returns the absolute model positions of the control points.
         * The points are specified in the order of source-to-target direction.
         * This function works for bundled beziers, but it is not applicable to the middle, straight-line edge in the bundle.
         */
        controlPoints(): Position[];
        /**
         * Get the control points in rendered coordinates.
         * http://js.cytoscape.org/#edge.renderedControlPoints
         */
        renderedControlPoints(): Position[];

        /**
         * Get an array of segment point model positions (i.e. bend points) for a {@code curve-style: segments} edge.
         *
         * While the segment points may be specified relatively in the stylesheet,
         * this function returns the absolute model positions of the segment points.
         * The points are specified in the order of source-to-target direction.
         */
        segmentPoints(): Position[];
        /**
         * Get the segment points in rendered coordinates.
         * http://js.cytoscape.org/#edge.renderedSegmentPoints
         */
        renderedSegmentPoints(): Position[];

        /**
         * Get the model position of where the edge ends, towards the source node.
         */
        sourceEndpoint(): Position;
        /**
         * Get the source endpoint in rendered coordinates.
         * http://js.cytoscape.org/#edge.renderedSourceEndpoint
         */
        renderedSourceEndpoint(): Position;

        /**
         * Get the model position of where the edge ends, towards the target node.
         */
        targetEndpoint(): Position;
        /**
         * Get the target endpoint in rendered coordinates.
         * http://js.cytoscape.org/#edge.renderedTargetEndpoint
         */
        renderedTargetEndpoint(): Position;

        /**
         * Get the model position of the midpoint of the edge.
         *
         * The midpoint is, by default, where the edge’s label is centred. It is also the position towards which mid arrows point.
         * For curve-style: unbundled-bezier edges, the midpoint is the middle extremum if the number of control points is odd.
         * For an even number of control points, the midpoint is where the two middle-most control points meet.
         * This is the middle inflection point for bilaterally symmetric or skew symmetric edges, for example.
         * For curve-style: segments edges, the midpoint is the middle segment point if the number of segment points is odd.
         * For an even number of segment points, the overall midpoint is the midpoint of the middle-most line segment (i.e. the mean of the middle two segment points).
         */
        midpoint(): Position;
        /**
         * Get the midpoint in rendered coordinates.
         * http://js.cytoscape.org/#edge.renderedMidpoint
         */
        renderedMidpoint(): Position;
    }
    interface EdgeSingularTraversing {
        /**
         * Get source node of this edge.
         * @param selector An optional selector that is used to filter the resultant collection.
         * http://js.cytoscape.org/#edge.source
         */
        source(selector?: Selector): NodeSingular;

        /**
         * Get target node of this edge.
         * @param selector An optional selector that is used to filter the resultant collection.
         * http://js.cytoscape.org/#edge.target
         */
        target(selector?: Selector): NodeSingular;
    }
    interface EdgeCollectionTraversing {
        // http://js.cytoscape.org/#collection/traversing

        /**
         * Get the nodes connected to the edges in the collection
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        connectedNodes(selector?: Selector): NodeCollection;

        /**
         * Get source nodes connected to the edges in the collection.
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        sources(selector?: Selector): NodeCollection;

        /**
         * Get target nodes connected to the edges in the collection.
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        targets(selector?: Selector): NodeCollection;

        /**
         * Get edges parallel to those in the collection.
         *
         * Two edges are said to be parallel if they connect the same two nodes.
         * Any two parallel edges may connect nodes in the same direction, in which case the edges share the same source and target.
         * They may alternatively connect nodes in the opposite direction, in which case the source and target are reversed in the second edge.
         * That is:
         * - edge1.source().id() === edge2.source().id()
         *   && edge1.target().id() === edge2.target().id()
         * OR
         * - edge1.source().id() === edge2.target().id()
         *   && edge1.target().id() === edge2.source().id()
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        parallelEdges(selector?: Selector): EdgeCollection;

        /**
         * Get edges codirected to those in the collection.
         *
         * Two edges are said to be codirected if they connect the same two nodes in the same direction: The edges have the same source and target.
         * That is:
         * - edge1.source().id() === edge2.source().id()
         *   && edge1.target().id() === edge2.target().id()
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        codirectedEdges(selector?: Selector): EdgeCollection;
    }
    interface NodeCollectionTraversing {
        // http://js.cytoscape.org/#collection/traversing

        /**
         * Get the edges connecting the collection to another collection. Direction of the edges does not matter.
         *
         * @param eles The other collection.
         * @param selector The other collection, specified as a selector which is matched against all elements in the graph.
         */
        edgesWith(eles: CollectionArgument | Selector): EdgeCollection;

        /**
         * Get the edges coming from the collection (i.e. the source) going to another collection (i.e. the target).
         *
         * @param eles The other collection.
         * @param selector The other collection, specified as a selector which is matched against all elements in the graph.
         */
        edgesTo(eles: CollectionArgument | Selector): EdgeCollection;

        /**
         * Get the edges connected to the nodes in the collection.
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        connectedEdges(selector?: Selector): EdgeCollection;

        /**
         * From the set of calling nodes, get the nodes which are roots (i.e. no incoming edges, as in a directed acyclic graph).
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        roots(selector?: Selector): NodeCollection;

        /**
         * From the set of calling nodes, get the nodes which are leaves (i.e. no outgoing edges, as in a directed acyclic graph).
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        leaves(selector?: Selector): NodeCollection;

        /**
         * Get edges (and their targets) coming out of the nodes in the collection.
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        outgoers(selector?: Selector): CollectionReturnValue;

        /**
         * Recursively get edges (and their targets) coming out of the nodes in the collection (i.e. the outgoers, the outgoers' outgoers, ...).
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        successors(selector?: Selector): CollectionReturnValue;

        /**
         * Get edges (and their sources) coming into the nodes in the collection.
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        incomers(selector?: Selector): CollectionReturnValue;

        /**
         * Recursively get edges (and their sources) coming into the nodes in the collection (i.e. the incomers, the incomers' incomers, ...).
         *
         * @param selector [optional] An optional selector that is used to filter the resultant collection.
         */
        predecessors(selector?: Selector): CollectionReturnValue;
    }

    /**
     * http://js.cytoscape.org/#collection/algorithms
     */

    type WeightFn = (edge: EdgeCollection) => number;

    /**
     * The handler returns true when it finds the desired node, and it returns false to cancel the search.
     * v - The current node.
     * e - The edge connecting the previous node to the current node.
     * u - The previous node.
     * i - The index indicating this node is the ith visited node.
     * depth - How many edge hops away this node is from the root nodes.
     */
    type SearchVisitFunction = (
        v: NodeSingular,
        e: EdgeSingular,
        u: NodeSingular,
        i: number,
        depth: number,
        // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
    ) => boolean | void;
    interface SearchFirstOptionsBase {
        /**
         * A handler function that is called when a node is visited in the search.
         */
        visit?: SearchVisitFunction;
        /**
         * A boolean indicating whether the algorithm should only go along edges from source to target (default false).
         */
        directed?: boolean;
    }
    interface SearchFirstOptions1 extends SearchFirstOptionsBase {
        /**
         * The root nodes (selector or collection) to start the search from.
         */
        root: Selector | CollectionArgument;
    }
    interface SearchFirstOptions2 extends SearchFirstOptionsBase {
        /**
         * The root nodes (selector or collection) to start the search from.
         */
        roots: Selector | CollectionArgument;
    }
    type SearchFirstOptions = SearchFirstOptions1 | SearchFirstOptions2;
    interface SearchFirstResult {
        /**
         * The path of the search.
         * - The path returned includes edges such that if path[i] is a node, then path[i - 1] is the edge used to get to that node.
         */
        path: CollectionArgument;
        /**
         * The node found by the search
         * - If no node was found, then found is empty.
         * - If your handler function returns false, then the only the path up to that point is returned.
         */
        found: NodeCollection;
    }

    /**
     * http://js.cytoscape.org/#eles.dijkstra
     */
    interface SearchDijkstraOptions {
        /**
         * The root node (selector or collection) where the algorithm starts.
         */
        root: Selector | CollectionArgument;

        /**
         * A function that returns the positive numeric weight for this edge.
         *
         * If no weight function is defined, a constant weight of 1 is used for each edge.
         */
        weight?: WeightFn;

        /**
         * A boolean indicating whether the algorithm should only go along edges from source to target (default false).
         */
        directed?: boolean;
    }
    /**
     * http://js.cytoscape.org/#eles.dijkstra
     */
    interface SearchDijkstraResult {
        /**
         * Returns the distance from the source node to node.
         */
        distanceTo(node: NodeSingular): number;

        /**
         * Returns a collection containing the shortest path from the source node to node.
         * The path starts with the source node and includes the edges between the nodes in the path such that if pathTo(node)[i] is an edge,
         * then pathTo(node)[i-1] is the previous node in the path and pathTo(node)[i+1] is the next node in the path.
         */
        pathTo(node: NodeSingular): CollectionReturnValue;
    }
    /**
     * http://js.cytoscape.org/#eles.aStar
     */
    interface SearchAStarOptions {
        root: Selector | CollectionArgument;
        goal: Selector | CollectionArgument;
        weight?: WeightFn;
        heuristic?(node: NodeCollection): number;
        directed?: boolean;
    }
    /**
     * http://js.cytoscape.org/#eles.aStar
     */
    interface SearchAStarResult {
        found: boolean;
        distance: number;
        path: CollectionReturnValue;
    }

    /**
     * http://js.cytoscape.org/#eles.floydWarshall
     */
    interface SearchFloydWarshallOptions {
        weight: WeightFn;
        directed?: boolean;
    }

    /**
     * http://js.cytoscape.org/#eles.floydWarshall
     */
    interface SearchFloydWarshallResult {
        /**
         * Returns the distance from the source node to node.
         */
        distance(fromNode: NodeSingular | CollectionSelection, toNode: NodeSingular | Selector): number;

        /**
         * Returns a collection containing the shortest path from the source node to node.
         * The path starts with the source node and includes the edges
         * between the nodes in the path such that if pathTo(node)[i] is an edge,
         * then pathTo(node)[i-1] is the previous node in the path and pathTo(node)[i+1]
         * is the next node in the path.
         */
        path(fromNode: NodeSingular | CollectionSelection, toNode: NodeSingular | Selector): CollectionReturnValue;
    }

    /**
     * http://js.cytoscape.org/#eles.bellmanFord
     */
    interface SearchBellmanFordOptions {
        /**
         * The root node (selector or collection) where the search starts.
         */
        root: any;
        /**
         * A function that returns the positive numeric weight for this edge.
         */
        weight?: WeightFn;
        /**
         * Indicating whether the algorithm should only go along
         * edges from source to target (default false).
         */
        directed: boolean;
        /**
         * Indicating whether the algorithm should find and return
         * negative weight cycles (default true).
         */
        findNegativeWeightCycles?: boolean;
    }
    /**
     * http://js.cytoscape.org/#eles.bellmanFord
     */
    interface SearchBellmanFordResult {
        /**
         * function that computes the shortest path from root node to the argument node
         * (either objects or selector string)
         */
        pathTo(node: NodeSingular | Selector): CollectionReturnValue;

        /**
         *  function that computes the shortest distance from root node to argument node
         * (either objects or selector string)
         */
        distanceTo(node: NodeSingular | Selector): number;

        /* true/false. If true, pathTo and distanceTo will be undefined */
        hasNegativeWeightCycle: boolean;

        /**
         * array of collections corresponding to the negative weight cycles found
         * (only populated if the findNegativeWeightCycles option is set to true)
         */
        negativeWeightCycles: CollectionReturnValue[];
    }

    /**
     * http://js.cytoscape.org/#eles.kruskal
     * trivial so implemented in the function
     */

    /**
     * http://js.cytoscape.org/#eles.pageRank
     */
    interface SearchPageRankOptions {
        /** Numeric parameter for the algorithm. */
        dampingFactor?: number;
        /** Numeric parameter that represents the required precision. */
        precision?: number;
        /** Maximum number of iterations to perform. */
        iterations?: number;
    }
    /**
     * http://js.cytoscape.org/#eles.pageRank
     */
    interface SearchPageRankResult {
        /** function that computes the rank of a given node (either object or selector string) */
        rank(node: NodeCollection): number;
    }

    /**
     * http://js.cytoscape.org/#eles.degreeCentrality
     */
    interface SearchDegreeCentralityOptions {
        /**
         * The root node (selector or collection) for which the
         * centrality calculation is made.
         */
        root: NodeSingular | Selector;
        /**  A function that returns the weight for the edge. */
        weight?(edge: EdgeSingular): number;
        /**
         * The alpha value for the centrality calculation, ranging on [0, 1].
         * With value 0 (default), disregards edge weights and solely uses
         * number of edges in the centrality calculation. With value 1,
         * disregards number of edges and solely uses the edge weights
         * in the centrality calculation.
         */
        alpha?: number;
        /**
         * Whether the directed indegree and outdegree centrality is calculated (true) or
         * whether the undirected centrality is calculated (false, default).
         */
        directed?: boolean;
    }
    /**
     * http://js.cytoscape.org/#eles.degreeCentrality
     */
    interface SearchDegreeCentralityResultUndirected {
        /** the degree centrality of the root node */
        degree: number;
    }
    interface SearchDegreeCentralityResultDirected {
        /* the indegree centrality of the root node */
        indegree: number;
        /* the outdegree centrality of the root node */
        outdegree: number;
    }
    /**
     * http://js.cytoscape.org/#eles.degreeCentralityNormalized
     */
    interface SearchDegreeCentralityNormalizedOptions {
        /**  A function that returns the weight for the edge. */
        weight(edge: EdgeSingular): number;
        /**
         * The alpha value for the centrality calculation, ranging on [0, 1].
         * With value 0 (default), disregards edge weights and solely uses
         * number of edges in the centrality calculation. With value 1,
         * disregards number of edges and solely uses the edge weights
         * in the centrality calculation.
         */
        alpha?: number;
        /**
         * A boolean indicating whether the directed indegree and outdegree centrality is calculated (true) or
         * whether the undirected centrality is calculated (false, default).
         */
        directed?: boolean;
    }
    /**
     * http://js.cytoscape.org/#eles.degreeCentralityNormalized
     */
    interface SearchDegreeCentralityNormalizedResultUndirected {
        /** the normalised degree centrality of the specified node */
        degree(node: NodeSingular): any;
    }
    interface SearchDegreeCentralityNormalizedResultDirected {
        /** the normalised indegree centrality of the specified node */
        indegree(node: NodeSingular): any;

        /** the normalised outdegree centrality of the specified node */
        outdegree(node: NodeSingular): any;
    }
    /**
     * http://js.cytoscape.org/#eles.closenessCentrality
     */
    interface SearchClosenessCentralityOptions {
        /**
         * The root node (selector or collection) for which the
         * centrality calculation is made.
         */
        root: NodeSingular | Selector;
        /**  A function that returns the weight for the edge. */
        weight?(edge: EdgeSingular): number;

        /**
         * A boolean indicating whether the directed indegree and outdegree centrality is calculated (true) or
         * whether the undirected centrality is calculated (false, default).
         */
        directed?: boolean;
        /**
         * A boolean indicating whether the algorithm calculates the
         * harmonic mean (true, default) or the arithmetic mean (false) of distances.
         * The harmonic mean is very useful for graphs that are not strongly connected.
         */
        harmonic?: boolean;
    }
    /**
     * http://js.cytoscape.org/#eles.closenessCentrality
     * trivial
     */

    /**
     * http://js.cytoscape.org/#eles.closenessCentralityNormalized
     */
    interface SearchClosenessCentralityNormalizedOptions {
        /**  A function that returns the weight for the edge. */
        weight?(edge: EdgeSingular): number;
        directed?: boolean;
        /**
         * A boolean indicating whether the algorithm calculates the
         * harmonic mean (true, default) or the arithmetic mean (false) of distances.
         * The harmonic mean is very useful for graphs that are not strongly connected.
         */
        harmonic?: boolean;
    }
    /**
     * http://js.cytoscape.org/#eles.closenessCentralityNormalized
     */
    interface SearchClosenessCentralityNormalizedResult {
        /** the normalised closeness centrality of the specified node */
        closeness(node: NodeSingular): any;
    }

    /**
     * http://js.cytoscape.org/#eles.betweennessCentrality
     */
    interface SearchBetweennessOptions {
        /**  A function that returns the weight for the edge. */
        weight?(edge: EdgeSingular): number;

        /**
         * A boolean indicating whether the directed indegree and outdegree centrality is calculated (true) or
         * whether the undirected centrality is calculated (false, default).
         */
        directed?: boolean;
    }
    /**
     * http://js.cytoscape.org/#eles.betweennessCentrality
     */
    interface SearchBetweennessResult {
        /** returns the betweenness centrality of the specified node */
        betweenness(node: NodeSingular): number;

        /** returns the normalised betweenness centrality of the specified node */
        betweennessNormalized(node: NodeSingular): number;
        betweennessNormalised(node: NodeSingular): number;
    }

    /**
     * http://js.cytoscape.org/#eles.closenessCentralityNormalized
     */
    interface SearchClosenessCentralityNormalizedOptions {
        /**  A function that returns the weight for the edge. */
        weight?(edge: EdgeSingular): number;
        directed?: boolean;
        /**
         * A boolean indicating whether the algorithm calculates the
         * harmonic mean (true, default) or the arithmetic mean (false) of distances.
         * The harmonic mean is very useful for graphs that are not strongly connected.
         */
        harmonic?: boolean;
    }
    /**
     * http://js.cytoscape.org/#eles.closenessCentralityNormalized
     * trivial
     */

    /**
     * Options for hierarchical clustering.
     */
    interface HierarchicalClusteringOptions {
        attributes?: ((node: NodeSingular) => number)[];
        distance?: "euclidean" | "squaredEuclidean" | "manhattan" | "max" | ((length: number, getPAt: (i: number) => number, getQAt: (i: number) => number, nodeP?: NodeSingular, nodeQ?: NodeSingular) => number) | ((nodeP: NodeSingular, nodeQ: NodeSingular) => number);
        linkage?: "mean" | "min" | "max";
        mode?: "threshold" | "dendrogram";
        threshold?: number;
        dendrogramDepth?: number;
        addDendrogram?: boolean;
    }

    /**
     * Result of hierarchical clustering.
     */
    interface HierarchicalClusteringResult {
        clusters: NodeCollection[];
        dendrogram?: CollectionReturnValue;
    }

    /**
     * Options for Markov clustering.
     */
    interface MarkovClusteringOptions {
        attributes?: ((edge: EdgeSingular) => number)[];
        expandFactor?: number;
        inflateFactor?: number;
        multFactor?: number;
        maxIterations?: number;
    }

    /**
     * Result of Markov clustering.
     */
    type MarkovClusteringResult = NodeCollection[];

    /**
     * Options for k-means clustering.
     */
    interface KMeansOptions {
        attributes: ((node: NodeSingular) => number)[];
        k: number;
        distance?: "euclidean" | "squaredEuclidean" | "manhattan" | "max" | ((length: number, getPAt: (i: number) => number, getQAt: (i: number) => number, nodeP?: NodeSingular, nodeQ?: NodeSingular) => number);
        maxIterations?: number;
        sensitivityThreshold?: number;
    }

    /**
     * Result of k-means clustering.
     */
    type KMeansResult = NodeCollection[];

    /**
     * Options for k-medoids clustering.
     */
    interface KMedoidsOptions {
        attributes: ((node: NodeSingular) => number)[];
        k: number;
        distance?: "euclidean" | "squaredEuclidean" | "manhattan" | "max" | ((length: number, getPAt: (i: number) => number, getQAt: (i: number) => number, nodeP?: NodeSingular, nodeQ?: NodeSingular) => number) | ((nodeP: NodeSingular, nodeQ: NodeSingular) => number);
        maxIterations?: number;
    }

    /**
     * Result of k-medoids clustering.
     */
    type KMedoidsResult = NodeCollection[];

    /**
     * Options for fuzzy c-means clustering.
     */
    interface FuzzyCMeansOptions {
        attributes: ((node: NodeSingular) => number)[];
        k: number;
        distance?: "euclidean" | "squaredEuclidean" | "manhattan" | "max" | ((length: number, getPAt: (i: number) => number, getQAt: (i: number) => number, nodeP?: NodeSingular, nodeQ?: NodeSingular) => number);
        maxIterations?: number;
        sensitivityThreshold?: number;
    }

    /**
     * Result of fuzzy c-means clustering.
     */
    interface FuzzyCMeansResult {
        clusters: NodeCollection[];
        degreeOfMembership: number[][];
    }

    /**
     * Options for affinity propagation clustering.
     */
    interface AffinityPropagationOptions {
        attributes: ((node: NodeSingular) => number)[];
        distance?: "euclidean" | "squaredEuclidean" | "manhattan" | "max" | ((length: number, getPAt: (i: number) => number, getQAt: (i: number) => number, nodeP?: NodeSingular, nodeQ?: NodeSingular) => number) | ((nodeP: NodeSingular, nodeQ: NodeSingular) => number);
        preference?: "median" | "mean" | "min" | "max" | number;
        damping?: number;
        minIterations?: number;
        maxIterations?: number;
    }

    /**
     * Result of affinity propagation clustering.
     */
    type AffinityPropagationResult = NodeCollection[];

    /**
     * Options for Hierholzer's algorithm.
     */
    interface HierholzerOptions {
        root?: Selector | NodeCollection;
        directed?: boolean;
    }

    /**
     * Result of Hierholzer's algorithm.
     */
    interface HierholzerResult {
        found: boolean;
        trail: CollectionReturnValue;
    }

    interface SearchAlgorithms {
        /**
         * Perform a breadth-first search within the elements in the collection.
         * @param options
         * http://js.cytoscape.org/#eles.breadthFirstSearch
         * @alias bfs
         */
        breadthFirstSearch(options: SearchFirstOptions): SearchFirstResult;
        bfs(options: SearchFirstOptions): SearchFirstResult;
        
        /**
         * Perform a depth-first search within the elements in the collection.
         * http://js.cytoscape.org/#eles.depthFirstSearch
         * @alias dfs
         */
        depthFirstSearch(options: SearchFirstOptions): SearchFirstResult;
        dfs(options: SearchFirstOptions): SearchFirstResult;

        /**
         * Perform Dijkstra's algorithm on the elements in the collection.
         * This finds the shortest paths to all other nodes in the collection from the root node.
         * http://js.cytoscape.org/#eles.dijkstra
         */
        dijkstra(options: SearchDijkstraOptions): SearchDijkstraResult;

        /**
         * Perform the A* search algorithm on the elements in the collection.
         * This finds the shortest path from the root node to the goal node.
         * http://js.cytoscape.org/#eles.aStar
         */
        aStar(options: SearchAStarOptions): SearchAStarResult;

        /**
         * Perform the Floyd Warshall search algorithm on the elements in the collection.
         * This finds the shortest path between all pairs of nodes.
         * http://js.cytoscape.org/#eles.floydWarshall
         */
        floydWarshall(options: SearchFloydWarshallOptions): SearchFloydWarshallResult;

        /**
         * Perform the Bellman-Ford search algorithm on the elements in the collection.
         * This finds the shortest path from the starting node to all other nodes in the collection.
         * http://js.cytoscape.org/#eles.bellmanFord
         */
        bellmanFord(options: SearchBellmanFordOptions): SearchBellmanFordResult;
    
        /**
         * Perform the Hierholzer search algorithm on the elements in the collection.
         * This finds Eulerian trails and circuits.
         * http://js.cytoscape.org/#eles.hierholzer
         */
        hierholzer(options: HierholzerOptions): HierholzerResult;
    }

    interface SpanningAlgorithms {
        /**
         * Perform Kruskal's algorithm on the elements in the collection,
         * returning the minimum spanning tree, assuming undirected edges.
         * http://js.cytoscape.org/#eles.kruskal
         */
        kruskal(handler: (edge: EdgeCollection) => number): CollectionReturnValue;
    }

    interface CutAlgorithms {
        /**
         * Finds the minimum cut in a graph using the Karger-Stein algorithm.
         * The optimal result is found with a high probability, but without guarantee.
         * http://js.cytoscape.org/#eles.kargerStein
         */
        kargerStein(): {
            cut: EdgeCollection;
            components: CollectionReturnValue;
            partitionFirst: NodeCollection;
            partitionSecond: NodeCollection;
        };

        /**
         * finds the biconnected components in an undirected graph,
         * as well as their respective cut vertices, using an algorithm due to Hopcroft and Tarjan.
         * http://js.cytoscape.org/#eles.hopcroftTarjanBiconnected
         */
        hopcroftTarjanBiconnected(): { cut: NodeCollection; components: CollectionReturnValue };
        /**
         * Finds the biconnected components in an undirected graph,
         * as well as their respective cut vertices, using an algorithm due to Hopcroft and Tarjan.
         * http://js.cytoscape.org/#eles.hopcroftTarjanBiconnected
         */
        hopcroftTarjanBiconnectedComponents(): { cut: NodeCollection; components: CollectionReturnValue };
        /**
         * Finds the biconnected components in an undirected graph,
         * as well as their respective cut vertices, using an algorithm due to Hopcroft and Tarjan.
         * http://js.cytoscape.org/#eles.hopcroftTarjanBiconnected
         */
        htb(): { cut: NodeCollection; components: CollectionReturnValue };
        /**
         * Finds the biconnected components in an undirected graph,
         * as well as their respective cut vertices, using an algorithm due to Hopcroft and Tarjan.
         * http://js.cytoscape.org/#eles.hopcroftTarjanBiconnected
         */
        htbc(): { cut: NodeCollection; components: CollectionReturnValue };

        /**
         * Finds the strongly connected components of a directed graph using Tarjan's algorithm.
         * http://js.cytoscape.org/#eles.tarjanStronglyConnected
         */
        tarjanStronglyConnected(): { cut: EdgeCollection; components: CollectionReturnValue };
        /**
         * Finds the strongly connected components of a directed graph using Tarjan's algorithm.
         * http://js.cytoscape.org/#eles.tarjanStronglyConnected
         */
        tarjanStronglyConnectedComponents(): { cut: EdgeCollection; components: CollectionReturnValue };
        /**
         * Finds the strongly connected components of a directed graph using Tarjan's algorithm.
         * http://js.cytoscape.org/#eles.tarjanStronglyConnected
         */
        tsc(): { cut: EdgeCollection; components: CollectionReturnValue };
        /**
         * Finds the strongly connected components of a directed graph using Tarjan's algorithm.
         * http://js.cytoscape.org/#eles.tarjanStronglyConnected
         */
        tscc(): { cut: EdgeCollection; components: CollectionReturnValue };
    }

    interface CentralityAlgorithms {
        /**
         * Considering only the elements in the calling collection,
         * calculate the degree centrality of the specified root node.
         * http://js.cytoscape.org/#eles.degreeCentrality
         */
        degreeCentrality(
            options: SearchDegreeCentralityOptions,
        ): SearchDegreeCentralityResultDirected | SearchDegreeCentralityResultUndirected;

        /**
         * Considering only the elements in the calling collection,
         * calculate the normalised degree centrality of the nodes.
         * http://js.cytoscape.org/#eles.degreeCentralityNormalized
         */
        degreeCentralityNormalized(
            options: SearchDegreeCentralityNormalizedOptions,
        ): SearchDegreeCentralityNormalizedResultDirected | SearchDegreeCentralityNormalizedResultUndirected;

        /**
         * Considering only the elements in the calling collection,
         * calculate the closeness centrality of the specified root node.
         * http://js.cytoscape.org/#eles.closenessCentrality
         */
        closenessCentrality(options: SearchClosenessCentralityOptions): number;
        /**
         * Considering only the elements in the calling collection,
         * calculate the closeness centrality of the nodes.
         * http://js.cytoscape.org/#eles.closenessCentralityNormalized
         */
        closenessCentralityNormalized(
            options: SearchClosenessCentralityNormalizedOptions,
        ): SearchClosenessCentralityNormalizedResult;
        /**
         * Considering only the elements in the calling collection,
         * calculate the betweenness centrality of the nodes.
         * http://js.cytoscape.org/#eles.betweennessCentrality
         */
        betweennessCentrality(options: SearchBetweennessOptions): SearchBetweennessResult;
    
        /**
         * Rank the nodes in the collection using the Page Rank algorithm.
         * http://js.cytoscape.org/#eles.pageRank
         */
        pageRank(options: SearchPageRankOptions): SearchPageRankResult;
    }

    interface ClusteringAlgorithms {
        /**
         * Considering only the elements in the calling collection,
         * run the Markov cluster algorithm of the nodes.
         * http://js.cytoscape.org/#eles.markovClustering
         */
        markovClustering(options: MarkovClusteringOptions): MarkovClusteringResult;
        /**
         * Considering only the nodes in the calling collection,
         * calculate the k-means clustering of the nodes.
         * http://js.cytoscape.org/#nodes.kMeans
         */
        kMeans(options: KMeansOptions): KMeansResult;
        /**
         * Considering only the elements in the calling collection,
         * calculate the agglomerative hierarchical clustering of the nodes.
         * http://js.cytoscape.org/#nodes.hierarchicalClustering
         */
        hierarchicalClustering(options: HierarchicalClusteringOptions): HierarchicalClusteringResult;
    
        /**
         * Considering only the nodes in the calling collection,
         * calculate the k-medoids clustering of the nodes.
         * http://js.cytoscape.org/#nodes.kMedoids
         */
        kMedoids(options: KMedoidsOptions): KMedoidsResult;

        /**
         * Considering only the elements in the calling collection,
         * calculate the fuzzy c-means clustering of the nodes.
         * http://js.cytoscape.org/#nodes.fuzzyCMeans
         */
        fuzzyCMeans(options: FuzzyCMeansOptions): FuzzyCMeansResult;

        /**
         * Considering only the elements in the calling collection,
         * calculate the affinity propagation clustering of the nodes.
         * http://js.cytoscape.org/#nodes.affinityPropagation
         */
        affinityPropagation(options: AffinityPropagationOptions): AffinityPropagationResult;
    }

    interface CollectionAlgorithms extends SearchAlgorithms, SpanningAlgorithms, CutAlgorithms, CentralityAlgorithms, ClusteringAlgorithms {}

    /**
     * http://js.cytoscape.org/#collection/compound-nodes
     */
    interface NodeSingularCompound {
        /**
         * Get whether the node is a compound parent
         * (i.e. a node containing one or more child nodes)
         * http://js.cytoscape.org/#node.isParent
         */
        isParent(): boolean;
        /**
         * Get whether the node is childless (i.e. a node with no child nodes)
         * http://js.cytoscape.org/#node.isChildless
         */
        isChildless(): boolean;
        /**
         * Get whether the node is a compound child (i.e. contained within a node)
         *  http://js.cytoscape.org/#node.isChild
         */
        isChild(): boolean;
        /**
         * Get whether the node is an orphan (i.e. a node with no parent)
         * http://js.cytoscape.org/#node.isOrphan
         */
        isOrphan(): boolean;
    }
    /**
     * http://js.cytoscape.org/#collection/compound-nodes
     */
    interface NodeCollectionCompound {
        /**
         * Get the compound parent node of each node in the collection.
         * @param selector A selector used to filter the resultant collection.
         * http://js.cytoscape.org/#nodes.parent
         */
        parent(selector?: Selector): NodeCollection;
        /**
         * Get all compound ancestor nodes
         * (i.e. parents, parents' parents, etc.) of each node in the collection.
         * @param selector A selector used to filter the resultant collection.
         * http://js.cytoscape.org/#nodes.ancestors
         */
        ancestors(selector?: Selector): NodeCollection;
        parents(selector?: Selector): NodeCollection;
        /**
         * Get all compound ancestors common to all the nodes in the collection,
         * starting with the closest and getting progressively farther.
         * @param selector A selector used to filter the resultant collection.
         * http://js.cytoscape.org/#nodes.commonAncestors
         */
        commonAncestors(selector?: Selector): NodeCollection;
        /**
         * Get all orphan (i.e. has no compound parent) nodes in the calling collection.
         * @param selector A selector used to filter the resultant collection.
         * http://js.cytoscape.org/#nodes.orphans
         */
        orphans(selector?: Selector): NodeCollection;
        /**
         * Get all nonorphan (i.e. has a compound parent) nodes in the calling collection.
         * @param selector A selector used to filter the resultant collection.
         * http://js.cytoscape.org/#nodes.nonorphans
         */
        nonorphans(selector?: Selector): NodeCollection;
        /**
         * Get all compound child (i.e. direct descendant) nodes of each node in the collection.
         * @param selector A selector used to filter the resultant collection.
         * http://js.cytoscape.org/#nodes.children
         */
        children(selector?: Selector): NodeCollection;
        /**
         * Get all compound descendant (i.e. children, children's children, etc.)
         * nodes of each node in the collection.
         * @param selector A selector used to filter the resultant collection.
         * http://js.cytoscape.org/#nodes.descendants
         */
        descendants(selector?: Selector): NodeCollection;
        /**
         * Get all sibling (i.e. same compound parent)
         * nodes of each node in the collection.
         * @param selector A selector used to filter the resultant collection.
         * http://js.cytoscape.org/#nodes.siblings
         */
        siblings(selector?: Selector): NodeCollection;
    }

    /**
     * A selector functions similar to a CSS selector on DOM elements,
     * but selectors in Cytoscape.js instead work on
     * collections of graph elements.
     * Note that wherever a selector may be specified
     * as the argument to a function,
     * a eles.filter()-style filter function may be
     * used in place of the selector.
     *
     * See http://js.cytoscape.org/#selectors for
     * details about writing selectors.
     * Selectors are an island grammar.
     */
    type Selector = string;

    /**
     * A space separated list of event names.
     * http://js.cytoscape.org/#cy.promiseOn
     */
    type EventNames = string;

    /**
     * A string indicating the selection behaviour from user input.
     * http://js.cytoscape.org/#core/initialisation
     *
     * 'additive' : a new selection made by the user adds to the set of currently selected elements.
     * 'single' : a new selection made by the user becomes the entire set of currently
     *            selected elements (i.e. the previous elements are unselected)
     */
    type SelectionType = "additive" | "single";

    /**
     * http://js.cytoscape.org/#ele.group
     * http://js.cytoscape.org/#notation/elements-json
     *
     * 'nodes'
     * 'edges'
     */
    type ElementGroup = "nodes" | "edges";

    /**
     * 'x' : x coordinate
     * 'y' : y coordinate
     */
    type PositionDimension = "x" | "y";

    /**
     * Usually temp or nonserialisable data can be stored.
     * http://js.cytoscape.org/#notation/elements-json
     * http://js.cytoscape.org/#cy.scratch
     * http://js.cytoscape.org/#ele.scratch
     */
    type Scratchpad = any;

    /**
     * Style in Cytoscape.js follows CSS conventions as closely as possible.
     * In most cases, a property has the same name and behaviour as its corresponding CSS namesake.
     * However, the properties in CSS are not sufficient to specify the style of some parts of the graph.
     * In that case, additional properties are introduced that are unique to Cytoscape.js.
     *
     * For simplicity and ease of use, specificity rules are completely ignored in stylesheets.
     * For a given style property for a given element, the last matching selector wins.
     *
     * http://js.cytoscape.org/#style
     */
    namespace Css {
        type Colour = string;

        /**
         * In addition to specifying the value of a property outright, the developer may also use a mapper to dynamically specify the property value.
         * - data()
         * - mapData()
         * - function( ele ){ ... }
         * https://js.cytoscape.org/#style/mappers
         */
        type MapperFunction<Element, Type> = (ele: Element) => Type;

        type PropertyValue<SingularType extends NodeSingular | EdgeSingular | cytoscape.Core, Type> =
            | Type
            | MapperFunction<SingularType, Type>;
        type PropertyValueNode<Type> = PropertyValue<NodeSingular, Type>;
        type PropertyValueEdge<Type> = PropertyValue<EdgeSingular, Type>;
        type PropertyValueCore<Type> = PropertyValue<cytoscape.Core, Type>;

        /**
         * The shape of the node’s body.
         * Note that each shape fits within the specified width and height,
         * and so you may have to adjust width and height
         * if you desire an equilateral shape
         * (i.e. width !== height for several equilateral shapes).
         * 'polygon' is a custom polygon specified via shape-polygon-points.
         */
        type NodeShape =
            | "rectangle"
            | "roundrectangle"
            | "ellipse"
            | "triangle"
            | "pentagon"
            | "hexagon"
            | "heptagon"
            | "octagon"
            | "star"
            | "barrel"
            | "diamond"
            | "vee"
            | "rhomboid"
            | "polygon"
            | "tag"
            | "round-rectangle"
            | "round-triangle"
            | "round-diamond"
            | "round-pentagon"
            | "round-hexagon"
            | "round-heptagon"
            | "round-octagon"
            | "round-tag"
            | "cut-rectangle"
            | "bottom-round-rectangle"
            | "concave-hexagon";

        /**
         * A space-separated list of numbers ranging on [-1, 1],
         * representing alternating x and y values (i.e. x1 y1 x2 y2, x3 y3 ...).
         * This represents the points in the polygon for the node’s shape.
         * The bounding box of the node is given by (-1, -1), (1, -1), (1, 1), (-1, 1).
         */
        type ShapePolygonPoints = string;

        /**
         * The line style; may be solid, dotted, dashed, or double
         */
        type LineStyle = "solid" | "dotted" | "dashed" | "double";

        /**
         * http://js.cytoscape.org/#style/node-body
         */
        interface Node
            extends
                Partial<Overlay>,
                Partial<Underlay>,
                Partial<Outline>,
                PaddingNode,
                Partial<CompoundParentSizing>,
                Partial<Labels<NodeSingular>>,
                BackgroundImage,
                Partial<Ghost>,
                Partial<Visibility<NodeSingular>>,
                Partial<PieChartBackground>,
                Partial<Events<NodeSingular>>,
                Partial<TransitionAnimation>
        {
            /**
             * The CSS content field
             */
            content?: PropertyValueNode<string>;
            /**
             * The width of the node’s body.
             * This property can take on the special value label
             * so the width is automatically based on the node’s label.
             */
            width?: PropertyValueNode<number | string>;
            /**
             * The height of the node’s body.
             * This property can take on the special value label
             * so the height is automatically based on the node’s label.
             */
            height?: PropertyValueNode<number | string>;
            /**
             * The shape of the node’s body.
             */
            shape?: PropertyValueNode<NodeShape>;
            "shape-polygon-points"?: PropertyValueNode<ShapePolygonPoints>;
            backgroundColor?: PropertyValueNode<Colour>;
            /**
             * The colour of the node’s body.
             */
            "background-color"?: PropertyValueNode<Colour>;
            /**
             * Blackens the node’s body for values from 0 to 1;
             * whitens the node’s body for values from 0 to -1.
             */
            "background-blacken"?: PropertyValueNode<number>;
            /**
             * The opacity level of the node’s background colour.
             */
            "background-opacity"?: PropertyValueNode<number>;
            /**
             * The filling style of the node’s body; may be solid (default), linear-gradient, or radial-gradient.
             */
            "background-fill"?: PropertyValueNode<"solid" | "linear-gradient" | "radial-gradient">;
            /**
             * The size of the node’s border.
             */
            "background-gradient-direction"?: PropertyValueNode<string>;
            /**
             * The colors to use at each stop in the gradient for the node’s background; may be specified as a space-separated list or an array.
             */
            "background-gradient-stop-colors"?: PropertyValueNode<string[]>;
            /**
             * The positions of each stop in the gradient for the node’s background; may be specified as a space-separated list or an array.
             */
            "background-gradient-stop-positions"?: PropertyValueNode<(number | string)[]>;
            "border-width"?: PropertyValueNode<number | string>;
            /**
             * The style of the node’s border.
             */
            "border-style"?: PropertyValueNode<LineStyle>;
            /**
             * The colour of the node’s border.
             */
            "border-color"?: PropertyValueNode<Colour>;
            /**
             * The opacity of the node’s border.
             * A value between [0 1].
             */
            "border-opacity"?: PropertyValueNode<number>;
            /**
             * The position of the node’s border.
             * One of: center, inside, outside.
             */
            /**
             * The cap style of the node’s border; may be butt, round or square.
             */
            "border-cap"?: PropertyValueNode<"butt" | "round" | "square">;
            /**
             * The join style of the node’s border; may be miter, bevel or round.
             */
            "border-join"?: PropertyValueNode<"miter" | "bevel" | "round">;
            /**
             * The dashed line pattern which specifies alternating lengths of lines and gaps. (e.g. [6, 3]).
             */
            "border-dash-pattern"?: PropertyValueNode<number[]>;
            /**
             * The dashed line offset (e.g. 24). It is useful for creating edge animations.
             */
            "border-dash-offset"?: PropertyValueNode<number>;
            /**
             * The position of the node’s border; may be center, inside, outside.
             */
            "border-position"?: PropertyValueNode<"center" | "inside" | "outside">;
            /**
             * The corner radius for round shapes and the cut-rectangle, in px or em.
             */
            "corner-radius"?: PropertyValueNode<string>;
        }

        /**
         * A padding defines an addition to a node’s dimension. For example,
         * padding adds to a node’s outer (i.e. total) width and height.
         * This can be used to add spacing between a compound node parent
         * and its children.
         */
        interface PaddingNode {
            /**
             * The amount of padding around all sides of the node. Either percentage or pixel value can be specified.
             * For example, both `50%` and `50px` are acceptable values. By default, percentage padding is calculated as a percentage of node width.
             */
            "padding"?: PropertyValueNode<string>;
            /**
             * Determines how padding is calculated if and only if the percentage unit is used. Accepts one of the keywords specified below.
             * - `width`: calculate padding as a percentage of the node width.
             * - `height`: calculate padding as a percentage of the node height.
             * - `average`: calculate padding as a percentage of the average of the node width and height.
             * - `min`: calculate padding as a percentage of the minimum of the node width and height.
             * - `max`: calculate padding as a percentage of the maximum of the node width and height.
             */
            "padding-relative-to"?: PropertyValueNode<"width" | "height" | "average" | "min" | "max">;
            "padding-left"?: PropertyValueNode<string>;
            "padding-right"?: PropertyValueNode<string>;
            "padding-top"?: PropertyValueNode<string>;
            "padding-bottom"?: PropertyValueNode<string>;
        }

        interface CompoundParentSizing {
            /**
             * Whether to include labels of descendants in sizing a compound node; may be include or exclude.
             */
            "compound-sizing-wrt-labels"?: PropertyValueNode<"include" | "exclude">;
            /**
             * Specifies the minimum (inner) width of the node’s body for a compound parent node (e.g. 400px).
             */
            "min-width"?: PropertyValueNode<string>;
            /**
             * When a compound node is enlarged by its min-width, this value specifies the percent of the extra width put on the left side of the node (e.g. 50%).
             */
            "min-width-bias-left"?: PropertyValueNode<string>;
            /**
             * When a compound node is enlarged by its min-width, this value specifies the percent of the extra width put on the right side of the node (e.g. 50%).
             */
            "min-width-bias-right"?: PropertyValueNode<string>;
            /**
             * Specifies the minimum (inner) height of the node’s body for a compound parent node (e.g. 400px).
             */
            "min-height"?: PropertyValueNode<string>;
            /**
             * When a compound node is enlarged by its min-height, this value specifies the percent of the extra width put on the top side of the node (e.g. 50%).
             */
            "min-height-bias-top"?: PropertyValueNode<string>;
        }

        interface Outline {
            /**
             * The size of the node’s outline.
             */
            "outline-width"?: PropertyValueNode<number | string>;
            /**
             * The style of the node’s outline; may be solid, dotted, dashed, or double.
             */
            "outline-style"?: PropertyValueNode<LineStyle>;
            /**
             * The colour of the node’s outline.
             */
            "outline-color"?: PropertyValueNode<Colour>;
            /**
             * The opacity of the node’s outline.
             */
            "outline-opacity"?: PropertyValueNode<number>;
            /**
             * The offset of the node’s outline.
             */
            "outline-offset"?: PropertyValueNode<number | string>;
        }

        interface Dictionary {
            [key: string]: any;
        }

        // export interface ElementCss extends CSSStyleDeclaration { }
        /**
         * A background image may be applied to a node’s body:
         *
         * http://js.cytoscape.org/#style/background-image
         */
        interface BackgroundImage {
            /**
             * The URL that points to the image that should be used as the node’s background.
             * PNG, JPG, and SVG are supported formats.
             * You may use a data URI to use embedded images,
             * thereby saving a HTTP request.
             */
            "background-image"?: PropertyValueNode<string> | PropertyValueNode<string[]>;
            /**
             * All images are loaded with a crossorigin attribute which may be `anonymous` or
             * `use-credentials`.
             *
             * The default is set to `anonymous`.
             */
            "background-image-crossorigin"?:
                | PropertyValueNode<"anonymous" | "use-credentials">
                | PropertyValueNode<Array<"anonymous" | "use-credentials">>;
            /**
             * The opacity of the background image. [0 1]
             */
            "background-image-opacity"?: PropertyValueNode<number> | PropertyValueNode<number[]>;
            /**
             * Determines whether background image is smoothed (`yes`, default) or not (`no`).
             * This is only a hint, and the browser may or may not respect the
             * value set for this property.
             */
            "background-image-smoothing"?: PropertyValueNode<"yes" | "no"> | PropertyValueNode<Array<"yes" | "no">>;
            /**
             * Determines whether background image is within (`inside`)
             * or over top of the node (`over`).
             *
             * The default is set to `inside`.
             */
            "background-image-containment"?:
                | PropertyValueNode<"inside" | "over">
                | PropertyValueNode<Array<"inside" | "over">>;
            /**
             * Specifies the width of the image.
             * A percent value (e.g. 50%) may be used to set
             * the image width relative to the node width.
             * If used in combination with background- fit,
             * then this value overrides the width of the image
             * in calculating the fitting — thereby overriding the aspect ratio.
             * The auto value is used by default, which uses the width of the image.
             */
            "background-width"?:
                | PropertyValueNode<number | string>
                | PropertyValueNode<Array<number | string>>
               ;
            /**
             * Specifies the height of the image.
             * A percent value (e.g. 50%) may be used to set the image
             * height relative to the node height.
             * If used in combination with background- fit,
             * then this value overrides the height of the image in calculating
             * the fitting — thereby overriding the aspect ratio.
             * The auto value is used by default, which uses the height of the image.
             */
            "background-height"?:
                | PropertyValueNode<number | string>
                | PropertyValueNode<Array<number | string>>
               ;
            /**
             * How the background image is fit to the node;
             * may be none for original size,
             * contain to fit inside node,
             * or cover to cover the node.
             */
            "background-fit"?:
                | PropertyValueNode<"none" | "contain" | "cover">
                | PropertyValueNode<Array<"none" | "contain" | "cover">>
               ;
            /**
             * Whether to repeat the background image;
             * may be no-repeat, repeat-x, repeat-y, or repeat.
             */
            "background-repeat"?:
                | PropertyValueNode<"no-repeat" | "repeat-x" | "repeat-y" | "repeat">
                | PropertyValueNode<Array<"no-repeat" | "repeat-x" | "repeat-y" | "repeat">>
               ;
            /**
             * The x position of the background image,
             * measured in percent(e.g. `'50%'`) or pixels (e.g. `'10px'`).
             */
            "background-position-x"?:
                | PropertyValueNode<number | string>
                | PropertyValueNode<Array<number | string>>
               ;
            /**
             * The y position of the background image,
             * measured in percent(e.g. `'50%'`) or pixels (e.g. `'10px'`).
             */
            "background-position-y"?:
                | PropertyValueNode<number | string>
                | PropertyValueNode<Array<number | string>>
               ;
            /**
             * The x offset of the background image,
             * measured in percent(e.g. `'50%'`) or pixels (e.g. `'10px'`).
             */
            "background-offset-x"?: PropertyValueNode<number | string> | PropertyValueNode<Array<number | string>>;
            /**
             * The y offset of the background image,
             * measured in percent(e.g. `'50%'`) or pixels (e.g. `'10px'`).
             */
            "background-offset-y"?: PropertyValueNode<number | string> | PropertyValueNode<Array<number | string>>;
            /**
             * Changes whether the width is calculated relative to the width of the node or
             * the width in addition to the padding; may be inner or include-padding.
             *
             * If not specified, include-padding is used by default.
             */
            "background-width-relative-to"?:
                | PropertyValueNode<"inner" | "include-padding">
                | PropertyValueNode<Array<"inner" | "include-padding">>;
            /**
             * Changes whether the height is calculated relative to the height of the node or
             * the height in addition to the padding; may be `inner` or `include-padding`.
             *
             * If not specified, `include-padding` is used by default.
             */
            "background-height-relative-to"?:
                | PropertyValueNode<"inner" | "include-padding">
                | PropertyValueNode<Array<"inner" | "include-padding">>;
            /**
             * How background image clipping is handled;
             * may be node for clipped to node shape or none for no clipping.
             */
            "background-clip"?:
                | PropertyValueNode<"node" | "none">
                | PropertyValueNode<Array<"node" | "none">>
               ;
            /**
             * Specifies a padding size (e.g. 20) that expands the bounding box of the node in
             * all directions. This allows for images to be drawn outside of the normal bounding
             * box of the node when `background-clip` is none. This is useful for small decorations
             * just outside of the node.
             *
             * `bounds-expansions` accepts 1 value (for all directions),
             * 2 values, ([topAndBottom, leftAndRight]) or 4 values ([top, right, bottom, left]).
             */
            "bounds-expansion"?: PropertyValueNode<
                | number
                | string
                | [number | string, number | string]
                | [number | string, number | string, number | string, number | string]
            >;
        }

        /**
         * The ghost properties allow for creating a ghosting effect, a semitransparent duplicate of the element drawn at an offset.
         * https://js.cytoscape.org/#style/ghost
         */
        interface Ghost {
            /**
             * Whether to use the ghost effect; may be yes or no.
             */
            ghost: PropertyValueNode<"yes" | "no">;
            /**
             * The horizontal offset used to position the ghost effect.
             */
            "ghost-offset-x": PropertyValueNode<number>;
            /**
             * The vertical offset used to position the ghost effect.
             */
            "ghost-offset-y": PropertyValueNode<number>;
            /**
             * The opacity of the ghost effect.
             */
            "ghost-opacity": PropertyValueNode<number>;
        }

        /**
         * These properties allow you to create pie chart backgrounds on nodes.
         * Note that 16 slices maximum are supported per node,
         * so in the properties 1 <= i <= 16.
         * Of course, you must specify a numerical value for each property in place of i.
         * Each nonzero sized slice is placed in order of i,
         * starting from the 12 o’clock position and working clockwise.
         *
         * You may find it useful to reserve a number to a particular
         * colour for all nodes in your stylesheet.
         * Then you can specify values for pie-i-background-size
         * accordingly for each node via a mapper.
         * This would allow you to create consistently coloured
         * pie charts in each node of the graph based on element data.
         *
         * http://js.cytoscape.org/#style/pie-chart-background
         */
        interface PieChartBackground {
            /**
             *
             * The diameter of the pie, measured as a percent of node size (e.g. 100%) or an absolute length (e.g. 25px).
             */
            "pie-size": PropertyValueNode<number|string>;
            /**
             * 
             * The diameter of the hole in the centre of the pie, measured
             * as a percent of node size (e.g. 100%) or an absolute length
             * (e.g. 25px). This effectively converts the pie chart into a
             * ring chart (default disabled, 0).
             */
            "pie-hole": PropertyValueNode<number|string>;
            /**
             * 
             * The start angle of the pie, measured as an angle starting at
             * the 12 o'clock position and going clockwise (e.g. `90deg`
             * is 3 o'clock).  The default is to start at 12 o'clock (`0deg`, `0rad`).
             */
            "pie-start-angle": PropertyValueNode<number|string>;
            /**
             * @deprecated
             *
             * The colour of the node’s ith pie chart slice.
             */
            "pie-i-background-color": PropertyValueNode<Colour>;
            /**
             * @deprecated
             *
             * The size of the node’s ith (1 <= i <= 16) pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-i-background-size": PropertyValueNode<number>;
            /**
             * @deprecated
             *
             * The opacity of the node’s ith (1 <= i <= 16) pie chart slice.
             */
            "pie-i-background-opacity": PropertyValueNode<number>;

            /**
             * The colour of the node’s 1st pie chart slice.
             */
            "pie-1-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 1st pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-1-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 1st pie chart slice.
             */
            "pie-1-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 2nd pie chart slice.
             */
            "pie-2-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 2nd pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-2-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 2nd pie chart slice.
             */
            "pie-2-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 3rd pie chart slice.
             */
            "pie-3-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 3rd pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-3-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 3rd pie chart slice.
             */
            "pie-3-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 4th pie chart slice.
             */
            "pie-4-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 4th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-4-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 4th pie chart slice.
             */
            "pie-4-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 5th pie chart slice.
             */
            "pie-5-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 5th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-5-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 5th pie chart slice.
             */
            "pie-5-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 6th pie chart slice.
             */
            "pie-6-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 6th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-6-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 6th pie chart slice.
             */
            "pie-6-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 7th pie chart slice.
             */
            "pie-7-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 7th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-7-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 7th pie chart slice.
             */
            "pie-7-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 8th pie chart slice.
             */
            "pie-8-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 8th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-8-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 8th pie chart slice.
             */
            "pie-8-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 9th pie chart slice.
             */
            "pie-9-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 9th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-9-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 9th pie chart slice.
             */
            "pie-9-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 10th pie chart slice.
             */
            "pie-10-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 10th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-10-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 10th pie chart slice.
             */
            "pie-10-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 11th pie chart slice.
             */
            "pie-11-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 11th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-11-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 11th pie chart slice.
             */
            "pie-11-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 12th pie chart slice.
             */
            "pie-12-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 12th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-12-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 12th pie chart slice.
             */
            "pie-12-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 13th pie chart slice.
             */
            "pie-13-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 13th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-13-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 13th pie chart slice.
             */
            "pie-13-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 14th pie chart slice.
             */
            "pie-14-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 14th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-14-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 14th pie chart slice.
             */
            "pie-14-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 15th pie chart slice.
             */
            "pie-15-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 15th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-15-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 15th pie chart slice.
             */
            "pie-15-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 16th pie chart slice.
             */
            "pie-16-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 16th pie chart slice, measured in percent (e.g. 25% or 25).
             */
            "pie-16-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 16th pie chart slice.
             */
            "pie-16-background-opacity": PropertyValueNode<number>;
        }

        /**
         * These properties allow you to create stripe chart backgrounds on
         *  nodes ([demo](demos/stripe-style)).  Note that 16 stripes maximum
         *  are supported per node, so in the properties `1 <= i <= 16`.  Of 
         * course, you must specify a numerical value for each property in 
         * place of `i`.  Each nonzero sized stripe is placed in order of `i`,
         *  starting from the left and going rightwards for vertical stripes 
         * (`stripe-direction: vertical`) or starting from the top and going 
         * downwards for horizontal stripes (`stripe-direction: horizontal`).
         * 
         * You may find it useful to reserve a number to a particular colour 
         * for all nodes in your stylesheet.  Then you can specify values for
         *  `stripe-i-background-size` accordingly for each node via a mapper.  
         *  This would allow you to create consistently coloured pie charts
         *  in each node of the graph based on element data.
         *
         * http://js.cytoscape.org/#style/stripe-chart-background
         */
        interface StripeChartBackground {
            /**
             *
             * The size of the stripes, measured as a percent of node size (e.g. 100%) or an absolute length (e.g. 25px).
             */
            "stripe-size": PropertyValueNode<number|string>;
            /**
             *
             * The direction of the stripes, either `vertical` stripes or `horizontal` stripes.  Vertical stripes are
             * stacked from left to right, and horizontal stripes are stacked from top to bottom.
             */
            "stripe-direction": PropertyValueNode<"vertical" | "horizontal">;
            /**
             * The colour of the node’s 1st stripe chart stripe.
             */
            "stripe-1-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 1st stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-1-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 1st stripe chart stripe.
             */
            "stripe-1-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 2nd stripe chart stripe.
             */
            "stripe-2-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 2nd stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-2-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 2nd stripe chart stripe.
             */
            "stripe-2-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 3rd stripe chart stripe.
             */
            "stripe-3-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 3rd stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-3-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 3rd stripe chart stripe.
             */
            "stripe-3-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 4th stripe chart stripe.
             */
            "stripe-4-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 4th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-4-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 4th stripe chart stripe.
             */
            "stripe-4-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 5th stripe chart stripe.
             */
            "stripe-5-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 5th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-5-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 5th stripe chart stripe.
             */
            "stripe-5-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 6th stripe chart stripe.
             */
            "stripe-6-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 6th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-6-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 6th stripe chart stripe.
             */
            "stripe-6-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 7th stripe chart stripe.
             */
            "stripe-7-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 7th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-7-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 7th stripe chart stripe.
             */
            "stripe-7-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 8th stripe chart stripe.
             */
            "stripe-8-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 8th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-8-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 8th stripe chart stripe.
             */
            "stripe-8-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 9th stripe chart stripe.
             */
            "stripe-9-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 9th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-9-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 9th stripe chart stripe.
             */
            "stripe-9-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 10th stripe chart stripe.
             */
            "stripe-10-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 10th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-10-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 10th stripe chart stripe.
             */
            "stripe-10-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 11th stripe chart stripe.
             */
            "stripe-11-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 11th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-11-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 11th stripe chart stripe.
             */
            "stripe-11-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 12th stripe chart stripe.
             */
            "stripe-12-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 12th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-12-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 12th stripe chart stripe.
             */
            "stripe-12-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 13th stripe chart stripe.
             */
            "stripe-13-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 13th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-13-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 13th stripe chart stripe.
             */
            "stripe-13-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 14th stripe chart stripe.
             */
            "stripe-14-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 14th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-14-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 14th stripe chart stripe.
             */
            "stripe-14-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 15th stripe chart stripe.
             */
            "stripe-15-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 15th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-15-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 15th stripe chart stripe.
             */
            "stripe-15-background-opacity": PropertyValueNode<number>;
            /**
             * The colour of the node’s 16th stripe chart stripe.
             */
            "stripe-16-background-color": PropertyValueNode<Colour>;
            /**
             * The size of the node’s 16th stripe chart stripe, measured in percent (e.g. 25% or 25).
             */
            "stripe-16-background-size": PropertyValueNode<number>;
            /**
             * The opacity of the node’s 16th stripe chart stripe.
             */
            "stripe-16-background-opacity": PropertyValueNode<number>;
        }

        interface Edge
            extends
                EdgeLine,
                EdgeArrow,
                Partial<Gradient>,
                Partial<Overlay>,
                Partial<Underlay>,
                Partial<BezierEdges>,
                Partial<LoopEdges>,
                Partial<UnbundledBezierEdges>,
                Partial<HaystackEdges>,
                Partial<SegmentsEdges>,
                Partial<TaxiEdges>,
                Partial<Visibility<EdgeSingular>>,
                Partial<Labels<EdgeSingular>>,
                Partial<Events<EdgeSingular>>,
                Partial<EdgeEndpoints<EdgeSingular>>,
                Partial<TransitionAnimation>
        {}

        /**
         * These properties affect the styling of an edge’s line:
         *
         * http://js.cytoscape.org/#style/edge-line
         */
        interface EdgeLine {
            /**
             * The width of an edge’s line.
             */
            width?: PropertyValueEdge<number | string>;
            /**
             * The curving method used to separate two or more edges between two nodes;
             * may be
             *  - haystack (default, very fast, bundled straight edges for which loops and compounds are unsupported),
             *  - bezier(bundled curved edges),
             *  - unbundled - bezier(curved edges for use with manual control points), or
             *  - segments (a series of straight lines).
             * Note that haystack edges work best with ellipse, rectangle, or similar nodes.
             * Smaller node shapes, like triangle, will not be as aesthetically pleasing.
             * Also note that edge arrows are unsupported for haystack edges.
             */
            "curve-style"?: PropertyValueEdge<
                | "haystack"
                | "straight"
                | "bezier"
                | "unbundled-bezier"
                | "segments"
                | "taxi"
                | "round-taxi"
                | "round-segments"
            >;
            /**
             * The colour of the edge’s line.
             */
            "line-color"?: PropertyValueEdge<Colour>;
            /**
             * The style of the edge’s line.
             */
            "line-style"?: PropertyValueEdge<LineStyle>;
            /**
             * The cap of the edge's line.
             */
            "line-cap"?: PropertyValueEdge<"butt" | "round" | "square">;
            /**
             * The filling style of the edge's line.
             */
            "line-fill"?: PropertyValueEdge<"solid" | "linear-gradient" | "radial-gradient">;
            /**
             * The opacity of the edge’s line and arrow. Useful if you wish to have a separate opacity for the edge
             * label versus the edge line. Note that the opacity value of the edge element affects the effective
             * opacity of its line and label subcomponents.
             *
             * Value between `0` and `1` inclusive.
             */
            "line-opacity"?: PropertyValueEdge<number>;
            /**
             * The dashed line pattern which specifies alternating lengths of lines and gaps.
             */
            "line-dash-pattern"?: Array<PropertyValueEdge<number>>;
            /**
             * The dashed line offset.
             */
            "line-dash-offset"?: PropertyValueEdge<number>;
            /**
             * The width of the edge’s outline.
             */
            "line-outline-width"?: PropertyValueEdge<number | string>;
            /**
             * The colour of the edge’s outline.
             */
            "line-outline-color"?: PropertyValueEdge<Colour>;
            /**
             * The distance the edge ends from its target.
             */
            "target-distance-from-node"?: PropertyValueEdge<number | string>;
            /**
             * The distance the edge ends from its source.
             */
            "source-distance-from-node"?: PropertyValueEdge<number | string>;
        }

        /**
         * These properties specify the gradient colouration of an edge's line:
         *
         * https://js.cytoscape.org/#style/gradient
         */
        interface Gradient {
            /**
             * The colors of the gradient stops.
             */
            "line-gradient-stop-colors"?: PropertyValueEdge<Colour[]>;
            /**
             * The positions of the gradient stops.
             * If not specified (or invalid), the stops will divide equally.
             */
            "line-gradient-stop-positions"?: PropertyValueEdge<number[]>;
        }

        /**
         * For automatic, bundled bezier edges (curve - style: bezier):
         *
         * http://js.cytoscape.org/#style/bezier-edges
         */
        interface BezierEdges {
            /**
             * From the line perpendicular from source to target,
             * this value specifies the distance between successive bezier edges.
             */
            "control-point-step-size": PropertyValueEdge<number>;
            /**
             * A single value that overrides "control-point-step-size" with a manual value.
             * Because it overrides the step size, bezier edges with the same value will overlap.
             * Thus, it’s best to use this as a one- off value for particular edges if need be.
             */
            "control-point-distance": PropertyValueEdge<number>;
            /**
             * A single value that weights control points along the line from source to target.
             * The value usually ranges on [0, 1], with
             * 0 towards the source node and
             * 1 towards the target node —
             * but larger or smaller values can also be used.
             */
            "control-point-weight": PropertyValueEdge<number>;
            /**
             * With value intersection (default),
             * the line from source to target for "control-point-weight" is
             * from the outside of the source node’s shape to the outside of
             * the target node’s shape.With value node- position,
             * the line is from the source position to the target position.
             * The "node-position" option makes calculating edge points easier
             * — but it should be used carefully because you can create invalid
             * points that intersection would have automatically corrected.
             */
            "edge-distances": PropertyValueEdge<"intersection" | "node-position">;
        }
        /**
         * Loop edges
         * For loops (i.e. same source and target)
         *
         * https://js.cytoscape.org/#style/loop-edges
         */
        interface LoopEdges {
            /**
             * Determines the angle that loops extend from the node in cases when the source and
             * target node of an edge is the same. The angle is specified from the 12 o’clock
             * position and it progresses clockwise for increasing positive values.
             * The default is `-45deg` (extending to the upper left).
             */
            "loop-direction": PropertyValueEdge<string>;
            /**
             * Determines the angle between the leaving and returning edges in loops. Positive
             * values result in clockwise looping and negative values result in counter-clockwise
             * looping. Default is `-90deg`.
             */
            "loop-sweep": PropertyValueEdge<string>;
        }
        /**
         * Unbundled bezier edges
         * For bezier edges with manual control points (curve - style: unbundled - bezier):
         *
         * http://js.cytoscape.org/#style/unbundled-bezier-edges
         */
        interface UnbundledBezierEdges {
            /**
             * A series of values that specify for each control point the
             * distance perpendicular to a line formed
             * from source to target, e.g. -20 20 - 20.
             */
            "control-point-distances": PropertyValueEdge<number | number[] | string>;
            /**
             * A series of values that weights control points along
             * a line from source to target, e.g. 0.25 0.5 0.75.
             * A value usually ranges on [0, 1], with
             * 0 towards the source node and
             * 1 towards the target node
             * — but larger or smaller values can also be used.
             */
            "control-point-weights": PropertyValueEdge<number | number[] | string>;
            /**
             * With value intersection (default),
             * the line from source to target for "control-point-weights"
             * is from the outside of the source node’s shape to the
             * outside of the target node’s shape.
             * With value
             * "node-position", the line is from the source position to the target position.
             * The "node-position" option makes calculating edge points easier
             * — but it should be used carefully because you can create
             * invalid points that intersection would have automatically corrected.
             */
            "edge-distances": PropertyValueEdge<"intersection" | "node-position">;
        }
        /**
         * Haystack edges
         * Loop edges and compound parent nodes are not supported by haystack edges.
         * Haystack edges are a more performant replacement for plain, straight line edges.
         *
         * For fast, straight line edges (curve - style: haystack):
         * http://js.cytoscape.org/#style/haystack-edges
         */
        interface HaystackEdges {
            /**
             * A value between 0 and 1 inclusive that indicates the relative radius used to position haystack edges on their connected nodes.
             * The outside of the node is at 1, and the centre of the node is at 0.
             */
            "haystack-radius": PropertyValueEdge<number>;
        }
        /**
         * Segments edges
         * For edges made of several straight lines (curve - style: segments):
         * http://js.cytoscape.org/#style/segments-edges
         */
        interface SegmentsEdges {
            /**
             * A series of values that specify for each segment point the distance perpendicular to a line formed from source to target, e.g. -20 20 - 20.
             */
            "segment-distances": PropertyValueEdge<number | number[] | string>;
            /**
             * A series of values that weights segment points along a line from source to target,
             * e.g. 0.25 0.5 0.75.A value usually ranges on [0, 1],
             * with 0 towards the source node and 1 towards the target node — but larger or smaller values can also be used.
             */
            "segment-weights": PropertyValueEdge<number | number[] | string>;
            /**
             * A series of values that provide the radii of the different points positioned by segment-distances and segment-weights, e.g. 15 0 5.
             * If less radii are provided than points have been defined, the last provided radius will be used for all the missing radius.
             * If a single radius is provided, it will therefore be applied to all the segment’s points.
             */
            "segment-radii"?: PropertyValueEdge<number[]>;
            /**
             * Defines where segment-radii are applied, which is particularly relevant when the corner angle is acute.
             * Values can be:
             * - `arc-radius`: Default strategy: The radius property is applied to the corner arc, which will be placed further away from the control point if the arc doesn’t fit in an acute angle.
             * - `influence-radius`: The radius property is applied to the control point sphere of influence. The arcs for a given control point will all start and end at radius distance from the control-points.
             */
            "radius-type"?: PropertyValueEdge<"arc-radius" | "influence-radius">;
            /**
             * With value
             *  * "intersection" (default), the line from source to target
             *  * for "segment-weights" is from the outside of the source node’s shape to the outside of the target node’s shape.
             *  * With value "node-position", the line is from the source position to the target position.
             * The "node-position" option makes calculating edge points easier
             * — but it should be used carefully because you can create
             * invalid points that intersection would have automatically corrected.
             */
            "edge-distances": PropertyValueEdge<"intersection" | "node-position">;
        }
        /**
         * Taxi edges
         * For hierarchical, bundled edges (curve-style: taxi)
         *
         * https://js.cytoscape.org/#style/taxi-edges
         */
        interface TaxiEdges {
            /**
             * The main direction of the edge, the direction starting out from the source node; may be one of:
             *  * `auto`: Automatically use `vertical` or `horizontal`, based on whether the vertical or horizontal distance is largest.
             *  * `vertical`: Automatically use `downward` or `upward`, based on the vertical direction from source to target.
             *  * `downward`: Bundle outgoers downwards.
             *  * `upward`: Bundle outgoers upwards.
             *  * `horizontal`: Automatically use `righward` or `leftward`, based on the horizontal direction from source to target.
             *  * `rightward`: Bundle outgoers righwards.
             *  * `leftward`: Bundle outgoers leftwards.
             */
            "taxi-direction": PropertyValueEdge<
                "auto" | "vertical" | "downward" | "upward" | "horizontal" | "rightward" | "leftward"
            >;
            /**
             * The distance along the primary axis where the first turn is applied.
             *  * This value may be an absolute distance (e.g. `'20px'`) or it may be a relative distance
             * between the source and target (e.g. `'50%'`).
             *  * A negative value may be specified to indicate a distance in the oppostite, target to
             * source direction (e.g. `'-20px'`).
             *  * Note that bundling may not work with an explicit direction (upward, downward, leftward, or rightward)
             * in tandem with a turn distance specified in percent units.
             */
            "taxi-turn": PropertyValueEdge<number | number[] | string>;
            /**
             * The minimum distance along the primary axis that is maintained between the nodes and the turns.
             *  * This value only takes on absolute values (e.g. `'5px'`).
             *  * This property makes the taxi edge be re-routed when the turns would be otherwise too close to
             * the source or target. As such, it also helps to avoid turns overlapping edge endpoint arrows.
             */
            "taxi-turn-min-distance": PropertyValueEdge<number | string>;
            /**
             * The radius of the rounded corners of the edge.
             */
            "taxi-radius"?: PropertyValueEdge<number>;
            /**
             * With value `intersection` (default), the `distances` (`taxi-turn` and `taxi-turn-min-distance`)
             * are considered from the outside of the source’s bounds to the outside of the target’s bounds.
             * With value `node-position`, the distances are considered from the source position to the target position.
             * The `node-position` option makes calculating edge points easier — but it should be used carefully because
             * you can create invalid points that `intersection` would have automatically corrected.
             */
            "edge-distances": PropertyValueEdge<"intersection" | "node-position">;
        }

        type ArrowShape =
            | "tee"
            | "vee"
            | "triangle"
            | "triangle-tee"
            | "circle-triangle"
            | "triangle-cross"
            | "triangle-backcurve"
            | "square"
            | "circle"
            | "diamond"
            | "chevron"
            | "none";

        type ArrowFill = "filled" | "hollow";

        /**
         * Edge arrow
         *  * <pos>-arrow-color : The colour of the edge’s source arrow.
         *  * <pos>-arrow-shape : The shape of the edge’s source arrow.
         *  * <pos>-arrow-fill : The fill state of the edge’s source arrow.
         *
         * For each edge arrow property above, replace <pos> with one of
         *  * source : Pointing towards the source node, at the end of the edge.
         *  * mid-source : Pointing towards the source node, at the middle of the edge.
         *  * target : Pointing towards the target node, at the end of the edge.
         *  * mid-target: Pointing towards the target node, at the middle of the edge.
         *
         * Only mid arrows are supported on haystack edges.
         * http://js.cytoscape.org/#style/edge-arrow
         */
        interface EdgeArrow {
            /** The size of the arrow. */
            "arrow-scale"?: PropertyValueEdge<number>;

            /** The colour of the edge’s source arrow. */
            "source-arrow-color"?: PropertyValueEdge<Colour>;
            /** The colour of the edge’s "mid-source" arrow. */
            "mid-source-arrow-color"?: PropertyValueEdge<Colour>;
            /** The colour of the edge’s target arrow. */
            "target-arrow-color"?: PropertyValueEdge<Colour>;
            /** The colour of the edge’s "mid-target" arrow. */
            "mid-target-arrow-color"?: PropertyValueEdge<Colour>;

            /** The shape of the edge’s source arrow. */
            "source-arrow-shape"?: PropertyValueEdge<ArrowShape>;
            /** The shape of the edge’s mid-source arrow. */
            "mid-source-arrow-shape"?: PropertyValueEdge<ArrowShape>;
            /** The shape of the edge’s target arrow. */
            "target-arrow-shape"?: PropertyValueEdge<ArrowShape>;
            /** The shape of the edge’s mid-target arrow. */
            "mid-target-arrow-shape"?: PropertyValueEdge<ArrowShape>;

            /** The fill state of the edge’s source arrow. */
            "source-arrow-fill"?: PropertyValueEdge<ArrowFill>;
            /** The fill state of the edge’s mid-source arrow. */
            "mid-source-arrow-fill"?: PropertyValueEdge<ArrowFill>;
            /** The fill state of the edge’s target arrow. */
            "target-arrow-fill"?: PropertyValueEdge<ArrowFill>;
            /** The fill state of the edge’s mid-target arrow. */
            "mid-target-arrow-fill"?: PropertyValueEdge<ArrowFill>;
        }

        /**
         * https://js.cytoscape.org/#style/edge-endpoints
         */
        interface EdgeEndpoints<SingularType extends EdgeSingular> {
            /** Specifies the endpoint of the source side of the edge  */
            "source-endpoint": PropertyValue<
                SingularType,
                | "inside-to-node"
                | "outside-to-node"
                | "outside-to-node-or-label"
                | "outside-to-line"
                | "outside-to-line-or-label"
                | string
            >;
            /** Specifies the endpoint of the target side of the edge  */
            "target-endpoint": PropertyValue<
                SingularType,
                | "inside-to-node"
                | "outside-to-node"
                | "outside-to-node-or-label"
                | "outside-to-line"
                | "outside-to-line-or-label"
                | string
            >;
        }

        /**
         * http://js.cytoscape.org/#style/visibility
         */
        interface Visibility<SingularType extends NodeSingular | EdgeSingular> {
            /**
             * Whether to display the element; may be element for displayed or none for not displayed.
             * Note that a "display: none" bezier edge does not take up space in its bundle.
             */
            display: PropertyValue<SingularType, "none" | "element">;
            /**
             * Whether the element is visible; may be visible or hidden.
             * Note that a "visibility : hidden" bezier edge still takes up space in its bundle.
             */
            visibility: PropertyValue<SingularType, "hidden" | "visible">;
            /**
             * The opacity of the element, ranging from 0 to 1.
             * Note that the opacity of a compound node parent affects the effective opacity of its children.
             */
            opacity: PropertyValue<SingularType, number>;
            /**
             * An integer value that affects the relative draw order of elements.
             * In general, an element with a higher "z-index" will be drawn on top of an element with a lower "z-index".
             * Note that edges are under nodes despite "z-index", except when necessary for compound nodes.
             */
            "z-index": PropertyValue<SingularType, number>;
            /**
             * May be bottom, orphan, auto (default), or top. The first drawn is bottom, the second is orphan,
             * which is the same depth as the root of the compound graph, followed by the default of auto
             * which draws in depth order from root to leaves of the compound graph. The last drawn is top.
             * It does not usually make sense to set this value for non-compound graphs.
             */
            "z-compound-depth": PropertyValue<SingularType, "auto" | "top" | "bottom" | "orphan">;
            /**
             * May be auto (default) or manual. The auto setting draws edges under nodes,
             * whereas manual ignores this convention and draws solely based on the z-index value.
             */
            "z-index-compare": PropertyValue<SingularType, "auto" | "manual">;
        }

        /** https://developer.mozilla.org/en-US/docs/Web/CSS/font-style */
        type FontStyle = "normal" | "italic" | "oblique";

        /** https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight */
        type FontWeight = number | "normal" | "bold" | "lighter" | "bolder";

        /** http://js.cytoscape.org/#style/labels */
        type TextTranformation = "none" | "uppercase" | "lowercase";

        /**
         * Labels
         * Label text:
         *
         * http://js.cytoscape.org/#style/labels
         */
        interface Labels<SingularType extends NodeSingular | EdgeSingular> {
            /**
             * The text to display for an element’s label.
             */
            label: PropertyValue<SingularType, string>;
            /**
             * The text to display for an edge’s source label.
             */
            "source-label": PropertyValue<SingularType, string>;
            /**
             * The text to display for an edge’s target label.
             */
            "target-label": PropertyValue<SingularType, string>;
            /**
             * Basic font styling:
             */
            /**
             * The colour of the element’s label.
             */
            color: PropertyValue<SingularType, Colour>;
            /**
             * The opacity of the label text, including its outline.
             */
            "text-opacity": PropertyValue<SingularType, number>;
            /**
             * A comma-separated list of font names to use on the label text.
             */
            "font-family": PropertyValue<SingularType, string>;
            /**
             * The size of the label text.
             * https://developer.mozilla.org/en-US/docs/Web/CSS/font-family
             */
            "font-size": PropertyValue<SingularType, number | string>;
            /**
             * A CSS font style to be applied to the label text.
             * https://developer.mozilla.org/en-US/docs/Web/CSS/font-style
             */
            "font-style": PropertyValue<SingularType, FontStyle>;
            /**
             * A CSS font weight to be applied to the label text.
             */
            "font-weight": PropertyValue<SingularType, FontWeight>;
            /**
             * A transformation to apply to the label text.
             */
            "text-transform": PropertyValue<SingularType, TextTranformation>;

            /**
             * Wrapping text:
             */

            /**
             * A wrapping style to apply to the label text; may be
             *  * "none" for no wrapping (including manual newlines ) or
             *  * "wrap" for manual and/ or autowrapping.
             *  * "ellipsis" to truncate the string and append
             */
            "text-wrap": PropertyValue<SingularType, "none" | "wrap" | "ellipsis">;
            /**
             * The maximum width for wrapped text,
             * applied when "text-wrap" is set to wrap.
             * For only manual newlines (i.e.\n), set a very large
             * value like 1000px such that only your newline characters would apply.
             */
            "text-max-width": PropertyValue<SingularType, string>;
            /**
             * The characters that may be used for possible wrapping locations when
             * a line overflows `text-max-width`; may be `whitespace` (default) or `anywhere`.
             * Note that anywhere is suited to CJK, where the characters are in a grid
             * and no whitespace exists. Using anywhere with text in the Latin alphabet,
             * for example, will split words at arbitrary locations.
             */
            "text-overflow-wrap": PropertyValue<SingularType, "whitespace" | "anywhere">;
            /**
             * The justification of multiline (wrapped) labels; may be
             * `left`, `center`, `right`, or `auto` (default). The auto value makes it so that a
             * node’s label is justified along the node — e.g. a label on the right side
             * of a node is left justified.
             */
            "text-justification": PropertyValue<SingularType, "auto" | "left" | "center" | "right">;
            /**
             * The line height of multiline text, as a relative, unitless value. It specifies the
             * vertical spacing between each line. With value `1` (default), the lines are stacked
             * directly on top of one another with no additional whitespace between them.
             * With value `2`, for example, there is whitespace between each line equal to the visible
             * height of a line of text.
             */
            "line-height": PropertyValue<SingularType, number>;

            /**
             * Node label alignment:
             */

            /**
             * The vertical alignment of a node’s label.
             */
            "text-halign": PropertyValue<SingularType, "left" | "center" | "right">;
            /**
             * The vertical alignment of a node’s label.
             */
            "text-valign": PropertyValue<SingularType, "top" | "center" | "bottom">;

            /**
             * Edge label alignment:
             */

            /**
             * For the source label of an edge, how far from the source node the label should be placed.
             */
            "source-text-offset": PropertyValue<SingularType, number>;
            /**
             * For the target label of an edge, how far from the target node the label should be placed.
             */
            "target-text-offset": PropertyValue<SingularType, number>;
            /**
             * Margins:
             */

            /**
             * A margin that shifts the label along the x- axis.
             */
            "text-margin-x": PropertyValue<SingularType, number>;
            /**
             * A margin that shifts the label along the y- axis.
             */
            "text-margin-y": PropertyValue<SingularType, number>;
            /**
             * (For the source label of an edge.)
             */
            "source-text-margin-x": PropertyValue<SingularType, number>;
            /**
             * (For the source label of an edge.)
             */
            "source-text-margin-y": PropertyValue<SingularType, number>;
            /**
             * (For the target label of an edge.)
             */
            "target-text-margin-x": PropertyValue<SingularType, number>;
            /**
             * (For the target label of an edge.)
             */
            "target-text-margin-y": PropertyValue<SingularType, number>;
            /**
             * Rotating text:
             */

            /**
             * A rotation angle that is applied to the label.
             *  * Rotations are clockwise.
             *  * For edges, the special value `autorotate` can be used to align the label to the edge.
             *  * For nodes, the label is rotated along its anchor point on the node, so a label margin may help for some usecases.
             *  * The special value `none` can be used to denote 0deg.
             *  * Rotations works best with left-to-right text.
             */
            "text-rotation": PropertyValue<SingularType, number | "autorotate" | "none">;

            /**
             * (For the source label of an edge.)
             */
            "source-text-rotation": PropertyValue<SingularType, number | "autorotate" | "none">;
            /**
             * (For the target label of an edge.)
             */
            "target-text-rotation": PropertyValue<SingularType, number | "autorotate" | "none">;

            /**
             * Outline:
             */

            /**
             * The colour of the outline around the element’s label text.
             */
            "text-outline-color": PropertyValue<SingularType, Colour>;
            /**
             * The opacity of the outline on label text.
             */
            "text-outline-opacity": PropertyValue<SingularType, number>;
            /**
             * The size of the outline on label text.
             */
            "text-outline-width": PropertyValue<SingularType, number | string>;

            /**
             * Background:
             */

            /**
             * The padding provides visual spacing between the text and the edge of the background.
             */
            "text-background-padding": PropertyValue<SingularType, string>;
            /**
             * A colour to apply on the text background.
             */
            "text-background-color": PropertyValue<SingularType, Colour>;
            /**
             * The opacity of the label background; the background is disabled for 0 (default value).
             */
            "text-background-opacity": PropertyValue<SingularType, number>;
            /**
             * The shape to use for the label background.
             */
            "text-background-shape": PropertyValue<SingularType, "rectangle" | "roundrectangle" | "circle">;

            /**
             * Border:
             */

            /**
             * The width of the border around the label; the border is disabled for 0 (default value).
             */
            "text-border-opacity": PropertyValue<SingularType, number>;
            /**
             * The width of the border around the label.
             */
            "text-border-width": PropertyValue<SingularType, number>;
            /**
             * The style of the border around the label.
             */
            "text-border-style": PropertyValue<SingularType, LineStyle>;
            /**
             * The colour of the border around the label.
             */
            "text-border-color": PropertyValue<SingularType, Colour>;

            /**
             * Interactivity:
             */

            /**
             * If zooming makes the effective font size of the label smaller than this,
             * then no label is shown.Note that because of performance optimisations,
             * the label may be shown at font sizes slightly smaller than this value.
             *
             * This effect is more pronounced at larger screen pixel ratios.However,
             * it is guaranteed that the label will be shown at sizes equal to or greater than the value specified.
             */
            "min-zoomed-font-size": PropertyValue<SingularType, number | string>;
            /**
             * Whether events should occur on an element if the label receives an event; may be `yes` or `no`.
             * You may want a style applied to the text on active so you know the text is activatable.
             */
            "text-events": PropertyValue<SingularType, "yes" | "no">;
            /**
             * Defines how an element responds to box selection via a selection rectangle.
             * 
             * - `contain` (default): The element is selected only if it is entirely within the selection box.
             * - `overlap`: The element is selected if it intersects with any part of the selection box.
             * - `none`: The element is excluded from box selection.
             * 
             * This property can be applied to nodes, edges, or both. For example, use `overlap` for more lenient selection or `contain` for stricter control.
             */
            "box-selection": PropertyValue<SingularType, "contain" | "overlap" | "none">;
        }

        /**
         * http://js.cytoscape.org/#style/events
         */
        interface Events<SingularType extends NodeSingular | EdgeSingular> {
            /**
             * Whether events should occur on an element (e.g.tap, mouseover, etc.).
             *  * For "no", the element receives no events and events simply pass through to the core/viewport.
             */
            events: PropertyValue<SingularType, "yes" | "no">;
            /**
             *  Whether events should occur on an element if the label receives an event.
             * You may want a style applied to the text on active so you know the text is activatable.
             */
            "text-events": PropertyValue<SingularType, "yes" | "no">;
        }

        /**
         * These properties allow for the creation of overlays on top of nodes or edges,
         * and are often used in the :active state.
         * http://js.cytoscape.org/#style/overlay
         */
        interface Overlay {
            /**
             * The colour of the overlay.
             */
            "overlay-color": PropertyValueEdge<Colour>;
            /**
             * The area outside of the element within which the overlay is shown.
             */
            "overlay-padding": PropertyValueEdge<number | string>;
            /**
             * The opacity of the overlay.
             */
            "overlay-opacity": PropertyValueEdge<number>;

            /**
             * The shape of the node overlay; may be round-rectangle (default), ellipse. Doesn’t apply to edges.
             */
            "overlay-shape"?: PropertyValueEdge<"round-rectangle" | "ellipse">;
        }

        /**
         * These properties allow for the creation of underlays behind nodes or edges,
         * and are often used in a highlighted state.
         */
        interface Underlay {
            /**
             * The colour of the underlay.
             */
            "underlay-color"?: PropertyValueNode<Colour>;
            /**
             * The area outside of the element within which the underlay is shown.
             */
            "underlay-padding"?: PropertyValueNode<number | string>;
            /**
             * The opacity of the underlay.
             */
            "underlay-opacity"?: PropertyValueNode<number>;
            /**
             * The shape of the node underlay; may be round-rectangle (default), ellipse. Doesn’t apply to edges.
             */
            "underlay-shape"?: PropertyValueNode<"round-rectangle" | "ellipse">;
        }

        /**
         * Transition animation
         */
        type TransitionTimingFunction =
            | "linear"
            | "spring"
            | "cubic-bezier"
            | "ease"
            | "ease-in"
            | "ease-out"
            | "ease-in-out"
            | "ease-in-sine"
            | "ease-out-sine"
            | "ease-in-out-sine"
            | "ease-in-quad"
            | "ease-out-quad"
            | "ease-in-out-quad"
            | "ease-in-cubic"
            | "ease-out-cubic"
            | "ease-in-out-cubic"
            | "ease-in-quart"
            | "ease-out-quart"
            | "ease-in-out-quart"
            | "ease-in-quint"
            | "ease-out-quint"
            | "ease-in-out-quint"
            | "ease-in-expo"
            | "ease-out-expo"
            | "ease-in-out-expo"
            | "ease-in-circ"
            | "ease-out-circ"
            | "ease-in-out-circ";

        /**
         * http://js.cytoscape.org/#style/transition-animation
         */
        interface TransitionAnimation {
            /**
             * A comma separated list of style properties to animate in this state.
             */
            "transition-property": string;
            /**
             * The length of the transition in seconds(e.g. 0.5s).
             */
            "transition-duration": number;
            /**
             * The length of the delay in seconds before the transition occurs (e.g. 250ms).
             */
            "transition-delay": number;
            /**
             * An easing function that controls the animation progress curve (a visualisation of easings serves as a reference).
             */
            "transition-timing-function": TransitionTimingFunction;
        }

        /**
         * Core
         * These properties affect UI global to the graph, and apply only to the core.
         * You can use the special core selector string to set these properties.
         * http://js.cytoscape.org/#style/core
         */
        interface Core {
            /**
             * Indicator:
             */

            /**
             * The colour of the indicator shown when the background is grabbed by the user.
             */
            "active-bg-color": PropertyValueCore<Colour>;
            /**
             * The opacity of the active background indicator.
             */
            "active-bg-opacity": PropertyValueCore<number>;
            /**
             * The size of the active background indicator.
             */
            "active-bg-size": PropertyValueCore<number>;
            /**
             * Selection box:
             */
            /**
             * The background colour of the selection box used for drag selection.
             */
            "selection-box-color": PropertyValueCore<Colour>;
            /**
             * The colour of the border on the selection box.
             */
            "selection-box-border-color": PropertyValueCore<Colour>;
            /**
             * The size of the border on the selection box.
             */
            "selection-box-border-width": PropertyValueCore<number>;
            /**
             * The opacity of the selection box.
             */
            "selection-box-opacity": PropertyValueCore<number>;
            /**
             * Texture during viewport gestures:
             */
            /**
             * The colour of the area outside the viewport texture when initOptions.textureOnViewport === true.
             */
            "outside-texture-bg-color": PropertyValueCore<Colour>;
            /**
             * The opacity of the area outside the viewport texture.
             */
            "outside-texture-bg-opacity": PropertyValueCore<number>;
        }
    }

    /**
     * Events passed to handler callbacks are similar to
     * jQuery event objects in that they wrap native event objects,
     * mimicking their API.
     *
     * http://js.cytoscape.org/#events
     */
    interface EventObject extends InputEventObject, LayoutEventObject {}

    interface EventObjectNode extends EventObject {
        target: NodeSingular;
    }

    interface EventObjectEdge extends EventObject {
        target: EdgeSingular;
    }

    interface EventObjectCore extends EventObject {
        target: Core;
    }

    /**
     * http://js.cytoscape.org/#events/event-object
     */
    interface AbstractEventObject {
        /** a reference to the corresponding core Core */
        cy: Core;
        /** indicates the element or core that first caused the event */
        target: any;
        /** the event type string (e.g. "tap", "select") */
        type: UserInputDeviceEventName | UserInputDeviceEventNameExt | CollectionEventName | GraphEventName;
        /** the event namespace string (e.g. "foo" for "foo.tap") */
        namespace: string;
        /** Unix epoch time of event in milliseconds */
        timeStamp: number;

        preventDefault: () => void;
        stopPropagation: () => void;
        stopImmediatePropagation: () => void;
        isDefaultPrevented: () => boolean;
        isPropagationStopped: () => boolean;
        isImmediatePropagationStopped: () => boolean;
    }
    interface InputEventObject extends AbstractEventObject {
        /** position : indicates the model position of the event */
        position: Position;
        /** renderedPosition : indicates the rendered position of the event */
        renderedPosition: Position;
        /** originalEvent : the original user input device event object */
        originalEvent: MouseEvent;
    }
    interface LayoutEventObject extends AbstractEventObject {
        /**
         * layout : indicates the corresponding layout that triggered the event
         * (useful if running multiple layouts simultaneously)
         */
        layout: any;
    }

    /**
     * These are normal browser events that you can bind to via Cytoscape.js.
     * You can bind these events to the core and to collections.
     * http://js.cytoscape.org/#events/user-input-device-events
     */
    type UserInputDeviceEventName =
        // when the mouse button is pressed
        | "mousedown"
        // when the mouse button is released
        | "mouseup"
        // after mousedown then mouseup
        | "click"
        // when the cursor is put on top of the target
        | "mouseover"
        // when the cursor is moved off of the target
        | "mouseout"
        // when the cursor is moved somewhere on top of the target
        | "mousemove"
        // when one or more fingers starts to touch the screen
        | "touchstart"
        // when one or more fingers are moved on the screen
        | "touchmove"
        // when one or more fingers are removed from the screen
        | "touchend";

    /**
     * There are also some higher level events that you can use
     * so you don’t have to bind to different events for
     * mouse-input devices and for touch devices.
     * http://js.cytoscape.org/#events/user-input-device-events
     */
    type UserInputDeviceEventNameExt =
        // normalised tap start event (either mousedown or touchstart)
        | "tapstart"
        | "vmousedown"
        // normalised move event (either touchmove or mousemove)
        | "tapdrag"
        | "vmousemove"
        // normalised over element event (either touchmove or mousemove/mouseover)
        | "tapdragover"
        // normalised off of element event (either touchmove or mousemove/mouseout)
        | "tapdragout"
        // normalised tap end event (either mouseup or touchend)
        | "tapend"
        | "vmouseup"
        // normalised tap event (either click, or touchstart followed by touchend without touchmove)
        | "tap"
        | "vclick"
        // normalised tap hold event
        | "taphold"
        // normalised right-click mousedown or two-finger tapstart
        | "cxttapstart"
        // normalised right-click mouseup or two-finger tapend
        | "cxttapend"
        // normalised right-click or two-finger tap
        | "cxttap"
        // normalised mousemove or two-finger drag after cxttapstart but before cxttapend
        | "cxtdrag"
        // when going over a node via cxtdrag
        | "cxtdragover"
        // when going off a node via cxtdrag
        | "cxtdragout"
        // when starting box selection
        | "boxstart"
        // when ending box selection
        | "boxend"
        // triggered on elements when selected by box selection
        | "boxselect"
        // triggered on elements when inside the box on boxend
        | "box";

    /**
     * These events are custom to Cytoscape.js. You can bind to these events for collections.
     * http://js.cytoscape.org/#events/collection-events
     */
    type CollectionEventName =
        // when an element is added to the graph
        | "add"
        // when an element is removed from the graph
        | "remove"
        // when an element is moved w.r.t. topology. Nodes: when the compound parent is changed. Edges: when the source or target is changed
        | "move"
        // when an element is selected
        | "select"
        // when an element is unselected
        | "unselect"
        // when an element is selected by a tap gesture
        | "tapselect"
        // when an element is unselected by a tap elsewhere
        | "tapunselect"
        // triggered on elements when selected by box selection
        | "boxselect"
        // triggered on elements when inside the box on boxend
        | "box"
        // when an element is locked
        | "lock"
        // when an element is unlocked
        | "unlock"
        // when an element is grabbed directly (including only the one node directly under the cursor or the user’s finger)
        | "grabon"
        // when an element is grabbed (including all elements that would be dragged)
        | "grab"
        // when an element is grabbed and then moved
        | "drag"
        // when an element is freed (i.e. let go from being grabbed)
        | "free"
        // when an element is freed directly (including only the one node directly under the cursor or the user’s finger)
        | "freeon"
        // when an element is freed after being dragged (i.e. grab then drag then free)
        | "dragfree"
        // when an element is freed after being dragged directly (i.e. grabon, drag, freeon)
        | "dragfreeon"
        // when an element changes position
        | "position"
        // when an element’s data is changed
        | "data"
        // when an element’s scratchpad data is changed
        | "scratch"
        // when an element’s style is changed
        | "style"
        // when a node’s background image is loaded
        | "background";

    /**
     * These events are custom to Cytoscape.js, and they occur on the core.
     * http://js.cytoscape.org/#events/graph-events
     */
    type GraphEventName =
        // when a layout starts running
        | "layoutstart"
        // when a layout has set initial positions for all the nodes (but perhaps not final positions)
        | "layoutready"
        // when a layout has finished running completely or otherwise stopped running
        | "layoutstop"
        // when a new Core of Cytoscape.js is ready to be interacted with
        | "ready"
        // when the Core of Cytoscape.js was explicitly destroyed by calling .destroy().
        | "destroy"
        // when the viewport is (re)rendered
        | "render"
        // when the viewport is panned
        | "pan"
        // when the viewport is panned via dragging
        | "dragpan"
        // when the viewport is zoomed
        | "zoom"
        // when the viewport is zoomed via pinch gesture. This event is only supported for browsers which support the gesturechange event or touch events.
        // Other browsers will fire the scrollzoom event.
        | "pinchzoom"
        // when the viewport is zoomed via the scroll wheel
        | "scrollzoom"
        // when the viewport is changed (i.e. from a pan, a zoom, or from both when zooming about a point – e.g. pinch-to-zoom)
        | "viewport"
        // when the viewport is resized (usually by calling cy.resize(), a window resize, or toggling a class on the Cytoscape.js div)
        | "resize";

    /**
     * Layouts
     * http://js.cytoscape.org/#layouts
     *
     * The function of a layout is to set the positions on the nodes in the graph.
     * Layouts are extensions of Cytoscape.js such that it is possible for
     * anyone to write a layout without modifying the library itself.
     * Several layouts are included with Cytoscape.js by default,
     * and their options are described in the sections that follow
     * with the default values specified.
     * Note that you must set options.name to the name of the
     * layout to specify which one you want to run.
     * Each layout has its own algorithm for setting the position for each node.
     * This algorithm influences the overall shape of the graph and the lengths of the edges.
     * A layout’s algorithm can be customised by setting its options.
     * Therefore, edge lengths can be controlled by setting the layout options appropriately.
     * For force-directed (physics) layouts,
     * there is generally an option to set a weight to each edge
     * to affect the relative edge lengths.
     * Edge length can also be affected by options like spacing
     * factors, angles, and overlap avoidance.
     * Setting edge length depends on the particular layout,
     * and some layouts will allow for more precise edge lengths than others.
     */

    interface Layouts extends LayoutManipulation, LayoutEvents {}

    type LayoutOptions =
        | NullLayoutOptions
        | RandomLayoutOptions
        | PresetLayoutOptions
        | GridLayoutOptions
        | CircleLayoutOptions
        | ConcentricLayoutOptions
        | BreadthFirstLayoutOptions
        | CoseLayoutOptions
        | BaseLayoutOptions;

    type LayoutHandler = (e: LayoutEventObject) => void;

    interface BaseLayoutOptions {
        name: string;
        // on layoutready event
        ready?: LayoutHandler;
        // on layoutstop event
        stop?: LayoutHandler;
        /**
         * transform a given node position. Useful for changing flow direction in discrete layouts
         *
         * @param node The node.
         * @param position The node position.
         */
        transform?(node: NodeSingular, position: Position): Position;
    }
    /**
     * http://js.cytoscape.org/#layouts/null
     */
    interface NullLayoutOptions {
        name: "null";
    }
    interface BoundingBox12 {
        x1: number;
        y1: number;
        x2: number;
        y2: number;
    }
    interface BoundingBoxWH {
        x1: number;
        y1: number;
        w: number;
        h: number;
    }
    interface AnimatedLayoutOptions {
        // whether to transition the node positions
        animate?: boolean;
        // duration of animation in ms if enabled
        animationDuration?: number;
        // easing of animation if enabled
        animationEasing?: Css.TransitionTimingFunction;
        /**
         * a function that determines whether the node should be animated.
         * All nodes animated by default on animate enabled.
         * Non-animated nodes are positioned immediately when the layout starts
         */
        animateFilter?(node: NodeSingular, index: number): boolean;
    }
    /**
     * http://js.cytoscape.org/#layouts/random
     */
    interface RandomLayoutOptions extends BaseLayoutOptions, AnimatedLayoutOptions {
        name: "random";
        // whether to fit to viewport
        fit?: boolean;
        // fit padding
        padding?: number;
        // constrain layout bounds
        boundingBox?: undefined | BoundingBox12 | BoundingBoxWH;
    }

    /**
     * http://js.cytoscape.org/#layouts/preset
     */
    interface NodePositionMap {
        [nodeid: string]: Position;
    }
    type NodePositionFunction = (nodeid: string) => Position;
    interface PresetLayoutOptions extends BaseLayoutOptions, AnimatedLayoutOptions {
        name: "preset";
        // map of (node id) => (position obj); or function(node){ return somPos; }
        positions?: NodePositionMap | NodePositionFunction;
        // the zoom level to set (prob want fit = false if set)
        zoom?: number;
        // the pan level to set (prob want fit = false if set)
        pan?: Position;
        // whether to fit to viewport
        fit?: boolean;
        // padding on fit
        padding?: number;
    }

    // A function that determines the order of the nodes. The return value has the same
    // semantics as for compare function passed to Array.sort.
    type SortingFunction = (a: NodeSingular, b: NodeSingular) => number;

    interface ShapedLayoutOptions extends BaseLayoutOptions, AnimatedLayoutOptions {
        // whether to fit to viewport
        fit?: boolean;
        // padding used on fit
        padding?: number;
        // constrain layout bounds
        boundingBox?: BoundingBox12 | BoundingBoxWH;

        // prevents node overlap, may overflow boundingBox if not enough space
        avoidOverlap?: boolean;

        // Excludes the label when calculating node bounding boxes for the layout algorithm
        nodeDimensionsIncludeLabels?: boolean;
        // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up
        spacingFactor?: number;

        // a sorting function to order the nodes
        sort?: SortingFunction;
    }
    /**
     * http://js.cytoscape.org/#layouts/grid
     */
    interface GridLayoutOptions extends ShapedLayoutOptions {
        name: "grid";

        // extra spacing around nodes when avoidOverlap: true
        avoidOverlapPadding?: number;

        // uses all available space on false, uses minimal space on true
        condense?: boolean;
        // force num of rows in the grid
        rows?: number;
        // force num of columns in the grid
        cols?: number;
        // returns { row, col } for element
        position?(node: NodeSingular): { row: number; col: number };
    }

    /**
     * http://js.cytoscape.org/#layouts/circle
     */
    interface CircleLayoutOptions extends ShapedLayoutOptions {
        name: "circle";

        // the radius of the circle
        radius?: number;

        // where nodes start in radians, e.g. 3 / 2 * Math.PI,
        startAngle?: number;
        // how many radians should be between the first and last node (defaults to full circle)
        sweep?: number;
        // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)
        clockwise?: boolean;
    }
    /**
     * http://js.cytoscape.org/#layouts/concentric
     */
    interface ConcentricLayoutOptions extends ShapedLayoutOptions {
        name: "concentric";

        // where nodes start in radians, e.g. 3 / 2 * Math.PI,
        startAngle?: number;
        // how many radians should be between the first and last node (defaults to full circle)
        sweep?: number;
        // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)
        clockwise?: boolean;

        // whether levels have an equal radial distance betwen them, may cause bounding box overflow
        equidistant?: boolean;
        minNodeSpacing?: number; // min spacing between outside of nodes (used for radius adjustment)
        // height of layout area (overrides container height)
        height?: number;
        // width of layout area (overrides container width)
        width?: number;
        // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up
        spacingFactor?: number;
        // returns numeric value for each node, placing higher nodes in levels towards the centre
        concentric?(node: NodeSingular): number;
        // the variation of concentric values in each level
        levelWidth?(node: NodeCollection): number;
    }

    /**
     * http://js.cytoscape.org/#layouts/breadthfirst
     */
    interface BreadthFirstLayoutOptions extends ShapedLayoutOptions {
        name: "breadthfirst";

        // whether the tree is directed downwards (or edges can point in any direction if false)
        directed?: boolean;
        // determines the direction in which the tree structure is drawn
        direction?: 'downward' | 'upward' | 'rightward' | 'leftward';
        // put depths in concentric circles if true, put depths top down if false
        circle?: boolean;
        // the roots of the trees
        roots?: string[];
        // Deprecated: how many times to try to position the nodes in a maximal way (i.e. no backtracking)
        maximalAdjustments?: number;
        // whether to shift nodes down their natural BFS depths in order to avoid upwards edges (DAGS only)
        maximal?: boolean;
        // whether to create an even grid into which the DAG is placed (circle:false only)
        grid?: boolean;
        // a sorting function to order nodes at equal depth. e.g. function(a, b){ return a.data('weight') - b.data('weight') }
        depthSort?: (a: NodeSingular, b: NodeSingular) => number;
    }

    /**
     * http://js.cytoscape.org/#layouts/cose
     */
    interface CoseLayoutOptions extends ShapedLayoutOptions {
        name: "cose";

        // Number of iterations between consecutive screen positions update
        // (0 -> only updated on the end)
        refresh?: number;
        // Randomize the initial positions of the nodes (true) or use existing positions (false)
        randomize?: boolean;
        // Extra spacing between components in non-compound graphs
        componentSpacing?: number;
        // Node repulsion (non overlapping) multiplier
        nodeRepulsion?: Css.PropertyValueNode<number>;

        // Node repulsion (overlapping) multiplier
        nodeOverlap?: number;
        // Ideal edge (non nested) length
        idealEdgeLength?: Css.PropertyValueEdge<number>;
        // Divisor to compute edge forces
        edgeElasticity?: Css.PropertyValueEdge<number>;

        // Nesting factor (multiplier) to compute ideal edge length for nested edges
        nestingFactor?: number;
        // Gravity force (constant)
        gravity?: number;
        // Maximum number of iterations to perform
        numIter?: number;
        // Initial temperature (maximum node displacement)
        initialTemp?: number;
        // Cooling factor (how the temperature is reduced between consecutive iterations
        coolingFactor?: number;
        // Lower temperature threshold (below this point the layout will end)
        minTemp?: number;
        // Deprecated: Pass a reference to weaver to use threads for calculations
        weaver?: boolean;

        // The layout animates only after this many milliseconds for animate:true
        // (prevents flashing on fast runs)
        animationThreshold?: number;
    }

    /**
     * http://js.cytoscape.org/#layouts/layout-manipulation
     * Layouts have a set of functions available to them,
     * which allow for more complex behaviour than the primary run-one-layout-at-a-time usecase.
     * A new, developer accessible layout can be made via cy.makeLayout().
     */
    interface LayoutManipulation {
        /**
         * Start running the layout
         * http://js.cytoscape.org/#layout.run
         */
        run(): this;
        start(): this;
        /**
         * Stop running the (asynchronous/discrete) layout
         * http://js.cytoscape.org/#layout.stop
         */
        stop(): this;
    }
    interface LayoutEvents {
        /**
         * http://js.cytoscape.org/#layouts/layout-events
         */
        /**
         * @param events A space separated list of event names.
         * @param data [optional] A plain object which is passed to the
         * handler in the event object argument.
         * @param handler  The handler function that is called
         * when one of the specified events occurs.
         */
        on(events: EventNames, handler: EventHandler): this;
        on(events: EventNames, data: any, handler: EventHandler): this;
        bind(events: EventNames, handler: EventHandler): this;
        bind(events: EventNames, data: any, handler: EventHandler): this;
        listen(events: EventNames, handler: EventHandler): this;
        listen(events: EventNames, data: any, handler: EventHandler): this;
        addListener(events: EventNames, handler: EventHandler): this;
        addListener(events: EventNames, data: any, handler: EventHandler): this;

        /**
         * Get a promise that is resolved with the first of any of
         * the specified events triggered on the layout.
         * http://js.cytoscape.org/#layout.promiseOn
         */
        promiseOn(events: EventNames): Promise<EventObject>;
        pon(events: EventNames): Promise<EventObject>;

        /**
         * Bind to events that are emitted by the layout, and trigger the handler only once.
         * @param events A space separated list of event names.
         * @param data [optional] A plain object which is passed to the handler in the event object argument.
         * @param handler The handler function that is called when one of the specified events occurs.
         */
        one(events: EventNames, handler: EventHandler): this;
        one(events: EventNames, data: any, handler: EventHandler): this;

        /**
         * Remove event handlers on the layout.
         * http://js.cytoscape.org/#layout.off
         *
         * @param events A space separated list of event names.
         * @param handler [optional] A reference to the handler function to remove.
         */
        off(events: EventNames, handler?: EventHandler): this;
        unbind(events: EventNames, handler?: EventHandler): this;
        unlisten(events: EventNames, handler?: EventHandler): this;
        removeListener(events: EventNames, handler?: EventHandler): this;

        /**
         * Remove all event handlers on the layout.
         * https://js.cytoscape.org/#layout.removeAllListeners
         */
        removeAllListeners(): this;

        /**
         * Trigger one or more events on the layout.
         * http://js.cytoscape.org/#layout.trigger
         * @param events A space separated list of event names to trigger.
         * @param extraParams [optional] An array of additional parameters to pass to the handler.
         */
        trigger(events: EventNames, extraParams?: any[]): this;
    }

    /**
     * An animation represents a visible change in state over
     * a duration of time for a single element.
     * Animations can be generated via cy.animation()
     * (for animations on the viewport) and ele.animation()
     * (for animations on graph elements).
     * http://js.cytoscape.org/#animations
     */

    /**
     * http://js.cytoscape.org/#animations/animation-manipulation
     */
    interface AnimationManipulation {
        /**
         * Requests that the animation be played, starting on the next frame.
         * If the animation is complete, it restarts from the beginning.
         * http://js.cytoscape.org/#ani.play
         */
        play(): this;
        /**
         * Requests that the animation be played, starting on the next frame.
         * If the animation is complete, it restarts from the beginning.
         * http://js.cytoscape.org/#ani.play
         */
        run(): this;
        /**
         * Get whether the animation is currently playing.
         * http://js.cytoscape.org/#ani.playing
         */
        playing(): boolean;
        /**
         * Get whether the animation is currently playing.
         * http://js.cytoscape.org/#ani.playing
         */
        running(): boolean;
        /**
         * Get or set how far along the animation has progressed.
         * http://js.cytoscape.org/#ani.progress
         */
        /**
         * Get the progress of the animation in percent.
         */
        progress(): number;
        /**
         * Set the progress of the animation in percent.
         * @param progress The progress in percent (i.e. between 0 and 1 inclusive) to set to the animation.
         */
        progress(progress: number): AnimationManipulation;
        /**
         * Get the progress of the animation in milliseconds.
         */
        time(): number;
        /**
         * Set the progress of the animation in milliseconds.
         * @param time The progress in milliseconds
         * (i.e. between 0 and the duration inclusive) to set to the animation.
         */
        time(time: number): AnimationManipulation;
        /**
         * Rewind the animation to the beginning.
         */
        rewind(): AnimationManipulation;
        /**
         * Fastforward the animation to the end.
         */
        fastforward(): AnimationManipulation;

        /**
         * Pause the animation, maintaining the current progress.
         * http://js.cytoscape.org/#ani.pause
         */
        pause(): AnimationManipulation;
        /**
         * Stop the animation, maintaining the current progress
         * and removing the animation from any associated queues.
         * http://js.cytoscape.org/#ani.stop
         */
        stop(): AnimationManipulation;
        /**
         * Get whether the animation has progressed to the end.
         * http://js.cytoscape.org/#ani.completed
         */
        completed(): AnimationManipulation;
        complete(): AnimationManipulation;
        /**
         * Apply the animation at its current progress.
         * http://js.cytoscape.org/#ani.apply
         */
        apply(): AnimationManipulation;
        /**
         * Get whether the animation is currently applying.
         * http://js.cytoscape.org/#ani.applying
         */
        applying(): AnimationManipulation;
        /**
         * Reverse the animation such that its starting
         * conditions and ending conditions are reversed.
         * http://js.cytoscape.org/#ani.reverse
         */
        reverse(): AnimationManipulation;
        /**
         * Get a promise that is fulfilled with the specified animation event.
         * @param animationEvent A string for the event name; completed or complete for
         * completing the animation or frame for the next frame of the animation.
         * http://js.cytoscape.org/#ani.promise
         */
        promise(animationEvent?: "completed" | "complete" | "frame"): Promise<EventObject>;
    }

    /**
     * Cytoscape extension type
     * Definition of an extension would be in following form:
     * @example
     * declare module 'cytoscape-ext' {
     *  const ext: cytoscape.Ext;
     *  export = ext;
     * }
     */
    type Ext = (cy: typeof cytoscape) => void;
    /**
     * Register imported extension into cytoscape
     * @param module Entry point for the extension, got by module = require('cy-ext')
     * or by import module from 'cy-ext'
     * http://js.cytoscape.org/#extensions
     */
    function use(module: Ext): void;
    /**
     * Surpress Cytoscape internal warnings globally with a flag.
     * @param condition If true, all Cytoscape warnings are surpressed.
     * https://js.cytoscape.org/#core/initialisation
     */
    function warnings(condition: boolean): void;
}
