
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.echarts = {}));
}(this, (function (exports) { 'use strict';

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose with or without fee is hereby granted.

    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    PERFORMANCE OF THIS SOFTWARE.
    ***************************************************************************** */
    /* global Reflect, Promise */

    var extendStatics = function(d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };

    function __extends(d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }

    var Browser = (function () {
        function Browser() {
            this.firefox = false;
            this.ie = false;
            this.edge = false;
            this.newEdge = false;
            this.weChat = false;
        }
        return Browser;
    }());
    var Env = (function () {
        function Env() {
            this.browser = new Browser();
            this.node = false;
            this.wxa = false;
            this.worker = false;
            this.svgSupported = false;
            this.touchEventsSupported = false;
            this.pointerEventsSupported = false;
            this.domSupported = false;
            this.transformSupported = false;
            this.transform3dSupported = false;
            this.hasGlobalWindow = typeof window !== 'undefined';
        }
        return Env;
    }());
    var env = new Env();
    if (typeof wx === 'object' && typeof wx.getSystemInfoSync === 'function') {
        env.wxa = true;
        env.touchEventsSupported = true;
    }
    else if (typeof document === 'undefined' && typeof self !== 'undefined') {
        env.worker = true;
    }
    else if (typeof navigator === 'undefined') {
        env.node = true;
        env.svgSupported = true;
    }
    else {
        detect(navigator.userAgent, env);
    }
    function detect(ua, env) {
        var browser = env.browser;
        var firefox = ua.match(/Firefox\/([\d.]+)/);
        var ie = ua.match(/MSIE\s([\d.]+)/)
            || ua.match(/Trident\/.+?rv:(([\d.]+))/);
        var edge = ua.match(/Edge?\/([\d.]+)/);
        var weChat = (/micromessenger/i).test(ua);
        if (firefox) {
            browser.firefox = true;
            browser.version = firefox[1];
        }
        if (ie) {
            browser.ie = true;
            browser.version = ie[1];
        }
        if (edge) {
            browser.edge = true;
            browser.version = edge[1];
            browser.newEdge = +edge[1].split('.')[0] > 18;
        }
        if (weChat) {
            browser.weChat = true;
        }
        env.svgSupported = typeof SVGRect !== 'undefined';
        env.touchEventsSupported = 'ontouchstart' in window && !browser.ie && !browser.edge;
        env.pointerEventsSupported = 'onpointerdown' in window
            && (browser.edge || (browser.ie && +browser.version >= 11));
        env.domSupported = typeof document !== 'undefined';
        var style = document.documentElement.style;
        env.transform3dSupported = ((browser.ie && 'transition' in style)
            || browser.edge
            || (('WebKitCSSMatrix' in window) && ('m11' in new WebKitCSSMatrix()))
            || 'MozPerspective' in style)
            && !('OTransition' in style);
        env.transformSupported = env.transform3dSupported
            || (browser.ie && +browser.version >= 9);
    }

    var DEFAULT_FONT_SIZE = 12;
    var DEFAULT_FONT_FAMILY = 'sans-serif';
    var DEFAULT_FONT = DEFAULT_FONT_SIZE + "px " + DEFAULT_FONT_FAMILY;
    var OFFSET = 20;
    var SCALE = 100;
    var defaultWidthMapStr = "007LLmW'55;N0500LLLLLLLLLL00NNNLzWW\\\\WQb\\0FWLg\\bWb\\WQ\\WrWWQ000CL5LLFLL0LL**F*gLLLL5F0LF\\FFF5.5N";
    function getTextWidthMap(mapStr) {
        var map = {};
        if (typeof JSON === 'undefined') {
            return map;
        }
        for (var i = 0; i < mapStr.length; i++) {
            var char = String.fromCharCode(i + 32);
            var size = (mapStr.charCodeAt(i) - OFFSET) / SCALE;
            map[char] = size;
        }
        return map;
    }
    var DEFAULT_TEXT_WIDTH_MAP = getTextWidthMap(defaultWidthMapStr);
    var platformApi = {
        createCanvas: function () {
            return typeof document !== 'undefined'
                && document.createElement('canvas');
        },
        measureText: (function () {
            var _ctx;
            var _cachedFont;
            return function (text, font) {
                if (!_ctx) {
                    var canvas = platformApi.createCanvas();
                    _ctx = canvas && canvas.getContext('2d');
                }
                if (_ctx) {
                    if (_cachedFont !== font) {
                        _cachedFont = _ctx.font = font || DEFAULT_FONT;
                    }
                    return _ctx.measureText(text);
                }
                else {
                    text = text || '';
                    font = font || DEFAULT_FONT;
                    var res = /^([0-9]*?)px$/.exec(font);
                    var fontSize = +(res && res[1]) || DEFAULT_FONT_SIZE;
                    var width = 0;
                    if (font.indexOf('mono') >= 0) {
                        width = fontSize * text.length;
                    }
                    else {
                        for (var i = 0; i < text.length; i++) {
                            var preCalcWidth = DEFAULT_TEXT_WIDTH_MAP[text[i]];
                            width += preCalcWidth == null ? fontSize : (preCalcWidth * fontSize);
                        }
                    }
                    return { width: width };
                }
            };
        })(),
        loadImage: function (src, onload, onerror) {
            var image = new Image();
            image.onload = onload;
            image.onerror = onerror;
            image.src = src;
            return image;
        }
    };
    function setPlatformAPI(newPlatformApis) {
        for (var key in platformApi) {
            if (newPlatformApis[key]) {
                platformApi[key] = newPlatformApis[key];
            }
        }
    }

    var BUILTIN_OBJECT = reduce([
        'Function',
        'RegExp',
        'Date',
        'Error',
        'CanvasGradient',
        'CanvasPattern',
        'Image',
        'Canvas'
    ], function (obj, val) {
        obj['[object ' + val + ']'] = true;
        return obj;
    }, {});
    var TYPED_ARRAY = reduce([
        'Int8',
        'Uint8',
        'Uint8Clamped',
        'Int16',
        'Uint16',
        'Int32',
        'Uint32',
        'Float32',
        'Float64'
    ], function (obj, val) {
        obj['[object ' + val + 'Array]'] = true;
        return obj;
    }, {});
    var objToString = Object.prototype.toString;
    var arrayProto = Array.prototype;
    var nativeForEach = arrayProto.forEach;
    var nativeFilter = arrayProto.filter;
    var nativeSlice = arrayProto.slice;
    var nativeMap = arrayProto.map;
    var ctorFunction = function () { }.constructor;
    var protoFunction = ctorFunction ? ctorFunction.prototype : null;
    var protoKey = '__proto__';
    var idStart = 0x0907;
    function guid() {
        return idStart++;
    }
    function logError() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        if (typeof console !== 'undefined') {
            console.error.apply(console, args);
        }
    }
    function clone(source) {
        if (source == null || typeof source !== 'object') {
            return source;
        }
        var result = source;
        var typeStr = objToString.call(source);
        if (typeStr === '[object Array]') {
            if (!isPrimitive(source)) {
                result = [];
                for (var i = 0, len = source.length; i < len; i++) {
                    result[i] = clone(source[i]);
                }
            }
        }
        else if (TYPED_ARRAY[typeStr]) {
            if (!isPrimitive(source)) {
                var Ctor = source.constructor;
                if (Ctor.from) {
                    result = Ctor.from(source);
                }
                else {
                    result = new Ctor(source.length);
                    for (var i = 0, len = source.length; i < len; i++) {
                        result[i] = source[i];
                    }
                }
            }
        }
        else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) {
            result = {};
            for (var key in source) {
                if (source.hasOwnProperty(key) && key !== protoKey) {
                    result[key] = clone(source[key]);
                }
            }
        }
        return result;
    }
    function merge(target, source, overwrite) {
        if (!isObject(source) || !isObject(target)) {
            return overwrite ? clone(source) : target;
        }
        for (var key in source) {
            if (source.hasOwnProperty(key) && key !== protoKey) {
                var targetProp = target[key];
                var sourceProp = source[key];
                if (isObject(sourceProp)
                    && isObject(targetProp)
                    && !isArray(sourceProp)
                    && !isArray(targetProp)
                    && !isDom(sourceProp)
                    && !isDom(targetProp)
                    && !isBuiltInObject(sourceProp)
                    && !isBuiltInObject(targetProp)
                    && !isPrimitive(sourceProp)
                    && !isPrimitive(targetProp)) {
                    merge(targetProp, sourceProp, overwrite);
                }
                else if (overwrite || !(key in target)) {
                    target[key] = clone(source[key]);
                }
            }
        }
        return target;
    }
    function mergeAll(targetAndSources, overwrite) {
        var result = targetAndSources[0];
        for (var i = 1, len = targetAndSources.length; i < len; i++) {
            result = merge(result, targetAndSources[i], overwrite);
        }
        return result;
    }
    function extend(target, source) {
        if (Object.assign) {
            Object.assign(target, source);
        }
        else {
            for (var key in source) {
                if (source.hasOwnProperty(key) && key !== protoKey) {
                    target[key] = source[key];
                }
            }
        }
        return target;
    }
    function defaults(target, source, overlay) {
        var keysArr = keys(source);
        for (var i = 0; i < keysArr.length; i++) {
            var key = keysArr[i];
            if ((overlay ? source[key] != null : target[key] == null)) {
                target[key] = source[key];
            }
        }
        return target;
    }
    var createCanvas = platformApi.createCanvas;
    function indexOf(array, value) {
        if (array) {
            if (array.indexOf) {
                return array.indexOf(value);
            }
            for (var i = 0, len = array.length; i < len; i++) {
                if (array[i] === value) {
                    return i;
                }
            }
        }
        return -1;
    }
    function inherits(clazz, baseClazz) {
        var clazzPrototype = clazz.prototype;
        function F() { }
        F.prototype = baseClazz.prototype;
        clazz.prototype = new F();
        for (var prop in clazzPrototype) {
            if (clazzPrototype.hasOwnProperty(prop)) {
                clazz.prototype[prop] = clazzPrototype[prop];
            }
        }
        clazz.prototype.constructor = clazz;
        clazz.superClass = baseClazz;
    }
    function mixin(target, source, override) {
        target = 'prototype' in target ? target.prototype : target;
        source = 'prototype' in source ? source.prototype : source;
        if (Object.getOwnPropertyNames) {
            var keyList = Object.getOwnPropertyNames(source);
            for (var i = 0; i < keyList.length; i++) {
                var key = keyList[i];
                if (key !== 'constructor') {
                    if ((override ? source[key] != null : target[key] == null)) {
                        target[key] = source[key];
                    }
                }
            }
        }
        else {
            defaults(target, source, override);
        }
    }
    function isArrayLike(data) {
        if (!data) {
            return false;
        }
        if (typeof data === 'string') {
            return false;
        }
        return typeof data.length === 'number';
    }
    function each(arr, cb, context) {
        if (!(arr && cb)) {
            return;
        }
        if (arr.forEach && arr.forEach === nativeForEach) {
            arr.forEach(cb, context);
        }
        else if (arr.length === +arr.length) {
            for (var i = 0, len = arr.length; i < len; i++) {
                cb.call(context, arr[i], i, arr);
            }
        }
        else {
            for (var key in arr) {
                if (arr.hasOwnProperty(key)) {
                    cb.call(context, arr[key], key, arr);
                }
            }
        }
    }
    function map(arr, cb, context) {
        if (!arr) {
            return [];
        }
        if (!cb) {
            return slice(arr);
        }
        if (arr.map && arr.map === nativeMap) {
            return arr.map(cb, context);
        }
        else {
            var result = [];
            for (var i = 0, len = arr.length; i < len; i++) {
                result.push(cb.call(context, arr[i], i, arr));
            }
            return result;
        }
    }
    function reduce(arr, cb, memo, context) {
        if (!(arr && cb)) {
            return;
        }
        for (var i = 0, len = arr.length; i < len; i++) {
            memo = cb.call(context, memo, arr[i], i, arr);
        }
        return memo;
    }
    function filter(arr, cb, context) {
        if (!arr) {
            return [];
        }
        if (!cb) {
            return slice(arr);
        }
        if (arr.filter && arr.filter === nativeFilter) {
            return arr.filter(cb, context);
        }
        else {
            var result = [];
            for (var i = 0, len = arr.length; i < len; i++) {
                if (cb.call(context, arr[i], i, arr)) {
                    result.push(arr[i]);
                }
            }
            return result;
        }
    }
    function find(arr, cb, context) {
        if (!(arr && cb)) {
            return;
        }
        for (var i = 0, len = arr.length; i < len; i++) {
            if (cb.call(context, arr[i], i, arr)) {
                return arr[i];
            }
        }
    }
    function keys(obj) {
        if (!obj) {
            return [];
        }
        if (Object.keys) {
            return Object.keys(obj);
        }
        var keyList = [];
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                keyList.push(key);
            }
        }
        return keyList;
    }
    function bindPolyfill(func, context) {
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        return function () {
            return func.apply(context, args.concat(nativeSlice.call(arguments)));
        };
    }
    var bind = (protoFunction && isFunction(protoFunction.bind))
        ? protoFunction.call.bind(protoFunction.bind)
        : bindPolyfill;
    function curry(func) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        return function () {
            return func.apply(this, args.concat(nativeSlice.call(arguments)));
        };
    }
    function isArray(value) {
        if (Array.isArray) {
            return Array.isArray(value);
        }
        return objToString.call(value) === '[object Array]';
    }
    function isFunction(value) {
        return typeof value === 'function';
    }
    function isString(value) {
        return typeof value === 'string';
    }
    function isStringSafe(value) {
        return objToString.call(value) === '[object String]';
    }
    function isNumber(value) {
        return typeof value === 'number';
    }
    function isObject(value) {
        var type = typeof value;
        return type === 'function' || (!!value && type === 'object');
    }
    function isBuiltInObject(value) {
        return !!BUILTIN_OBJECT[objToString.call(value)];
    }
    function isTypedArray(value) {
        return !!TYPED_ARRAY[objToString.call(value)];
    }
    function isDom(value) {
        return typeof value === 'object'
            && typeof value.nodeType === 'number'
            && typeof value.ownerDocument === 'object';
    }
    function isGradientObject(value) {
        return value.colorStops != null;
    }
    function isImagePatternObject(value) {
        return value.image != null;
    }
    function isRegExp(value) {
        return objToString.call(value) === '[object RegExp]';
    }
    function eqNaN(value) {
        return value !== value;
    }
    function retrieve() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        for (var i = 0, len = args.length; i < len; i++) {
            if (args[i] != null) {
                return args[i];
            }
        }
    }
    function retrieve2(value0, value1) {
        return value0 != null
            ? value0
            : value1;
    }
    function retrieve3(value0, value1, value2) {
        return value0 != null
            ? value0
            : value1 != null
                ? value1
                : value2;
    }
    function slice(arr) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        return nativeSlice.apply(arr, args);
    }
    function normalizeCssArray(val) {
        if (typeof (val) === 'number') {
            return [val, val, val, val];
        }
        var len = val.length;
        if (len === 2) {
            return [val[0], val[1], val[0], val[1]];
        }
        else if (len === 3) {
            return [val[0], val[1], val[2], val[1]];
        }
        return val;
    }
    function assert(condition, message) {
        if (!condition) {
            throw new Error(message);
        }
    }
    function trim(str) {
        if (str == null) {
            return null;
        }
        else if (typeof str.trim === 'function') {
            return str.trim();
        }
        else {
            return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
        }
    }
    var primitiveKey = '__ec_primitive__';
    function setAsPrimitive(obj) {
        obj[primitiveKey] = true;
    }
    function isPrimitive(obj) {
        return obj[primitiveKey];
    }
    var MapPolyfill = (function () {
        function MapPolyfill() {
            this.data = {};
        }
        MapPolyfill.prototype["delete"] = function (key) {
            var existed = this.has(key);
            if (existed) {
                delete this.data[key];
            }
            return existed;
        };
        MapPolyfill.prototype.has = function (key) {
            return this.data.hasOwnProperty(key);
        };
        MapPolyfill.prototype.get = function (key) {
            return this.data[key];
        };
        MapPolyfill.prototype.set = function (key, value) {
            this.data[key] = value;
            return this;
        };
        MapPolyfill.prototype.keys = function () {
            return keys(this.data);
        };
        MapPolyfill.prototype.forEach = function (callback) {
            var data = this.data;
            for (var key in data) {
                if (data.hasOwnProperty(key)) {
                    callback(data[key], key);
                }
            }
        };
        return MapPolyfill;
    }());
    var isNativeMapSupported = typeof Map === 'function';
    function maybeNativeMap() {
        return (isNativeMapSupported ? new Map() : new MapPolyfill());
    }
    var HashMap = (function () {
        function HashMap(obj) {
            var isArr = isArray(obj);
            this.data = maybeNativeMap();
            var thisMap = this;
            (obj instanceof HashMap)
                ? obj.each(visit)
                : (obj && each(obj, visit));
            function visit(value, key) {
                isArr ? thisMap.set(value, key) : thisMap.set(key, value);
            }
        }
        HashMap.prototype.hasKey = function (key) {
            return this.data.has(key);
        };
        HashMap.prototype.get = function (key) {
            return this.data.get(key);
        };
        HashMap.prototype.set = function (key, value) {
            this.data.set(key, value);
            return value;
        };
        HashMap.prototype.each = function (cb, context) {
            this.data.forEach(function (value, key) {
                cb.call(context, value, key);
            });
        };
        HashMap.prototype.keys = function () {
            var keys = this.data.keys();
            return isNativeMapSupported
                ? Array.from(keys)
                : keys;
        };
        HashMap.prototype.removeKey = function (key) {
            this.data["delete"](key);
        };
        return HashMap;
    }());
    function createHashMap(obj) {
        return new HashMap(obj);
    }
    function concatArray(a, b) {
        var newArray = new a.constructor(a.length + b.length);
        for (var i = 0; i < a.length; i++) {
            newArray[i] = a[i];
        }
        var offset = a.length;
        for (var i = 0; i < b.length; i++) {
            newArray[i + offset] = b[i];
        }
        return newArray;
    }
    function createObject(proto, properties) {
        var obj;
        if (Object.create) {
            obj = Object.create(proto);
        }
        else {
            var StyleCtor = function () { };
            StyleCtor.prototype = proto;
            obj = new StyleCtor();
        }
        if (properties) {
            extend(obj, properties);
        }
        return obj;
    }
    function disableUserSelect(dom) {
        var domStyle = dom.style;
        domStyle.webkitUserSelect = 'none';
        domStyle.userSelect = 'none';
        domStyle.webkitTapHighlightColor = 'rgba(0,0,0,0)';
        domStyle['-webkit-touch-callout'] = 'none';
    }
    function hasOwn(own, prop) {
        return own.hasOwnProperty(prop);
    }
    function noop() { }
    var RADIAN_TO_DEGREE = 180 / Math.PI;

    var util = /*#__PURE__*/Object.freeze({
        __proto__: null,
        guid: guid,
        logError: logError,
        clone: clone,
        merge: merge,
        mergeAll: mergeAll,
        extend: extend,
        defaults: defaults,
        createCanvas: createCanvas,
        indexOf: indexOf,
        inherits: inherits,
        mixin: mixin,
        isArrayLike: isArrayLike,
        each: each,
        map: map,
        reduce: reduce,
        filter: filter,
        find: find,
        keys: keys,
        bind: bind,
        curry: curry,
        isArray: isArray,
        isFunction: isFunction,
        isString: isString,
        isStringSafe: isStringSafe,
        isNumber: isNumber,
        isObject: isObject,
        isBuiltInObject: isBuiltInObject,
        isTypedArray: isTypedArray,
        isDom: isDom,
        isGradientObject: isGradientObject,
        isImagePatternObject: isImagePatternObject,
        isRegExp: isRegExp,
        eqNaN: eqNaN,
        retrieve: retrieve,
        retrieve2: retrieve2,
        retrieve3: retrieve3,
        slice: slice,
        normalizeCssArray: normalizeCssArray,
        assert: assert,
        trim: trim,
        setAsPrimitive: setAsPrimitive,
        isPrimitive: isPrimitive,
        HashMap: HashMap,
        createHashMap: createHashMap,
        concatArray: concatArray,
        createObject: createObject,
        disableUserSelect: disableUserSelect,
        hasOwn: hasOwn,
        noop: noop,
        RADIAN_TO_DEGREE: RADIAN_TO_DEGREE
    });

    function create(x, y) {
        if (x == null) {
            x = 0;
        }
        if (y == null) {
            y = 0;
        }
        return [x, y];
    }
    function copy(out, v) {
        out[0] = v[0];
        out[1] = v[1];
        return out;
    }
    function clone$1(v) {
        return [v[0], v[1]];
    }
    function set(out, a, b) {
        out[0] = a;
        out[1] = b;
        return out;
    }
    function add(out, v1, v2) {
        out[0] = v1[0] + v2[0];
        out[1] = v1[1] + v2[1];
        return out;
    }
    function scaleAndAdd(out, v1, v2, a) {
        out[0] = v1[0] + v2[0] * a;
        out[1] = v1[1] + v2[1] * a;
        return out;
    }
    function sub(out, v1, v2) {
        out[0] = v1[0] - v2[0];
        out[1] = v1[1] - v2[1];
        return out;
    }
    function len(v) {
        return Math.sqrt(lenSquare(v));
    }
    var length = len;
    function lenSquare(v) {
        return v[0] * v[0] + v[1] * v[1];
    }
    var lengthSquare = lenSquare;
    function mul(out, v1, v2) {
        out[0] = v1[0] * v2[0];
        out[1] = v1[1] * v2[1];
        return out;
    }
    function div(out, v1, v2) {
        out[0] = v1[0] / v2[0];
        out[1] = v1[1] / v2[1];
        return out;
    }
    function dot(v1, v2) {
        return v1[0] * v2[0] + v1[1] * v2[1];
    }
    function scale(out, v, s) {
        out[0] = v[0] * s;
        out[1] = v[1] * s;
        return out;
    }
    function normalize(out, v) {
        var d = len(v);
        if (d === 0) {
            out[0] = 0;
            out[1] = 0;
        }
        else {
            out[0] = v[0] / d;
            out[1] = v[1] / d;
        }
        return out;
    }
    function distance(v1, v2) {
        return Math.sqrt((v1[0] - v2[0]) * (v1[0] - v2[0])
            + (v1[1] - v2[1]) * (v1[1] - v2[1]));
    }
    var dist = distance;
    function distanceSquare(v1, v2) {
        return (v1[0] - v2[0]) * (v1[0] - v2[0])
            + (v1[1] - v2[1]) * (v1[1] - v2[1]);
    }
    var distSquare = distanceSquare;
    function negate(out, v) {
        out[0] = -v[0];
        out[1] = -v[1];
        return out;
    }
    function lerp(out, v1, v2, t) {
        out[0] = v1[0] + t * (v2[0] - v1[0]);
        out[1] = v1[1] + t * (v2[1] - v1[1]);
        return out;
    }
    function applyTransform(out, v, m) {
        var x = v[0];
        var y = v[1];
        out[0] = m[0] * x + m[2] * y + m[4];
        out[1] = m[1] * x + m[3] * y + m[5];
        return out;
    }
    function min(out, v1, v2) {
        out[0] = Math.min(v1[0], v2[0]);
        out[1] = Math.min(v1[1], v2[1]);
        return out;
    }
    function max(out, v1, v2) {
        out[0] = Math.max(v1[0], v2[0]);
        out[1] = Math.max(v1[1], v2[1]);
        return out;
    }

    var vector = /*#__PURE__*/Object.freeze({
        __proto__: null,
        create: create,
        copy: copy,
        clone: clone$1,
        set: set,
        add: add,
        scaleAndAdd: scaleAndAdd,
        sub: sub,
        len: len,
        length: length,
        lenSquare: lenSquare,
        lengthSquare: lengthSquare,
        mul: mul,
        div: div,
        dot: dot,
        scale: scale,
        normalize: normalize,
        distance: distance,
        dist: dist,
        distanceSquare: distanceSquare,
        distSquare: distSquare,
        negate: negate,
        lerp: lerp,
        applyTransform: applyTransform,
        min: min,
        max: max
    });

    var Param = (function () {
        function Param(target, e) {
            this.target = target;
            this.topTarget = e && e.topTarget;
        }
        return Param;
    }());
    var Draggable = (function () {
        function Draggable(handler) {
            this.handler = handler;
            handler.on('mousedown', this._dragStart, this);
            handler.on('mousemove', this._drag, this);
            handler.on('mouseup', this._dragEnd, this);
        }
        Draggable.prototype._dragStart = function (e) {
            var draggingTarget = e.target;
            while (draggingTarget && !draggingTarget.draggable) {
                draggingTarget = draggingTarget.parent || draggingTarget.__hostTarget;
            }
            if (draggingTarget) {
                this._draggingTarget = draggingTarget;
                draggingTarget.dragging = true;
                this._x = e.offsetX;
                this._y = e.offsetY;
                this.handler.dispatchToElement(new Param(draggingTarget, e), 'dragstart', e.event);
            }
        };
        Draggable.prototype._drag = function (e) {
            var draggingTarget = this._draggingTarget;
            if (draggingTarget) {
                var x = e.offsetX;
                var y = e.offsetY;
                var dx = x - this._x;
                var dy = y - this._y;
                this._x = x;
                this._y = y;
                draggingTarget.drift(dx, dy, e);
                this.handler.dispatchToElement(new Param(draggingTarget, e), 'drag', e.event);
                var dropTarget = this.handler.findHover(x, y, draggingTarget).target;
                var lastDropTarget = this._dropTarget;
                this._dropTarget = dropTarget;
                if (draggingTarget !== dropTarget) {
                    if (lastDropTarget && dropTarget !== lastDropTarget) {
                        this.handler.dispatchToElement(new Param(lastDropTarget, e), 'dragleave', e.event);
                    }
                    if (dropTarget && dropTarget !== lastDropTarget) {
                        this.handler.dispatchToElement(new Param(dropTarget, e), 'dragenter', e.event);
                    }
                }
            }
        };
        Draggable.prototype._dragEnd = function (e) {
            var draggingTarget = this._draggingTarget;
            if (draggingTarget) {
                draggingTarget.dragging = false;
            }
            this.handler.dispatchToElement(new Param(draggingTarget, e), 'dragend', e.event);
            if (this._dropTarget) {
                this.handler.dispatchToElement(new Param(this._dropTarget, e), 'drop', e.event);
            }
            this._draggingTarget = null;
            this._dropTarget = null;
        };
        return Draggable;
    }());

    var Eventful = (function () {
        function Eventful(eventProcessors) {
            if (eventProcessors) {
                this._$eventProcessor = eventProcessors;
            }
        }
        Eventful.prototype.on = function (event, query, handler, context) {
            if (!this._$handlers) {
                this._$handlers = {};
            }
            var _h = this._$handlers;
            if (typeof query === 'function') {
                context = handler;
                handler = query;
                query = null;
            }
            if (!handler || !event) {
                return this;
            }
            var eventProcessor = this._$eventProcessor;
            if (query != null && eventProcessor && eventProcessor.normalizeQuery) {
                query = eventProcessor.normalizeQuery(query);
            }
            if (!_h[event]) {
                _h[event] = [];
            }
            for (var i = 0; i < _h[event].length; i++) {
                if (_h[event][i].h === handler) {
                    return this;
                }
            }
            var wrap = {
                h: handler,
                query: query,
                ctx: (context || this),
                callAtLast: handler.zrEventfulCallAtLast
            };
            var lastIndex = _h[event].length - 1;
            var lastWrap = _h[event][lastIndex];
            (lastWrap && lastWrap.callAtLast)
                ? _h[event].splice(lastIndex, 0, wrap)
                : _h[event].push(wrap);
            return this;
        };
        Eventful.prototype.isSilent = function (eventName) {
            var _h = this._$handlers;
            return !_h || !_h[eventName] || !_h[eventName].length;
        };
        Eventful.prototype.off = function (eventType, handler) {
            var _h = this._$handlers;
            if (!_h) {
                return this;
            }
            if (!eventType) {
                this._$handlers = {};
                return this;
            }
            if (handler) {
                if (_h[eventType]) {
                    var newList = [];
                    for (var i = 0, l = _h[eventType].length; i < l; i++) {
                        if (_h[eventType][i].h !== handler) {
                            newList.push(_h[eventType][i]);
                        }
                    }
                    _h[eventType] = newList;
                }
                if (_h[eventType] && _h[eventType].length === 0) {
                    delete _h[eventType];
                }
            }
            else {
                delete _h[eventType];
            }
            return this;
        };
        Eventful.prototype.trigger = function (eventType) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            if (!this._$handlers) {
                return this;
            }
            var _h = this._$handlers[eventType];
            var eventProcessor = this._$eventProcessor;
            if (_h) {
                var argLen = args.length;
                var len = _h.length;
                for (var i = 0; i < len; i++) {
                    var hItem = _h[i];
                    if (eventProcessor
                        && eventProcessor.filter
                        && hItem.query != null
                        && !eventProcessor.filter(eventType, hItem.query)) {
                        continue;
                    }
                    switch (argLen) {
                        case 0:
                            hItem.h.call(hItem.ctx);
                            break;
                        case 1:
                            hItem.h.call(hItem.ctx, args[0]);
                            break;
                        case 2:
                            hItem.h.call(hItem.ctx, args[0], args[1]);
                            break;
                        default:
                            hItem.h.apply(hItem.ctx, args);
                            break;
                    }
                }
            }
            eventProcessor && eventProcessor.afterTrigger
                && eventProcessor.afterTrigger(eventType);
            return this;
        };
        Eventful.prototype.triggerWithContext = function (type) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            if (!this._$handlers) {
                return this;
            }
            var _h = this._$handlers[type];
            var eventProcessor = this._$eventProcessor;
            if (_h) {
                var argLen = args.length;
                var ctx = args[argLen - 1];
                var len = _h.length;
                for (var i = 0; i < len; i++) {
                    var hItem = _h[i];
                    if (eventProcessor
                        && eventProcessor.filter
                        && hItem.query != null
                        && !eventProcessor.filter(type, hItem.query)) {
                        continue;
                    }
                    switch (argLen) {
                        case 0:
                            hItem.h.call(ctx);
                            break;
                        case 1:
                            hItem.h.call(ctx, args[0]);
                            break;
                        case 2:
                            hItem.h.call(ctx, args[0], args[1]);
                            break;
                        default:
                            hItem.h.apply(ctx, args.slice(1, argLen - 1));
                            break;
                    }
                }
            }
            eventProcessor && eventProcessor.afterTrigger
                && eventProcessor.afterTrigger(type);
            return this;
        };
        return Eventful;
    }());

    var LN2 = Math.log(2);
    function determinant(rows, rank, rowStart, rowMask, colMask, detCache) {
        var cacheKey = rowMask + '-' + colMask;
        var fullRank = rows.length;
        if (detCache.hasOwnProperty(cacheKey)) {
            return detCache[cacheKey];
        }
        if (rank === 1) {
            var colStart = Math.round(Math.log(((1 << fullRank) - 1) & ~colMask) / LN2);
            return rows[rowStart][colStart];
        }
        var subRowMask = rowMask | (1 << rowStart);
        var subRowStart = rowStart + 1;
        while (rowMask & (1 << subRowStart)) {
            subRowStart++;
        }
        var sum = 0;
        for (var j = 0, colLocalIdx = 0; j < fullRank; j++) {
            var colTag = 1 << j;
            if (!(colTag & colMask)) {
                sum += (colLocalIdx % 2 ? -1 : 1) * rows[rowStart][j]
                    * determinant(rows, rank - 1, subRowStart, subRowMask, colMask | colTag, detCache);
                colLocalIdx++;
            }
        }
        detCache[cacheKey] = sum;
        return sum;
    }
    function buildTransformer(src, dest) {
        var mA = [
            [src[0], src[1], 1, 0, 0, 0, -dest[0] * src[0], -dest[0] * src[1]],
            [0, 0, 0, src[0], src[1], 1, -dest[1] * src[0], -dest[1] * src[1]],
            [src[2], src[3], 1, 0, 0, 0, -dest[2] * src[2], -dest[2] * src[3]],
            [0, 0, 0, src[2], src[3], 1, -dest[3] * src[2], -dest[3] * src[3]],
            [src[4], src[5], 1, 0, 0, 0, -dest[4] * src[4], -dest[4] * src[5]],
            [0, 0, 0, src[4], src[5], 1, -dest[5] * src[4], -dest[5] * src[5]],
            [src[6], src[7], 1, 0, 0, 0, -dest[6] * src[6], -dest[6] * src[7]],
            [0, 0, 0, src[6], src[7], 1, -dest[7] * src[6], -dest[7] * src[7]]
        ];
        var detCache = {};
        var det = determinant(mA, 8, 0, 0, 0, detCache);
        if (det === 0) {
            return;
        }
        var vh = [];
        for (var i = 0; i < 8; i++) {
            for (var j = 0; j < 8; j++) {
                vh[j] == null && (vh[j] = 0);
                vh[j] += ((i + j) % 2 ? -1 : 1)
                    * determinant(mA, 7, i === 0 ? 1 : 0, 1 << i, 1 << j, detCache)
                    / det * dest[i];
            }
        }
        return function (out, srcPointX, srcPointY) {
            var pk = srcPointX * vh[6] + srcPointY * vh[7] + 1;
            out[0] = (srcPointX * vh[0] + srcPointY * vh[1] + vh[2]) / pk;
            out[1] = (srcPointX * vh[3] + srcPointY * vh[4] + vh[5]) / pk;
        };
    }

    var EVENT_SAVED_PROP = '___zrEVENTSAVED';
    var _calcOut = [];
    function transformLocalCoord(out, elFrom, elTarget, inX, inY) {
        return transformCoordWithViewport(_calcOut, elFrom, inX, inY, true)
            && transformCoordWithViewport(out, elTarget, _calcOut[0], _calcOut[1]);
    }
    function transformCoordWithViewport(out, el, inX, inY, inverse) {
        if (el.getBoundingClientRect && env.domSupported && !isCanvasEl(el)) {
            var saved = el[EVENT_SAVED_PROP] || (el[EVENT_SAVED_PROP] = {});
            var markers = prepareCoordMarkers(el, saved);
            var transformer = preparePointerTransformer(markers, saved, inverse);
            if (transformer) {
                transformer(out, inX, inY);
                return true;
            }
        }
        return false;
    }
    function prepareCoordMarkers(el, saved) {
        var markers = saved.markers;
        if (markers) {
            return markers;
        }
        markers = saved.markers = [];
        var propLR = ['left', 'right'];
        var propTB = ['top', 'bottom'];
        for (var i = 0; i < 4; i++) {
            var marker = document.createElement('div');
            var stl = marker.style;
            var idxLR = i % 2;
            var idxTB = (i >> 1) % 2;
            stl.cssText = [
                'position: absolute',
                'visibility: hidden',
                'padding: 0',
                'margin: 0',
                'border-width: 0',
                'user-select: none',
                'width:0',
                'height:0',
                propLR[idxLR] + ':0',
                propTB[idxTB] + ':0',
                propLR[1 - idxLR] + ':auto',
                propTB[1 - idxTB] + ':auto',
                ''
            ].join('!important;');
            el.appendChild(marker);
            markers.push(marker);
        }
        return markers;
    }
    function preparePointerTransformer(markers, saved, inverse) {
        var transformerName = inverse ? 'invTrans' : 'trans';
        var transformer = saved[transformerName];
        var oldSrcCoords = saved.srcCoords;
        var srcCoords = [];
        var destCoords = [];
        var oldCoordTheSame = true;
        for (var i = 0; i < 4; i++) {
            var rect = markers[i].getBoundingClientRect();
            var ii = 2 * i;
            var x = rect.left;
            var y = rect.top;
            srcCoords.push(x, y);
            oldCoordTheSame = oldCoordTheSame && oldSrcCoords && x === oldSrcCoords[ii] && y === oldSrcCoords[ii + 1];
            destCoords.push(markers[i].offsetLeft, markers[i].offsetTop);
        }
        return (oldCoordTheSame && transformer)
            ? transformer
            : (saved.srcCoords = srcCoords,
                saved[transformerName] = inverse
                    ? buildTransformer(destCoords, srcCoords)
                    : buildTransformer(srcCoords, destCoords));
    }
    function isCanvasEl(el) {
        return el.nodeName.toUpperCase() === 'CANVAS';
    }
    var replaceReg = /([&<>"'])/g;
    var replaceMap = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        '\'': '&#39;'
    };
    function encodeHTML(source) {
        return source == null
            ? ''
            : (source + '').replace(replaceReg, function (str, c) {
                return replaceMap[c];
            });
    }

    var MOUSE_EVENT_REG = /^(?:mouse|pointer|contextmenu|drag|drop)|click/;
    var _calcOut$1 = [];
    var firefoxNotSupportOffsetXY = env.browser.firefox
        && +env.browser.version.split('.')[0] < 39;
    function clientToLocal(el, e, out, calculate) {
        out = out || {};
        if (calculate) {
            calculateZrXY(el, e, out);
        }
        else if (firefoxNotSupportOffsetXY
            && e.layerX != null
            && e.layerX !== e.offsetX) {
            out.zrX = e.layerX;
            out.zrY = e.layerY;
        }
        else if (e.offsetX != null) {
            out.zrX = e.offsetX;
            out.zrY = e.offsetY;
        }
        else {
            calculateZrXY(el, e, out);
        }
        return out;
    }
    function calculateZrXY(el, e, out) {
        if (env.domSupported && el.getBoundingClientRect) {
            var ex = e.clientX;
            var ey = e.clientY;
            if (isCanvasEl(el)) {
                var box = el.getBoundingClientRect();
                out.zrX = ex - box.left;
                out.zrY = ey - box.top;
                return;
            }
            else {
                if (transformCoordWithViewport(_calcOut$1, el, ex, ey)) {
                    out.zrX = _calcOut$1[0];
                    out.zrY = _calcOut$1[1];
                    return;
                }
            }
        }
        out.zrX = out.zrY = 0;
    }
    function getNativeEvent(e) {
        return e
            || window.event;
    }
    function normalizeEvent(el, e, calculate) {
        e = getNativeEvent(e);
        if (e.zrX != null) {
            return e;
        }
        var eventType = e.type;
        var isTouch = eventType && eventType.indexOf('touch') >= 0;
        if (!isTouch) {
            clientToLocal(el, e, e, calculate);
            var wheelDelta = getWheelDeltaMayPolyfill(e);
            e.zrDelta = wheelDelta ? wheelDelta / 120 : -(e.detail || 0) / 3;
        }
        else {
            var touch = eventType !== 'touchend'
                ? e.targetTouches[0]
                : e.changedTouches[0];
            touch && clientToLocal(el, touch, e, calculate);
        }
        var button = e.button;
        if (e.which == null && button !== undefined && MOUSE_EVENT_REG.test(e.type)) {
            e.which = (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0)));
        }
        return e;
    }
    function getWheelDeltaMayPolyfill(e) {
        var rawWheelDelta = e.wheelDelta;
        if (rawWheelDelta) {
            return rawWheelDelta;
        }
        var deltaX = e.deltaX;
        var deltaY = e.deltaY;
        if (deltaX == null || deltaY == null) {
            return rawWheelDelta;
        }
        var delta = deltaY !== 0 ? Math.abs(deltaY) : Math.abs(deltaX);
        var sign = deltaY > 0 ? -1
            : deltaY < 0 ? 1
                : deltaX > 0 ? -1
                    : 1;
        return 3 * delta * sign;
    }
    function addEventListener(el, name, handler, opt) {
        el.addEventListener(name, handler, opt);
    }
    function removeEventListener(el, name, handler, opt) {
        el.removeEventListener(name, handler, opt);
    }
    var stop = function (e) {
        e.preventDefault();
        e.stopPropagation();
        e.cancelBubble = true;
    };
    function isMiddleOrRightButtonOnMouseUpDown(e) {
        return e.which === 2 || e.which === 3;
    }

    var GestureMgr = (function () {
        function GestureMgr() {
            this._track = [];
        }
        GestureMgr.prototype.recognize = function (event, target, root) {
            this._doTrack(event, target, root);
            return this._recognize(event);
        };
        GestureMgr.prototype.clear = function () {
            this._track.length = 0;
            return this;
        };
        GestureMgr.prototype._doTrack = function (event, target, root) {
            var touches = event.touches;
            if (!touches) {
                return;
            }
            var trackItem = {
                points: [],
                touches: [],
                target: target,
                event: event
            };
            for (var i = 0, len = touches.length; i < len; i++) {
                var touch = touches[i];
                var pos = clientToLocal(root, touch, {});
                trackItem.points.push([pos.zrX, pos.zrY]);
                trackItem.touches.push(touch);
            }
            this._track.push(trackItem);
        };
        GestureMgr.prototype._recognize = function (event) {
            for (var eventName in recognizers) {
                if (recognizers.hasOwnProperty(eventName)) {
                    var gestureInfo = recognizers[eventName](this._track, event);
                    if (gestureInfo) {
                        return gestureInfo;
                    }
                }
            }
        };
        return GestureMgr;
    }());
    function dist$1(pointPair) {
        var dx = pointPair[1][0] - pointPair[0][0];
        var dy = pointPair[1][1] - pointPair[0][1];
        return Math.sqrt(dx * dx + dy * dy);
    }
    function center(pointPair) {
        return [
            (pointPair[0][0] + pointPair[1][0]) / 2,
            (pointPair[0][1] + pointPair[1][1]) / 2
        ];
    }
    var recognizers = {
        pinch: function (tracks, event) {
            var trackLen = tracks.length;
            if (!trackLen) {
                return;
            }
            var pinchEnd = (tracks[trackLen - 1] || {}).points;
            var pinchPre = (tracks[trackLen - 2] || {}).points || pinchEnd;
            if (pinchPre
                && pinchPre.length > 1
                && pinchEnd
                && pinchEnd.length > 1) {
                var pinchScale = dist$1(pinchEnd) / dist$1(pinchPre);
                !isFinite(pinchScale) && (pinchScale = 1);
                event.pinchScale = pinchScale;
                var pinchCenter = center(pinchEnd);
                event.pinchX = pinchCenter[0];
                event.pinchY = pinchCenter[1];
                return {
                    type: 'pinch',
                    target: tracks[0].target,
                    event: event
                };
            }
        }
    };

    function create$1() {
        return [1, 0, 0, 1, 0, 0];
    }
    function identity(out) {
        out[0] = 1;
        out[1] = 0;
        out[2] = 0;
        out[3] = 1;
        out[4] = 0;
        out[5] = 0;
        return out;
    }
    function copy$1(out, m) {
        out[0] = m[0];
        out[1] = m[1];
        out[2] = m[2];
        out[3] = m[3];
        out[4] = m[4];
        out[5] = m[5];
        return out;
    }
    function mul$1(out, m1, m2) {
        var out0 = m1[0] * m2[0] + m1[2] * m2[1];
        var out1 = m1[1] * m2[0] + m1[3] * m2[1];
        var out2 = m1[0] * m2[2] + m1[2] * m2[3];
        var out3 = m1[1] * m2[2] + m1[3] * m2[3];
        var out4 = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];
        var out5 = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];
        out[0] = out0;
        out[1] = out1;
        out[2] = out2;
        out[3] = out3;
        out[4] = out4;
        out[5] = out5;
        return out;
    }
    function translate(out, a, v) {
        out[0] = a[0];
        out[1] = a[1];
        out[2] = a[2];
        out[3] = a[3];
        out[4] = a[4] + v[0];
        out[5] = a[5] + v[1];
        return out;
    }
    function rotate(out, a, rad) {
        var aa = a[0];
        var ac = a[2];
        var atx = a[4];
        var ab = a[1];
        var ad = a[3];
        var aty = a[5];
        var st = Math.sin(rad);
        var ct = Math.cos(rad);
        out[0] = aa * ct + ab * st;
        out[1] = -aa * st + ab * ct;
        out[2] = ac * ct + ad * st;
        out[3] = -ac * st + ct * ad;
        out[4] = ct * atx + st * aty;
        out[5] = ct * aty - st * atx;
        return out;
    }
    function scale$1(out, a, v) {
        var vx = v[0];
        var vy = v[1];
        out[0] = a[0] * vx;
        out[1] = a[1] * vy;
        out[2] = a[2] * vx;
        out[3] = a[3] * vy;
        out[4] = a[4] * vx;
        out[5] = a[5] * vy;
        return out;
    }
    function invert(out, a) {
        var aa = a[0];
        var ac = a[2];
        var atx = a[4];
        var ab = a[1];
        var ad = a[3];
        var aty = a[5];
        var det = aa * ad - ab * ac;
        if (!det) {
            return null;
        }
        det = 1.0 / det;
        out[0] = ad * det;
        out[1] = -ab * det;
        out[2] = -ac * det;
        out[3] = aa * det;
        out[4] = (ac * aty - ad * atx) * det;
        out[5] = (ab * atx - aa * aty) * det;
        return out;
    }
    function clone$2(a) {
        var b = create$1();
        copy$1(b, a);
        return b;
    }

    var matrix = /*#__PURE__*/Object.freeze({
        __proto__: null,
        create: create$1,
        identity: identity,
        copy: copy$1,
        mul: mul$1,
        translate: translate,
        rotate: rotate,
        scale: scale$1,
        invert: invert,
        clone: clone$2
    });

    var Point = (function () {
        function Point(x, y) {
            this.x = x || 0;
            this.y = y || 0;
        }
        Point.prototype.copy = function (other) {
            this.x = other.x;
            this.y = other.y;
            return this;
        };
        Point.prototype.clone = function () {
            return new Point(this.x, this.y);
        };
        Point.prototype.set = function (x, y) {
            this.x = x;
            this.y = y;
            return this;
        };
        Point.prototype.equal = function (other) {
            return other.x === this.x && other.y === this.y;
        };
        Point.prototype.add = function (other) {
            this.x += other.x;
            this.y += other.y;
            return this;
        };
        Point.prototype.scale = function (scalar) {
            this.x *= scalar;
            this.y *= scalar;
        };
        Point.prototype.scaleAndAdd = function (other, scalar) {
            this.x += other.x * scalar;
            this.y += other.y * scalar;
        };
        Point.prototype.sub = function (other) {
            this.x -= other.x;
            this.y -= other.y;
            return this;
        };
        Point.prototype.dot = function (other) {
            return this.x * other.x + this.y * other.y;
        };
        Point.prototype.len = function () {
            return Math.sqrt(this.x * this.x + this.y * this.y);
        };
        Point.prototype.lenSquare = function () {
            return this.x * this.x + this.y * this.y;
        };
        Point.prototype.normalize = function () {
            var len = this.len();
            this.x /= len;
            this.y /= len;
            return this;
        };
        Point.prototype.distance = function (other) {
            var dx = this.x - other.x;
            var dy = this.y - other.y;
            return Math.sqrt(dx * dx + dy * dy);
        };
        Point.prototype.distanceSquare = function (other) {
            var dx = this.x - other.x;
            var dy = this.y - other.y;
            return dx * dx + dy * dy;
        };
        Point.prototype.negate = function () {
            this.x = -this.x;
            this.y = -this.y;
            return this;
        };
        Point.prototype.transform = function (m) {
            if (!m) {
                return;
            }
            var x = this.x;
            var y = this.y;
            this.x = m[0] * x + m[2] * y + m[4];
            this.y = m[1] * x + m[3] * y + m[5];
            return this;
        };
        Point.prototype.toArray = function (out) {
            out[0] = this.x;
            out[1] = this.y;
            return out;
        };
        Point.prototype.fromArray = function (input) {
            this.x = input[0];
            this.y = input[1];
        };
        Point.set = function (p, x, y) {
            p.x = x;
            p.y = y;
        };
        Point.copy = function (p, p2) {
            p.x = p2.x;
            p.y = p2.y;
        };
        Point.len = function (p) {
            return Math.sqrt(p.x * p.x + p.y * p.y);
        };
        Point.lenSquare = function (p) {
            return p.x * p.x + p.y * p.y;
        };
        Point.dot = function (p0, p1) {
            return p0.x * p1.x + p0.y * p1.y;
        };
        Point.add = function (out, p0, p1) {
            out.x = p0.x + p1.x;
            out.y = p0.y + p1.y;
        };
        Point.sub = function (out, p0, p1) {
            out.x = p0.x - p1.x;
            out.y = p0.y - p1.y;
        };
        Point.scale = function (out, p0, scalar) {
            out.x = p0.x * scalar;
            out.y = p0.y * scalar;
        };
        Point.scaleAndAdd = function (out, p0, p1, scalar) {
            out.x = p0.x + p1.x * scalar;
            out.y = p0.y + p1.y * scalar;
        };
        Point.lerp = function (out, p0, p1, t) {
            var onet = 1 - t;
            out.x = onet * p0.x + t * p1.x;
            out.y = onet * p0.y + t * p1.y;
        };
        return Point;
    }());

    var mathMin = Math.min;
    var mathMax = Math.max;
    var lt = new Point();
    var rb = new Point();
    var lb = new Point();
    var rt = new Point();
    var minTv = new Point();
    var maxTv = new Point();
    var BoundingRect = (function () {
        function BoundingRect(x, y, width, height) {
            if (width < 0) {
                x = x + width;
                width = -width;
            }
            if (height < 0) {
                y = y + height;
                height = -height;
            }
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }
        BoundingRect.prototype.union = function (other) {
            var x = mathMin(other.x, this.x);
            var y = mathMin(other.y, this.y);
            if (isFinite(this.x) && isFinite(this.width)) {
                this.width = mathMax(other.x + other.width, this.x + this.width) - x;
            }
            else {
                this.width = other.width;
            }
            if (isFinite(this.y) && isFinite(this.height)) {
                this.height = mathMax(other.y + other.height, this.y + this.height) - y;
            }
            else {
                this.height = other.height;
            }
            this.x = x;
            this.y = y;
        };
        BoundingRect.prototype.applyTransform = function (m) {
            BoundingRect.applyTransform(this, this, m);
        };
        BoundingRect.prototype.calculateTransform = function (b) {
            var a = this;
            var sx = b.width / a.width;
            var sy = b.height / a.height;
            var m = create$1();
            translate(m, m, [-a.x, -a.y]);
            scale$1(m, m, [sx, sy]);
            translate(m, m, [b.x, b.y]);
            return m;
        };
        BoundingRect.prototype.intersect = function (b, mtv) {
            if (!b) {
                return false;
            }
            if (!(b instanceof BoundingRect)) {
                b = BoundingRect.create(b);
            }
            var a = this;
            var ax0 = a.x;
            var ax1 = a.x + a.width;
            var ay0 = a.y;
            var ay1 = a.y + a.height;
            var bx0 = b.x;
            var bx1 = b.x + b.width;
            var by0 = b.y;
            var by1 = b.y + b.height;
            var overlap = !(ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0);
            if (mtv) {
                var dMin = Infinity;
                var dMax = 0;
                var d0 = Math.abs(ax1 - bx0);
                var d1 = Math.abs(bx1 - ax0);
                var d2 = Math.abs(ay1 - by0);
                var d3 = Math.abs(by1 - ay0);
                var dx = Math.min(d0, d1);
                var dy = Math.min(d2, d3);
                if (ax1 < bx0 || bx1 < ax0) {
                    if (dx > dMax) {
                        dMax = dx;
                        if (d0 < d1) {
                            Point.set(maxTv, -d0, 0);
                        }
                        else {
                            Point.set(maxTv, d1, 0);
                        }
                    }
                }
                else {
                    if (dx < dMin) {
                        dMin = dx;
                        if (d0 < d1) {
                            Point.set(minTv, d0, 0);
                        }
                        else {
                            Point.set(minTv, -d1, 0);
                        }
                    }
                }
                if (ay1 < by0 || by1 < ay0) {
                    if (dy > dMax) {
                        dMax = dy;
                        if (d2 < d3) {
                            Point.set(maxTv, 0, -d2);
                        }
                        else {
                            Point.set(maxTv, 0, d3);
                        }
                    }
                }
                else {
                    if (dx < dMin) {
                        dMin = dx;
                        if (d2 < d3) {
                            Point.set(minTv, 0, d2);
                        }
                        else {
                            Point.set(minTv, 0, -d3);
                        }
                    }
                }
            }
            if (mtv) {
                Point.copy(mtv, overlap ? minTv : maxTv);
            }
            return overlap;
        };
        BoundingRect.prototype.contain = function (x, y) {
            var rect = this;
            return x >= rect.x
                && x <= (rect.x + rect.width)
                && y >= rect.y
                && y <= (rect.y + rect.height);
        };
        BoundingRect.prototype.clone = function () {
            return new BoundingRect(this.x, this.y, this.width, this.height);
        };
        BoundingRect.prototype.copy = function (other) {
            BoundingRect.copy(this, other);
        };
        BoundingRect.prototype.plain = function () {
            return {
                x: this.x,
                y: this.y,
                width: this.width,
                height: this.height
            };
        };
        BoundingRect.prototype.isFinite = function () {
            return isFinite(this.x)
                && isFinite(this.y)
                && isFinite(this.width)
                && isFinite(this.height);
        };
        BoundingRect.prototype.isZero = function () {
            return this.width === 0 || this.height === 0;
        };
        BoundingRect.create = function (rect) {
            return new BoundingRect(rect.x, rect.y, rect.width, rect.height);
        };
        BoundingRect.copy = function (target, source) {
            target.x = source.x;
            target.y = source.y;
            target.width = source.width;
            target.height = source.height;
        };
        BoundingRect.applyTransform = function (target, source, m) {
            if (!m) {
                if (target !== source) {
                    BoundingRect.copy(target, source);
                }
                return;
            }
            if (m[1] < 1e-5 && m[1] > -1e-5 && m[2] < 1e-5 && m[2] > -1e-5) {
                var sx = m[0];
                var sy = m[3];
                var tx = m[4];
                var ty = m[5];
                target.x = source.x * sx + tx;
                target.y = source.y * sy + ty;
                target.width = source.width * sx;
                target.height = source.height * sy;
                if (target.width < 0) {
                    target.x += target.width;
                    target.width = -target.width;
                }
                if (target.height < 0) {
                    target.y += target.height;
                    target.height = -target.height;
                }
                return;
            }
            lt.x = lb.x = source.x;
            lt.y = rt.y = source.y;
            rb.x = rt.x = source.x + source.width;
            rb.y = lb.y = source.y + source.height;
            lt.transform(m);
            rt.transform(m);
            rb.transform(m);
            lb.transform(m);
            target.x = mathMin(lt.x, rb.x, lb.x, rt.x);
            target.y = mathMin(lt.y, rb.y, lb.y, rt.y);
            var maxX = mathMax(lt.x, rb.x, lb.x, rt.x);
            var maxY = mathMax(lt.y, rb.y, lb.y, rt.y);
            target.width = maxX - target.x;
            target.height = maxY - target.y;
        };
        return BoundingRect;
    }());

    var SILENT = 'silent';
    function makeEventPacket(eveType, targetInfo, event) {
        return {
            type: eveType,
            event: event,
            target: targetInfo.target,
            topTarget: targetInfo.topTarget,
            cancelBubble: false,
            offsetX: event.zrX,
            offsetY: event.zrY,
            gestureEvent: event.gestureEvent,
            pinchX: event.pinchX,
            pinchY: event.pinchY,
            pinchScale: event.pinchScale,
            wheelDelta: event.zrDelta,
            zrByTouch: event.zrByTouch,
            which: event.which,
            stop: stopEvent
        };
    }
    function stopEvent() {
        stop(this.event);
    }
    var EmptyProxy = (function (_super) {
        __extends(EmptyProxy, _super);
        function EmptyProxy() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.handler = null;
            return _this;
        }
        EmptyProxy.prototype.dispose = function () { };
        EmptyProxy.prototype.setCursor = function () { };
        return EmptyProxy;
    }(Eventful));
    var HoveredResult = (function () {
        function HoveredResult(x, y) {
            this.x = x;
            this.y = y;
        }
        return HoveredResult;
    }());
    var handlerNames = [
        'click', 'dblclick', 'mousewheel', 'mouseout',
        'mouseup', 'mousedown', 'mousemove', 'contextmenu'
    ];
    var tmpRect = new BoundingRect(0, 0, 0, 0);
    var Handler = (function (_super) {
        __extends(Handler, _super);
        function Handler(storage, painter, proxy, painterRoot, pointerSize) {
            var _this = _super.call(this) || this;
            _this._hovered = new HoveredResult(0, 0);
            _this.storage = storage;
            _this.painter = painter;
            _this.painterRoot = painterRoot;
            _this._pointerSize = pointerSize;
            proxy = proxy || new EmptyProxy();
            _this.proxy = null;
            _this.setHandlerProxy(proxy);
            _this._draggingMgr = new Draggable(_this);
            return _this;
        }
        Handler.prototype.setHandlerProxy = function (proxy) {
            if (this.proxy) {
                this.proxy.dispose();
            }
            if (proxy) {
                each(handlerNames, function (name) {
                    proxy.on && proxy.on(name, this[name], this);
                }, this);
                proxy.handler = this;
            }
            this.proxy = proxy;
        };
        Handler.prototype.mousemove = function (event) {
            var x = event.zrX;
            var y = event.zrY;
            var isOutside = isOutsideBoundary(this, x, y);
            var lastHovered = this._hovered;
            var lastHoveredTarget = lastHovered.target;
            if (lastHoveredTarget && !lastHoveredTarget.__zr) {
                lastHovered = this.findHover(lastHovered.x, lastHovered.y);
                lastHoveredTarget = lastHovered.target;
            }
            var hovered = this._hovered = isOutside ? new HoveredResult(x, y) : this.findHover(x, y);
            var hoveredTarget = hovered.target;
            var proxy = this.proxy;
            proxy.setCursor && proxy.setCursor(hoveredTarget ? hoveredTarget.cursor : 'default');
            if (lastHoveredTarget && hoveredTarget !== lastHoveredTarget) {
                this.dispatchToElement(lastHovered, 'mouseout', event);
            }
            this.dispatchToElement(hovered, 'mousemove', event);
            if (hoveredTarget && hoveredTarget !== lastHoveredTarget) {
                this.dispatchToElement(hovered, 'mouseover', event);
            }
        };
        Handler.prototype.mouseout = function (event) {
            var eventControl = event.zrEventControl;
            if (eventControl !== 'only_globalout') {
                this.dispatchToElement(this._hovered, 'mouseout', event);
            }
            if (eventControl !== 'no_globalout') {
                this.trigger('globalout', { type: 'globalout', event: event });
            }
        };
        Handler.prototype.resize = function () {
            this._hovered = new HoveredResult(0, 0);
        };
        Handler.prototype.dispatch = function (eventName, eventArgs) {
            var handler = this[eventName];
            handler && handler.call(this, eventArgs);
        };
        Handler.prototype.dispose = function () {
            this.proxy.dispose();
            this.storage = null;
            this.proxy = null;
            this.painter = null;
        };
        Handler.prototype.setCursorStyle = function (cursorStyle) {
            var proxy = this.proxy;
            proxy.setCursor && proxy.setCursor(cursorStyle);
        };
        Handler.prototype.dispatchToElement = function (targetInfo, eventName, event) {
            targetInfo = targetInfo || {};
            var el = targetInfo.target;
            if (el && el.silent) {
                return;
            }
            var eventKey = ('on' + eventName);
            var eventPacket = makeEventPacket(eventName, targetInfo, event);
            while (el) {
                el[eventKey]
                    && (eventPacket.cancelBubble = !!el[eventKey].call(el, eventPacket));
                el.trigger(eventName, eventPacket);
                el = el.__hostTarget ? el.__hostTarget : el.parent;
                if (eventPacket.cancelBubble) {
                    break;
                }
            }
            if (!eventPacket.cancelBubble) {
                this.trigger(eventName, eventPacket);
                if (this.painter && this.painter.eachOtherLayer) {
                    this.painter.eachOtherLayer(function (layer) {
                        if (typeof (layer[eventKey]) === 'function') {
                            layer[eventKey].call(layer, eventPacket);
                        }
                        if (layer.trigger) {
                            layer.trigger(eventName, eventPacket);
                        }
                    });
                }
            }
        };
        Handler.prototype.findHover = function (x, y, exclude) {
            var list = this.storage.getDisplayList();
            var out = new HoveredResult(x, y);
            setHoverTarget(list, out, x, y, exclude);
            if (this._pointerSize && !out.target) {
                var candidates = [];
                var pointerSize = this._pointerSize;
                var targetSizeHalf = pointerSize / 2;
                var pointerRect = new BoundingRect(x - targetSizeHalf, y - targetSizeHalf, pointerSize, pointerSize);
                for (var i = list.length - 1; i >= 0; i--) {
                    var el = list[i];
                    if (el !== exclude
                        && !el.ignore
                        && !el.ignoreCoarsePointer
                        && (!el.parent || !el.parent.ignoreCoarsePointer)) {
                        tmpRect.copy(el.getBoundingRect());
                        if (el.transform) {
                            tmpRect.applyTransform(el.transform);
                        }
                        if (tmpRect.intersect(pointerRect)) {
                            candidates.push(el);
                        }
                    }
                }
                if (candidates.length) {
                    var rStep = 4;
                    var thetaStep = Math.PI / 12;
                    var PI2 = Math.PI * 2;
                    for (var r = 0; r < targetSizeHalf; r += rStep) {
                        for (var theta = 0; theta < PI2; theta += thetaStep) {
                            var x1 = x + r * Math.cos(theta);
                            var y1 = y + r * Math.sin(theta);
                            setHoverTarget(candidates, out, x1, y1, exclude);
                            if (out.target) {
                                return out;
                            }
                        }
                    }
                }
            }
            return out;
        };
        Handler.prototype.processGesture = function (event, stage) {
            if (!this._gestureMgr) {
                this._gestureMgr = new GestureMgr();
            }
            var gestureMgr = this._gestureMgr;
            stage === 'start' && gestureMgr.clear();
            var gestureInfo = gestureMgr.recognize(event, this.findHover(event.zrX, event.zrY, null).target, this.proxy.dom);
            stage === 'end' && gestureMgr.clear();
            if (gestureInfo) {
                var type = gestureInfo.type;
                event.gestureEvent = type;
                var res = new HoveredResult();
                res.target = gestureInfo.target;
                this.dispatchToElement(res, type, gestureInfo.event);
            }
        };
        return Handler;
    }(Eventful));
    each(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick', 'contextmenu'], function (name) {
        Handler.prototype[name] = function (event) {
            var x = event.zrX;
            var y = event.zrY;
            var isOutside = isOutsideBoundary(this, x, y);
            var hovered;
            var hoveredTarget;
            if (name !== 'mouseup' || !isOutside) {
                hovered = this.findHover(x, y);
                hoveredTarget = hovered.target;
            }
            if (name === 'mousedown') {
                this._downEl = hoveredTarget;
                this._downPoint = [event.zrX, event.zrY];
                this._upEl = hoveredTarget;
            }
            else if (name === 'mouseup') {
                this._upEl = hoveredTarget;
            }
            else if (name === 'click') {
                if (this._downEl !== this._upEl
                    || !this._downPoint
                    || dist(this._downPoint, [event.zrX, event.zrY]) > 4) {
                    return;
                }
                this._downPoint = null;
            }
            this.dispatchToElement(hovered, name, event);
        };
    });
    function isHover(displayable, x, y) {
        if (displayable[displayable.rectHover ? 'rectContain' : 'contain'](x, y)) {
            var el = displayable;
            var isSilent = void 0;
            var ignoreClip = false;
            while (el) {
                if (el.ignoreClip) {
                    ignoreClip = true;
                }
                if (!ignoreClip) {
                    var clipPath = el.getClipPath();
                    if (clipPath && !clipPath.contain(x, y)) {
                        return false;
                    }
                    if (el.silent) {
                        isSilent = true;
                    }
                }
                var hostEl = el.__hostTarget;
                el = hostEl ? hostEl : el.parent;
            }
            return isSilent ? SILENT : true;
        }
        return false;
    }
    function setHoverTarget(list, out, x, y, exclude) {
        for (var i = list.length - 1; i >= 0; i--) {
            var el = list[i];
            var hoverCheckResult = void 0;
            if (el !== exclude
                && !el.ignore
                && (hoverCheckResult = isHover(el, x, y))) {
                !out.topTarget && (out.topTarget = el);
                if (hoverCheckResult !== SILENT) {
                    out.target = el;
                    break;
                }
            }
        }
    }
    function isOutsideBoundary(handlerInstance, x, y) {
        var painter = handlerInstance.painter;
        return x < 0 || x > painter.getWidth() || y < 0 || y > painter.getHeight();
    }

    var DEFAULT_MIN_MERGE = 32;
    var DEFAULT_MIN_GALLOPING = 7;
    function minRunLength(n) {
        var r = 0;
        while (n >= DEFAULT_MIN_MERGE) {
            r |= n & 1;
            n >>= 1;
        }
        return n + r;
    }
    function makeAscendingRun(array, lo, hi, compare) {
        var runHi = lo + 1;
        if (runHi === hi) {
            return 1;
        }
        if (compare(array[runHi++], array[lo]) < 0) {
            while (runHi < hi && compare(array[runHi], array[runHi - 1]) < 0) {
                runHi++;
            }
            reverseRun(array, lo, runHi);
        }
        else {
            while (runHi < hi && compare(array[runHi], array[runHi - 1]) >= 0) {
                runHi++;
            }
        }
        return runHi - lo;
    }
    function reverseRun(array, lo, hi) {
        hi--;
        while (lo < hi) {
            var t = array[lo];
            array[lo++] = array[hi];
            array[hi--] = t;
        }
    }
    function binaryInsertionSort(array, lo, hi, start, compare) {
        if (start === lo) {
            start++;
        }
        for (; start < hi; start++) {
            var pivot = array[start];
            var left = lo;
            var right = start;
            var mid;
            while (left < right) {
                mid = left + right >>> 1;
                if (compare(pivot, array[mid]) < 0) {
                    right = mid;
                }
                else {
                    left = mid + 1;
                }
            }
            var n = start - left;
            switch (n) {
                case 3:
                    array[left + 3] = array[left + 2];
                case 2:
                    array[left + 2] = array[left + 1];
                case 1:
                    array[left + 1] = array[left];
                    break;
                default:
                    while (n > 0) {
                        array[left + n] = array[left + n - 1];
                        n--;
                    }
            }
            array[left] = pivot;
        }
    }
    function gallopLeft(value, array, start, length, hint, compare) {
        var lastOffset = 0;
        var maxOffset = 0;
        var offset = 1;
        if (compare(value, array[start + hint]) > 0) {
            maxOffset = length - hint;
            while (offset < maxOffset && compare(value, array[start + hint + offset]) > 0) {
                lastOffset = offset;
                offset = (offset << 1) + 1;
                if (offset <= 0) {
                    offset = maxOffset;
                }
            }
            if (offset > maxOffset) {
                offset = maxOffset;
            }
            lastOffset += hint;
            offset += hint;
        }
        else {
            maxOffset = hint + 1;
            while (offset < maxOffset && compare(value, array[start + hint - offset]) <= 0) {
                lastOffset = offset;
                offset = (offset << 1) + 1;
                if (offset <= 0) {
                    offset = maxOffset;
                }
            }
            if (offset > maxOffset) {
                offset = maxOffset;
            }
            var tmp = lastOffset;
            lastOffset = hint - offset;
            offset = hint - tmp;
        }
        lastOffset++;
        while (lastOffset < offset) {
            var m = lastOffset + (offset - lastOffset >>> 1);
            if (compare(value, array[start + m]) > 0) {
                lastOffset = m + 1;
            }
            else {
                offset = m;
            }
        }
        return offset;
    }
    function gallopRight(value, array, start, length, hint, compare) {
        var lastOffset = 0;
        var maxOffset = 0;
        var offset = 1;
        if (compare(value, array[start + hint]) < 0) {
            maxOffset = hint + 1;
            while (offset < maxOffset && compare(value, array[start + hint - offset]) < 0) {
                lastOffset = offset;
                offset = (offset << 1) + 1;
                if (offset <= 0) {
                    offset = maxOffset;
                }
            }
            if (offset > maxOffset) {
                offset = maxOffset;
            }
            var tmp = lastOffset;
            lastOffset = hint - offset;
            offset = hint - tmp;
        }
        else {
            maxOffset = length - hint;
            while (offset < maxOffset && compare(value, array[start + hint + offset]) >= 0) {
                lastOffset = offset;
                offset = (offset << 1) + 1;
                if (offset <= 0) {
                    offset = maxOffset;
                }
            }
            if (offset > maxOffset) {
                offset = maxOffset;
            }
            lastOffset += hint;
            offset += hint;
        }
        lastOffset++;
        while (lastOffset < offset) {
            var m = lastOffset + (offset - lastOffset >>> 1);
            if (compare(value, array[start + m]) < 0) {
                offset = m;
            }
            else {
                lastOffset = m + 1;
            }
        }
        return offset;
    }
    function TimSort(array, compare) {
        var minGallop = DEFAULT_MIN_GALLOPING;
        var length = 0;
        var runStart;
        var runLength;
        var stackSize = 0;
        length = array.length;
        var tmp = [];
        runStart = [];
        runLength = [];
        function pushRun(_runStart, _runLength) {
            runStart[stackSize] = _runStart;
            runLength[stackSize] = _runLength;
            stackSize += 1;
        }
        function mergeRuns() {
            while (stackSize > 1) {
                var n = stackSize - 2;
                if ((n >= 1 && runLength[n - 1] <= runLength[n] + runLength[n + 1])
                    || (n >= 2 && runLength[n - 2] <= runLength[n] + runLength[n - 1])) {
                    if (runLength[n - 1] < runLength[n + 1]) {
                        n--;
                    }
                }
                else if (runLength[n] > runLength[n + 1]) {
                    break;
                }
                mergeAt(n);
            }
        }
        function forceMergeRuns() {
            while (stackSize > 1) {
                var n = stackSize - 2;
                if (n > 0 && runLength[n - 1] < runLength[n + 1]) {
                    n--;
                }
                mergeAt(n);
            }
        }
        function mergeAt(i) {
            var start1 = runStart[i];
            var length1 = runLength[i];
            var start2 = runStart[i + 1];
            var length2 = runLength[i + 1];
            runLength[i] = length1 + length2;
            if (i === stackSize - 3) {
                runStart[i + 1] = runStart[i + 2];
                runLength[i + 1] = runLength[i + 2];
            }
            stackSize--;
            var k = gallopRight(array[start2], array, start1, length1, 0, compare);
            start1 += k;
            length1 -= k;
            if (length1 === 0) {
                return;
            }
            length2 = gallopLeft(array[start1 + length1 - 1], array, start2, length2, length2 - 1, compare);
            if (length2 === 0) {
                return;
            }
            if (length1 <= length2) {
                mergeLow(start1, length1, start2, length2);
            }
            else {
                mergeHigh(start1, length1, start2, length2);
            }
        }
        function mergeLow(start1, length1, start2, length2) {
            var i = 0;
            for (i = 0; i < length1; i++) {
                tmp[i] = array[start1 + i];
            }
            var cursor1 = 0;
            var cursor2 = start2;
            var dest = start1;
            array[dest++] = array[cursor2++];
            if (--length2 === 0) {
                for (i = 0; i < length1; i++) {
                    array[dest + i] = tmp[cursor1 + i];
                }
                return;
            }
            if (length1 === 1) {
                for (i = 0; i < length2; i++) {
                    array[dest + i] = array[cursor2 + i];
                }
                array[dest + length2] = tmp[cursor1];
                return;
            }
            var _minGallop = minGallop;
            var count1;
            var count2;
            var exit;
            while (1) {
                count1 = 0;
                count2 = 0;
                exit = false;
                do {
                    if (compare(array[cursor2], tmp[cursor1]) < 0) {
                        array[dest++] = array[cursor2++];
                        count2++;
                        count1 = 0;
                        if (--length2 === 0) {
                            exit = true;
                            break;
                        }
                    }
                    else {
                        array[dest++] = tmp[cursor1++];
                        count1++;
                        count2 = 0;
                        if (--length1 === 1) {
                            exit = true;
                            break;
                        }
                    }
                } while ((count1 | count2) < _minGallop);
                if (exit) {
                    break;
                }
                do {
                    count1 = gallopRight(array[cursor2], tmp, cursor1, length1, 0, compare);
                    if (count1 !== 0) {
                        for (i = 0; i < count1; i++) {
                            array[dest + i] = tmp[cursor1 + i];
                        }
                        dest += count1;
                        cursor1 += count1;
                        length1 -= count1;
                        if (length1 <= 1) {
                            exit = true;
                            break;
                        }
                    }
                    array[dest++] = array[cursor2++];
                    if (--length2 === 0) {
                        exit = true;
                        break;
                    }
                    count2 = gallopLeft(tmp[cursor1], array, cursor2, length2, 0, compare);
                    if (count2 !== 0) {
                        for (i = 0; i < count2; i++) {
                            array[dest + i] = array[cursor2 + i];
                        }
                        dest += count2;
                        cursor2 += count2;
                        length2 -= count2;
                        if (length2 === 0) {
                            exit = true;
                            break;
                        }
                    }
                    array[dest++] = tmp[cursor1++];
                    if (--length1 === 1) {
                        exit = true;
                        break;
                    }
                    _minGallop--;
                } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);
                if (exit) {
                    break;
                }
                if (_minGallop < 0) {
                    _minGallop = 0;
                }
                _minGallop += 2;
            }
            minGallop = _minGallop;
            minGallop < 1 && (minGallop = 1);
            if (length1 === 1) {
                for (i = 0; i < length2; i++) {
                    array[dest + i] = array[cursor2 + i];
                }
                array[dest + length2] = tmp[cursor1];
            }
            else if (length1 === 0) {
                throw new Error();
            }
            else {
                for (i = 0; i < length1; i++) {
                    array[dest + i] = tmp[cursor1 + i];
                }
            }
        }
        function mergeHigh(start1, length1, start2, length2) {
            var i = 0;
            for (i = 0; i < length2; i++) {
                tmp[i] = array[start2 + i];
            }
            var cursor1 = start1 + length1 - 1;
            var cursor2 = length2 - 1;
            var dest = start2 + length2 - 1;
            var customCursor = 0;
            var customDest = 0;
            array[dest--] = array[cursor1--];
            if (--length1 === 0) {
                customCursor = dest - (length2 - 1);
                for (i = 0; i < length2; i++) {
                    array[customCursor + i] = tmp[i];
                }
                return;
            }
            if (length2 === 1) {
                dest -= length1;
                cursor1 -= length1;
                customDest = dest + 1;
                customCursor = cursor1 + 1;
                for (i = length1 - 1; i >= 0; i--) {
                    array[customDest + i] = array[customCursor + i];
                }
                array[dest] = tmp[cursor2];
                return;
            }
            var _minGallop = minGallop;
            while (true) {
                var count1 = 0;
                var count2 = 0;
                var exit = false;
                do {
                    if (compare(tmp[cursor2], array[cursor1]) < 0) {
                        array[dest--] = array[cursor1--];
                        count1++;
                        count2 = 0;
                        if (--length1 === 0) {
                            exit = true;
                            break;
                        }
                    }
                    else {
                        array[dest--] = tmp[cursor2--];
                        count2++;
                        count1 = 0;
                        if (--length2 === 1) {
                            exit = true;
                            break;
                        }
                    }
                } while ((count1 | count2) < _minGallop);
                if (exit) {
                    break;
                }
                do {
                    count1 = length1 - gallopRight(tmp[cursor2], array, start1, length1, length1 - 1, compare);
                    if (count1 !== 0) {
                        dest -= count1;
                        cursor1 -= count1;
                        length1 -= count1;
                        customDest = dest + 1;
                        customCursor = cursor1 + 1;
                        for (i = count1 - 1; i >= 0; i--) {
                            array[customDest + i] = array[customCursor + i];
                        }
                        if (length1 === 0) {
                            exit = true;
                            break;
                        }
                    }
                    array[dest--] = tmp[cursor2--];
                    if (--length2 === 1) {
                        exit = true;
                        break;
                    }
                    count2 = length2 - gallopLeft(array[cursor1], tmp, 0, length2, length2 - 1, compare);
                    if (count2 !== 0) {
                        dest -= count2;
                        cursor2 -= count2;
                        length2 -= count2;
                        customDest = dest + 1;
                        customCursor = cursor2 + 1;
                        for (i = 0; i < count2; i++) {
                            array[customDest + i] = tmp[customCursor + i];
                        }
                        if (length2 <= 1) {
                            exit = true;
                            break;
                        }
                    }
                    array[dest--] = array[cursor1--];
                    if (--length1 === 0) {
                        exit = true;
                        break;
                    }
                    _minGallop--;
                } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);
                if (exit) {
                    break;
                }
                if (_minGallop < 0) {
                    _minGallop = 0;
                }
                _minGallop += 2;
            }
            minGallop = _minGallop;
            if (minGallop < 1) {
                minGallop = 1;
            }
            if (length2 === 1) {
                dest -= length1;
                cursor1 -= length1;
                customDest = dest + 1;
                customCursor = cursor1 + 1;
                for (i = length1 - 1; i >= 0; i--) {
                    array[customDest + i] = array[customCursor + i];
                }
                array[dest] = tmp[cursor2];
            }
            else if (length2 === 0) {
                throw new Error();
            }
            else {
                customCursor = dest - (length2 - 1);
                for (i = 0; i < length2; i++) {
                    array[customCursor + i] = tmp[i];
                }
            }
        }
        return {
            mergeRuns: mergeRuns,
            forceMergeRuns: forceMergeRuns,
            pushRun: pushRun
        };
    }
    function sort(array, compare, lo, hi) {
        if (!lo) {
            lo = 0;
        }
        if (!hi) {
            hi = array.length;
        }
        var remaining = hi - lo;
        if (remaining < 2) {
            return;
        }
        var runLength = 0;
        if (remaining < DEFAULT_MIN_MERGE) {
            runLength = makeAscendingRun(array, lo, hi, compare);
            binaryInsertionSort(array, lo, hi, lo + runLength, compare);
            return;
        }
        var ts = TimSort(array, compare);
        var minRun = minRunLength(remaining);
        do {
            runLength = makeAscendingRun(array, lo, hi, compare);
            if (runLength < minRun) {
                var force = remaining;
                if (force > minRun) {
                    force = minRun;
                }
                binaryInsertionSort(array, lo, lo + force, lo + runLength, compare);
                runLength = force;
            }
            ts.pushRun(lo, runLength);
            ts.mergeRuns();
            remaining -= runLength;
            lo += runLength;
        } while (remaining !== 0);
        ts.forceMergeRuns();
    }

    var REDRAW_BIT = 1;
    var STYLE_CHANGED_BIT = 2;
    var SHAPE_CHANGED_BIT = 4;

    var invalidZErrorLogged = false;
    function logInvalidZError() {
        if (invalidZErrorLogged) {
            return;
        }
        invalidZErrorLogged = true;
        console.warn('z / z2 / zlevel of displayable is invalid, which may cause unexpected errors');
    }
    function shapeCompareFunc(a, b) {
        if (a.zlevel === b.zlevel) {
            if (a.z === b.z) {
                return a.z2 - b.z2;
            }
            return a.z - b.z;
        }
        return a.zlevel - b.zlevel;
    }
    var Storage = (function () {
        function Storage() {
            this._roots = [];
            this._displayList = [];
            this._displayListLen = 0;
            this.displayableSortFunc = shapeCompareFunc;
        }
        Storage.prototype.traverse = function (cb, context) {
            for (var i = 0; i < this._roots.length; i++) {
                this._roots[i].traverse(cb, context);
            }
        };
        Storage.prototype.getDisplayList = function (update, includeIgnore) {
            includeIgnore = includeIgnore || false;
            var displayList = this._displayList;
            if (update || !displayList.length) {
                this.updateDisplayList(includeIgnore);
            }
            return displayList;
        };
        Storage.prototype.updateDisplayList = function (includeIgnore) {
            this._displayListLen = 0;
            var roots = this._roots;
            var displayList = this._displayList;
            for (var i = 0, len = roots.length; i < len; i++) {
                this._updateAndAddDisplayable(roots[i], null, includeIgnore);
            }
            displayList.length = this._displayListLen;
            sort(displayList, shapeCompareFunc);
        };
        Storage.prototype._updateAndAddDisplayable = function (el, clipPaths, includeIgnore) {
            if (el.ignore && !includeIgnore) {
                return;
            }
            el.beforeUpdate();
            el.update();
            el.afterUpdate();
            var userSetClipPath = el.getClipPath();
            if (el.ignoreClip) {
                clipPaths = null;
            }
            else if (userSetClipPath) {
                if (clipPaths) {
                    clipPaths = clipPaths.slice();
                }
                else {
                    clipPaths = [];
                }
                var currentClipPath = userSetClipPath;
                var parentClipPath = el;
                while (currentClipPath) {
                    currentClipPath.parent = parentClipPath;
                    currentClipPath.updateTransform();
                    clipPaths.push(currentClipPath);
                    parentClipPath = currentClipPath;
                    currentClipPath = currentClipPath.getClipPath();
                }
            }
            if (el.childrenRef) {
                var children = el.childrenRef();
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    if (el.__dirty) {
                        child.__dirty |= REDRAW_BIT;
                    }
                    this._updateAndAddDisplayable(child, clipPaths, includeIgnore);
                }
                el.__dirty = 0;
            }
            else {
                var disp = el;
                if (clipPaths && clipPaths.length) {
                    disp.__clipPaths = clipPaths;
                }
                else if (disp.__clipPaths && disp.__clipPaths.length > 0) {
                    disp.__clipPaths = [];
                }
                if (isNaN(disp.z)) {
                    logInvalidZError();
                    disp.z = 0;
                }
                if (isNaN(disp.z2)) {
                    logInvalidZError();
                    disp.z2 = 0;
                }
                if (isNaN(disp.zlevel)) {
                    logInvalidZError();
                    disp.zlevel = 0;
                }
                this._displayList[this._displayListLen++] = disp;
            }
            var decalEl = el.getDecalElement && el.getDecalElement();
            if (decalEl) {
                this._updateAndAddDisplayable(decalEl, clipPaths, includeIgnore);
            }
            var textGuide = el.getTextGuideLine();
            if (textGuide) {
                this._updateAndAddDisplayable(textGuide, clipPaths, includeIgnore);
            }
            var textEl = el.getTextContent();
            if (textEl) {
                this._updateAndAddDisplayable(textEl, clipPaths, includeIgnore);
            }
        };
        Storage.prototype.addRoot = function (el) {
            if (el.__zr && el.__zr.storage === this) {
                return;
            }
            this._roots.push(el);
        };
        Storage.prototype.delRoot = function (el) {
            if (el instanceof Array) {
                for (var i = 0, l = el.length; i < l; i++) {
                    this.delRoot(el[i]);
                }
                return;
            }
            var idx = indexOf(this._roots, el);
            if (idx >= 0) {
                this._roots.splice(idx, 1);
            }
        };
        Storage.prototype.delAllRoots = function () {
            this._roots = [];
            this._displayList = [];
            this._displayListLen = 0;
            return;
        };
        Storage.prototype.getRoots = function () {
            return this._roots;
        };
        Storage.prototype.dispose = function () {
            this._displayList = null;
            this._roots = null;
        };
        return Storage;
    }());

    var requestAnimationFrame;
    requestAnimationFrame = (env.hasGlobalWindow
        && ((window.requestAnimationFrame && window.requestAnimationFrame.bind(window))
            || (window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window))
            || window.mozRequestAnimationFrame
            || window.webkitRequestAnimationFrame)) || function (func) {
        return setTimeout(func, 16);
    };
    var requestAnimationFrame$1 = requestAnimationFrame;

    var easingFuncs = {
        linear: function (k) {
            return k;
        },
        quadraticIn: function (k) {
            return k * k;
        },
        quadraticOut: function (k) {
            return k * (2 - k);
        },
        quadraticInOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k;
            }
            return -0.5 * (--k * (k - 2) - 1);
        },
        cubicIn: function (k) {
            return k * k * k;
        },
        cubicOut: function (k) {
            return --k * k * k + 1;
        },
        cubicInOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k * k;
            }
            return 0.5 * ((k -= 2) * k * k + 2);
        },
        quarticIn: function (k) {
            return k * k * k * k;
        },
        quarticOut: function (k) {
            return 1 - (--k * k * k * k);
        },
        quarticInOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k * k * k;
            }
            return -0.5 * ((k -= 2) * k * k * k - 2);
        },
        quinticIn: function (k) {
            return k * k * k * k * k;
        },
        quinticOut: function (k) {
            return --k * k * k * k * k + 1;
        },
        quinticInOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k * k * k * k;
            }
            return 0.5 * ((k -= 2) * k * k * k * k + 2);
        },
        sinusoidalIn: function (k) {
            return 1 - Math.cos(k * Math.PI / 2);
        },
        sinusoidalOut: function (k) {
            return Math.sin(k * Math.PI / 2);
        },
        sinusoidalInOut: function (k) {
            return 0.5 * (1 - Math.cos(Math.PI * k));
        },
        exponentialIn: function (k) {
            return k === 0 ? 0 : Math.pow(1024, k - 1);
        },
        exponentialOut: function (k) {
            return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
        },
        exponentialInOut: function (k) {
            if (k === 0) {
                return 0;
            }
            if (k === 1) {
                return 1;
            }
            if ((k *= 2) < 1) {
                return 0.5 * Math.pow(1024, k - 1);
            }
            return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);
        },
        circularIn: function (k) {
            return 1 - Math.sqrt(1 - k * k);
        },
        circularOut: function (k) {
            return Math.sqrt(1 - (--k * k));
        },
        circularInOut: function (k) {
            if ((k *= 2) < 1) {
                return -0.5 * (Math.sqrt(1 - k * k) - 1);
            }
            return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
        },
        elasticIn: function (k) {
            var s;
            var a = 0.1;
            var p = 0.4;
            if (k === 0) {
                return 0;
            }
            if (k === 1) {
                return 1;
            }
            if (!a || a < 1) {
                a = 1;
                s = p / 4;
            }
            else {
                s = p * Math.asin(1 / a) / (2 * Math.PI);
            }
            return -(a * Math.pow(2, 10 * (k -= 1))
                * Math.sin((k - s) * (2 * Math.PI) / p));
        },
        elasticOut: function (k) {
            var s;
            var a = 0.1;
            var p = 0.4;
            if (k === 0) {
                return 0;
            }
            if (k === 1) {
                return 1;
            }
            if (!a || a < 1) {
                a = 1;
                s = p / 4;
            }
            else {
                s = p * Math.asin(1 / a) / (2 * Math.PI);
            }
            return (a * Math.pow(2, -10 * k)
                * Math.sin((k - s) * (2 * Math.PI) / p) + 1);
        },
        elasticInOut: function (k) {
            var s;
            var a = 0.1;
            var p = 0.4;
            if (k === 0) {
                return 0;
            }
            if (k === 1) {
                return 1;
            }
            if (!a || a < 1) {
                a = 1;
                s = p / 4;
            }
            else {
                s = p * Math.asin(1 / a) / (2 * Math.PI);
            }
            if ((k *= 2) < 1) {
                return -0.5 * (a * Math.pow(2, 10 * (k -= 1))
                    * Math.sin((k - s) * (2 * Math.PI) / p));
            }
            return a * Math.pow(2, -10 * (k -= 1))
                * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;
        },
        backIn: function (k) {
            var s = 1.70158;
            return k * k * ((s + 1) * k - s);
        },
        backOut: function (k) {
            var s = 1.70158;
            return --k * k * ((s + 1) * k + s) + 1;
        },
        backInOut: function (k) {
            var s = 1.70158 * 1.525;
            if ((k *= 2) < 1) {
                return 0.5 * (k * k * ((s + 1) * k - s));
            }
            return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
        },
        bounceIn: function (k) {
            return 1 - easingFuncs.bounceOut(1 - k);
        },
        bounceOut: function (k) {
            if (k < (1 / 2.75)) {
                return 7.5625 * k * k;
            }
            else if (k < (2 / 2.75)) {
                return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;
            }
            else if (k < (2.5 / 2.75)) {
                return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;
            }
            else {
                return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;
            }
        },
        bounceInOut: function (k) {
            if (k < 0.5) {
                return easingFuncs.bounceIn(k * 2) * 0.5;
            }
            return easingFuncs.bounceOut(k * 2 - 1) * 0.5 + 0.5;
        }
    };

    var mathPow = Math.pow;
    var mathSqrt = Math.sqrt;
    var EPSILON = 1e-8;
    var EPSILON_NUMERIC = 1e-4;
    var THREE_SQRT = mathSqrt(3);
    var ONE_THIRD = 1 / 3;
    var _v0 = create();
    var _v1 = create();
    var _v2 = create();
    function isAroundZero(val) {
        return val > -EPSILON && val < EPSILON;
    }
    function isNotAroundZero(val) {
        return val > EPSILON || val < -EPSILON;
    }
    function cubicAt(p0, p1, p2, p3, t) {
        var onet = 1 - t;
        return onet * onet * (onet * p0 + 3 * t * p1)
            + t * t * (t * p3 + 3 * onet * p2);
    }
    function cubicDerivativeAt(p0, p1, p2, p3, t) {
        var onet = 1 - t;
        return 3 * (((p1 - p0) * onet + 2 * (p2 - p1) * t) * onet
            + (p3 - p2) * t * t);
    }
    function cubicRootAt(p0, p1, p2, p3, val, roots) {
        var a = p3 + 3 * (p1 - p2) - p0;
        var b = 3 * (p2 - p1 * 2 + p0);
        var c = 3 * (p1 - p0);
        var d = p0 - val;
        var A = b * b - 3 * a * c;
        var B = b * c - 9 * a * d;
        var C = c * c - 3 * b * d;
        var n = 0;
        if (isAroundZero(A) && isAroundZero(B)) {
            if (isAroundZero(b)) {
                roots[0] = 0;
            }
            else {
                var t1 = -c / b;
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
        }
        else {
            var disc = B * B - 4 * A * C;
            if (isAroundZero(disc)) {
                var K = B / A;
                var t1 = -b / a + K;
                var t2 = -K / 2;
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
                if (t2 >= 0 && t2 <= 1) {
                    roots[n++] = t2;
                }
            }
            else if (disc > 0) {
                var discSqrt = mathSqrt(disc);
                var Y1 = A * b + 1.5 * a * (-B + discSqrt);
                var Y2 = A * b + 1.5 * a * (-B - discSqrt);
                if (Y1 < 0) {
                    Y1 = -mathPow(-Y1, ONE_THIRD);
                }
                else {
                    Y1 = mathPow(Y1, ONE_THIRD);
                }
                if (Y2 < 0) {
                    Y2 = -mathPow(-Y2, ONE_THIRD);
                }
                else {
                    Y2 = mathPow(Y2, ONE_THIRD);
                }
                var t1 = (-b - (Y1 + Y2)) / (3 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
            else {
                var T = (2 * A * b - 3 * a * B) / (2 * mathSqrt(A * A * A));
                var theta = Math.acos(T) / 3;
                var ASqrt = mathSqrt(A);
                var tmp = Math.cos(theta);
                var t1 = (-b - 2 * ASqrt * tmp) / (3 * a);
                var t2 = (-b + ASqrt * (tmp + THREE_SQRT * Math.sin(theta))) / (3 * a);
                var t3 = (-b + ASqrt * (tmp - THREE_SQRT * Math.sin(theta))) / (3 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
                if (t2 >= 0 && t2 <= 1) {
                    roots[n++] = t2;
                }
                if (t3 >= 0 && t3 <= 1) {
                    roots[n++] = t3;
                }
            }
        }
        return n;
    }
    function cubicExtrema(p0, p1, p2, p3, extrema) {
        var b = 6 * p2 - 12 * p1 + 6 * p0;
        var a = 9 * p1 + 3 * p3 - 3 * p0 - 9 * p2;
        var c = 3 * p1 - 3 * p0;
        var n = 0;
        if (isAroundZero(a)) {
            if (isNotAroundZero(b)) {
                var t1 = -c / b;
                if (t1 >= 0 && t1 <= 1) {
                    extrema[n++] = t1;
                }
            }
        }
        else {
            var disc = b * b - 4 * a * c;
            if (isAroundZero(disc)) {
                extrema[0] = -b / (2 * a);
            }
            else if (disc > 0) {
                var discSqrt = mathSqrt(disc);
                var t1 = (-b + discSqrt) / (2 * a);
                var t2 = (-b - discSqrt) / (2 * a);
                if (t1 >= 0 && t1 <= 1) {
                    extrema[n++] = t1;
                }
                if (t2 >= 0 && t2 <= 1) {
                    extrema[n++] = t2;
                }
            }
        }
        return n;
    }
    function cubicSubdivide(p0, p1, p2, p3, t, out) {
        var p01 = (p1 - p0) * t + p0;
        var p12 = (p2 - p1) * t + p1;
        var p23 = (p3 - p2) * t + p2;
        var p012 = (p12 - p01) * t + p01;
        var p123 = (p23 - p12) * t + p12;
        var p0123 = (p123 - p012) * t + p012;
        out[0] = p0;
        out[1] = p01;
        out[2] = p012;
        out[3] = p0123;
        out[4] = p0123;
        out[5] = p123;
        out[6] = p23;
        out[7] = p3;
    }
    function cubicProjectPoint(x0, y0, x1, y1, x2, y2, x3, y3, x, y, out) {
        var t;
        var interval = 0.005;
        var d = Infinity;
        var prev;
        var next;
        var d1;
        var d2;
        _v0[0] = x;
        _v0[1] = y;
        for (var _t = 0; _t < 1; _t += 0.05) {
            _v1[0] = cubicAt(x0, x1, x2, x3, _t);
            _v1[1] = cubicAt(y0, y1, y2, y3, _t);
            d1 = distSquare(_v0, _v1);
            if (d1 < d) {
                t = _t;
                d = d1;
            }
        }
        d = Infinity;
        for (var i = 0; i < 32; i++) {
            if (interval < EPSILON_NUMERIC) {
                break;
            }
            prev = t - interval;
            next = t + interval;
            _v1[0] = cubicAt(x0, x1, x2, x3, prev);
            _v1[1] = cubicAt(y0, y1, y2, y3, prev);
            d1 = distSquare(_v1, _v0);
            if (prev >= 0 && d1 < d) {
                t = prev;
                d = d1;
            }
            else {
                _v2[0] = cubicAt(x0, x1, x2, x3, next);
                _v2[1] = cubicAt(y0, y1, y2, y3, next);
                d2 = distSquare(_v2, _v0);
                if (next <= 1 && d2 < d) {
                    t = next;
                    d = d2;
                }
                else {
                    interval *= 0.5;
                }
            }
        }
        if (out) {
            out[0] = cubicAt(x0, x1, x2, x3, t);
            out[1] = cubicAt(y0, y1, y2, y3, t);
        }
        return mathSqrt(d);
    }
    function cubicLength(x0, y0, x1, y1, x2, y2, x3, y3, iteration) {
        var px = x0;
        var py = y0;
        var d = 0;
        var step = 1 / iteration;
        for (var i = 1; i <= iteration; i++) {
            var t = i * step;
            var x = cubicAt(x0, x1, x2, x3, t);
            var y = cubicAt(y0, y1, y2, y3, t);
            var dx = x - px;
            var dy = y - py;
            d += Math.sqrt(dx * dx + dy * dy);
            px = x;
            py = y;
        }
        return d;
    }
    function quadraticAt(p0, p1, p2, t) {
        var onet = 1 - t;
        return onet * (onet * p0 + 2 * t * p1) + t * t * p2;
    }
    function quadraticDerivativeAt(p0, p1, p2, t) {
        return 2 * ((1 - t) * (p1 - p0) + t * (p2 - p1));
    }
    function quadraticRootAt(p0, p1, p2, val, roots) {
        var a = p0 - 2 * p1 + p2;
        var b = 2 * (p1 - p0);
        var c = p0 - val;
        var n = 0;
        if (isAroundZero(a)) {
            if (isNotAroundZero(b)) {
                var t1 = -c / b;
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
        }
        else {
            var disc = b * b - 4 * a * c;
            if (isAroundZero(disc)) {
                var t1 = -b / (2 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
            else if (disc > 0) {
                var discSqrt = mathSqrt(disc);
                var t1 = (-b + discSqrt) / (2 * a);
                var t2 = (-b - discSqrt) / (2 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
                if (t2 >= 0 && t2 <= 1) {
                    roots[n++] = t2;
                }
            }
        }
        return n;
    }
    function quadraticExtremum(p0, p1, p2) {
        var divider = p0 + p2 - 2 * p1;
        if (divider === 0) {
            return 0.5;
        }
        else {
            return (p0 - p1) / divider;
        }
    }
    function quadraticSubdivide(p0, p1, p2, t, out) {
        var p01 = (p1 - p0) * t + p0;
        var p12 = (p2 - p1) * t + p1;
        var p012 = (p12 - p01) * t + p01;
        out[0] = p0;
        out[1] = p01;
        out[2] = p012;
        out[3] = p012;
        out[4] = p12;
        out[5] = p2;
    }
    function quadraticProjectPoint(x0, y0, x1, y1, x2, y2, x, y, out) {
        var t;
        var interval = 0.005;
        var d = Infinity;
        _v0[0] = x;
        _v0[1] = y;
        for (var _t = 0; _t < 1; _t += 0.05) {
            _v1[0] = quadraticAt(x0, x1, x2, _t);
            _v1[1] = quadraticAt(y0, y1, y2, _t);
            var d1 = distSquare(_v0, _v1);
            if (d1 < d) {
                t = _t;
                d = d1;
            }
        }
        d = Infinity;
        for (var i = 0; i < 32; i++) {
            if (interval < EPSILON_NUMERIC) {
                break;
            }
            var prev = t - interval;
            var next = t + interval;
            _v1[0] = quadraticAt(x0, x1, x2, prev);
            _v1[1] = quadraticAt(y0, y1, y2, prev);
            var d1 = distSquare(_v1, _v0);
            if (prev >= 0 && d1 < d) {
                t = prev;
                d = d1;
            }
            else {
                _v2[0] = quadraticAt(x0, x1, x2, next);
                _v2[1] = quadraticAt(y0, y1, y2, next);
                var d2 = distSquare(_v2, _v0);
                if (next <= 1 && d2 < d) {
                    t = next;
                    d = d2;
                }
                else {
                    interval *= 0.5;
                }
            }
        }
        if (out) {
            out[0] = quadraticAt(x0, x1, x2, t);
            out[1] = quadraticAt(y0, y1, y2, t);
        }
        return mathSqrt(d);
    }
    function quadraticLength(x0, y0, x1, y1, x2, y2, iteration) {
        var px = x0;
        var py = y0;
        var d = 0;
        var step = 1 / iteration;
        for (var i = 1; i <= iteration; i++) {
            var t = i * step;
            var x = quadraticAt(x0, x1, x2, t);
            var y = quadraticAt(y0, y1, y2, t);
            var dx = x - px;
            var dy = y - py;
            d += Math.sqrt(dx * dx + dy * dy);
            px = x;
            py = y;
        }
        return d;
    }

    var regexp = /cubic-bezier\(([0-9,\.e ]+)\)/;
    function createCubicEasingFunc(cubicEasingStr) {
        var cubic = cubicEasingStr && regexp.exec(cubicEasingStr);
        if (cubic) {
            var points = cubic[1].split(',');
            var a_1 = +trim(points[0]);
            var b_1 = +trim(points[1]);
            var c_1 = +trim(points[2]);
            var d_1 = +trim(points[3]);
            if (isNaN(a_1 + b_1 + c_1 + d_1)) {
                return;
            }
            var roots_1 = [];
            return function (p) {
                return p <= 0
                    ? 0 : p >= 1
                    ? 1
                    : cubicRootAt(0, a_1, c_1, 1, p, roots_1) && cubicAt(0, b_1, d_1, 1, roots_1[0]);
            };
        }
    }

    var Clip = (function () {
        function Clip(opts) {
            this._inited = false;
            this._startTime = 0;
            this._pausedTime = 0;
            this._paused = false;
            this._life = opts.life || 1000;
            this._delay = opts.delay || 0;
            this.loop = opts.loop || false;
            this.onframe = opts.onframe || noop;
            this.ondestroy = opts.ondestroy || noop;
            this.onrestart = opts.onrestart || noop;
            opts.easing && this.setEasing(opts.easing);
        }
        Clip.prototype.step = function (globalTime, deltaTime) {
            if (!this._inited) {
                this._startTime = globalTime + this._delay;
                this._inited = true;
            }
            if (this._paused) {
                this._pausedTime += deltaTime;
                return;
            }
            var life = this._life;
            var elapsedTime = globalTime - this._startTime - this._pausedTime;
            var percent = elapsedTime / life;
            if (percent < 0) {
                percent = 0;
            }
            percent = Math.min(percent, 1);
            var easingFunc = this.easingFunc;
            var schedule = easingFunc ? easingFunc(percent) : percent;
            this.onframe(schedule);
            if (percent === 1) {
                if (this.loop) {
                    var remainder = elapsedTime % life;
                    this._startTime = globalTime - remainder;
                    this._pausedTime = 0;
                    this.onrestart();
                }
                else {
                    return true;
                }
            }
            return false;
        };
        Clip.prototype.pause = function () {
            this._paused = true;
        };
        Clip.prototype.resume = function () {
            this._paused = false;
        };
        Clip.prototype.setEasing = function (easing) {
            this.easing = easing;
            this.easingFunc = isFunction(easing)
                ? easing
                : easingFuncs[easing] || createCubicEasingFunc(easing);
        };
        return Clip;
    }());

    var Entry = (function () {
        function Entry(val) {
            this.value = val;
        }
        return Entry;
    }());
    var LinkedList = (function () {
        function LinkedList() {
            this._len = 0;
        }
        LinkedList.prototype.insert = function (val) {
            var entry = new Entry(val);
            this.insertEntry(entry);
            return entry;
        };
        LinkedList.prototype.insertEntry = function (entry) {
            if (!this.head) {
                this.head = this.tail = entry;
            }
            else {
                this.tail.next = entry;
                entry.prev = this.tail;
                entry.next = null;
                this.tail = entry;
            }
            this._len++;
        };
        LinkedList.prototype.remove = function (entry) {
            var prev = entry.prev;
            var next = entry.next;
            if (prev) {
                prev.next = next;
            }
            else {
                this.head = next;
            }
            if (next) {
                next.prev = prev;
            }
            else {
                this.tail = prev;
            }
            entry.next = entry.prev = null;
            this._len--;
        };
        LinkedList.prototype.len = function () {
            return this._len;
        };
        LinkedList.prototype.clear = function () {
            this.head = this.tail = null;
            this._len = 0;
        };
        return LinkedList;
    }());
    var LRU = (function () {
        function LRU(maxSize) {
            this._list = new LinkedList();
            this._maxSize = 10;
            this._map = {};
            this._maxSize = maxSize;
        }
        LRU.prototype.put = function (key, value) {
            var list = this._list;
            var map = this._map;
            var removed = null;
            if (map[key] == null) {
                var len = list.len();
                var entry = this._lastRemovedEntry;
                if (len >= this._maxSize && len > 0) {
                    var leastUsedEntry = list.head;
                    list.remove(leastUsedEntry);
                    delete map[leastUsedEntry.key];
                    removed = leastUsedEntry.value;
                    this._lastRemovedEntry = leastUsedEntry;
                }
                if (entry) {
                    entry.value = value;
                }
                else {
                    entry = new Entry(value);
                }
                entry.key = key;
                list.insertEntry(entry);
                map[key] = entry;
            }
            return removed;
        };
        LRU.prototype.get = function (key) {
            var entry = this._map[key];
            var list = this._list;
            if (entry != null) {
                if (entry !== list.tail) {
                    list.remove(entry);
                    list.insertEntry(entry);
                }
                return entry.value;
            }
        };
        LRU.prototype.clear = function () {
            this._list.clear();
            this._map = {};
        };
        LRU.prototype.len = function () {
            return this._list.len();
        };
        return LRU;
    }());

    var kCSSColorTable = {
        'transparent': [0, 0, 0, 0], 'aliceblue': [240, 248, 255, 1],
        'antiquewhite': [250, 235, 215, 1], 'aqua': [0, 255, 255, 1],
        'aquamarine': [127, 255, 212, 1], 'azure': [240, 255, 255, 1],
        'beige': [245, 245, 220, 1], 'bisque': [255, 228, 196, 1],
        'black': [0, 0, 0, 1], 'blanchedalmond': [255, 235, 205, 1],
        'blue': [0, 0, 255, 1], 'blueviolet': [138, 43, 226, 1],
        'brown': [165, 42, 42, 1], 'burlywood': [222, 184, 135, 1],
        'cadetblue': [95, 158, 160, 1], 'chartreuse': [127, 255, 0, 1],
        'chocolate': [210, 105, 30, 1], 'coral': [255, 127, 80, 1],
        'cornflowerblue': [100, 149, 237, 1], 'cornsilk': [255, 248, 220, 1],
        'crimson': [220, 20, 60, 1], 'cyan': [0, 255, 255, 1],
        'darkblue': [0, 0, 139, 1], 'darkcyan': [0, 139, 139, 1],
        'darkgoldenrod': [184, 134, 11, 1], 'darkgray': [169, 169, 169, 1],
        'darkgreen': [0, 100, 0, 1], 'darkgrey': [169, 169, 169, 1],
        'darkkhaki': [189, 183, 107, 1], 'darkmagenta': [139, 0, 139, 1],
        'darkolivegreen': [85, 107, 47, 1], 'darkorange': [255, 140, 0, 1],
        'darkorchid': [153, 50, 204, 1], 'darkred': [139, 0, 0, 1],
        'darksalmon': [233, 150, 122, 1], 'darkseagreen': [143, 188, 143, 1],
        'darkslateblue': [72, 61, 139, 1], 'darkslategray': [47, 79, 79, 1],
        'darkslategrey': [47, 79, 79, 1], 'darkturquoise': [0, 206, 209, 1],
        'darkviolet': [148, 0, 211, 1], 'deeppink': [255, 20, 147, 1],
        'deepskyblue': [0, 191, 255, 1], 'dimgray': [105, 105, 105, 1],
        'dimgrey': [105, 105, 105, 1], 'dodgerblue': [30, 144, 255, 1],
        'firebrick': [178, 34, 34, 1], 'floralwhite': [255, 250, 240, 1],
        'forestgreen': [34, 139, 34, 1], 'fuchsia': [255, 0, 255, 1],
        'gainsboro': [220, 220, 220, 1], 'ghostwhite': [248, 248, 255, 1],
        'gold': [255, 215, 0, 1], 'goldenrod': [218, 165, 32, 1],
        'gray': [128, 128, 128, 1], 'green': [0, 128, 0, 1],
        'greenyellow': [173, 255, 47, 1], 'grey': [128, 128, 128, 1],
        'honeydew': [240, 255, 240, 1], 'hotpink': [255, 105, 180, 1],
        'indianred': [205, 92, 92, 1], 'indigo': [75, 0, 130, 1],
        'ivory': [255, 255, 240, 1], 'khaki': [240, 230, 140, 1],
        'lavender': [230, 230, 250, 1], 'lavenderblush': [255, 240, 245, 1],
        'lawngreen': [124, 252, 0, 1], 'lemonchiffon': [255, 250, 205, 1],
        'lightblue': [173, 216, 230, 1], 'lightcoral': [240, 128, 128, 1],
        'lightcyan': [224, 255, 255, 1], 'lightgoldenrodyellow': [250, 250, 210, 1],
        'lightgray': [211, 211, 211, 1], 'lightgreen': [144, 238, 144, 1],
        'lightgrey': [211, 211, 211, 1], 'lightpink': [255, 182, 193, 1],
        'lightsalmon': [255, 160, 122, 1], 'lightseagreen': [32, 178, 170, 1],
        'lightskyblue': [135, 206, 250, 1], 'lightslategray': [119, 136, 153, 1],
        'lightslategrey': [119, 136, 153, 1], 'lightsteelblue': [176, 196, 222, 1],
        'lightyellow': [255, 255, 224, 1], 'lime': [0, 255, 0, 1],
        'limegreen': [50, 205, 50, 1], 'linen': [250, 240, 230, 1],
        'magenta': [255, 0, 255, 1], 'maroon': [128, 0, 0, 1],
        'mediumaquamarine': [102, 205, 170, 1], 'mediumblue': [0, 0, 205, 1],
        'mediumorchid': [186, 85, 211, 1], 'mediumpurple': [147, 112, 219, 1],
        'mediumseagreen': [60, 179, 113, 1], 'mediumslateblue': [123, 104, 238, 1],
        'mediumspringgreen': [0, 250, 154, 1], 'mediumturquoise': [72, 209, 204, 1],
        'mediumvioletred': [199, 21, 133, 1], 'midnightblue': [25, 25, 112, 1],
        'mintcream': [245, 255, 250, 1], 'mistyrose': [255, 228, 225, 1],
        'moccasin': [255, 228, 181, 1], 'navajowhite': [255, 222, 173, 1],
        'navy': [0, 0, 128, 1], 'oldlace': [253, 245, 230, 1],
        'olive': [128, 128, 0, 1], 'olivedrab': [107, 142, 35, 1],
        'orange': [255, 165, 0, 1], 'orangered': [255, 69, 0, 1],
        'orchid': [218, 112, 214, 1], 'palegoldenrod': [238, 232, 170, 1],
        'palegreen': [152, 251, 152, 1], 'paleturquoise': [175, 238, 238, 1],
        'palevioletred': [219, 112, 147, 1], 'papayawhip': [255, 239, 213, 1],
        'peachpuff': [255, 218, 185, 1], 'peru': [205, 133, 63, 1],
        'pink': [255, 192, 203, 1], 'plum': [221, 160, 221, 1],
        'powderblue': [176, 224, 230, 1], 'purple': [128, 0, 128, 1],
        'red': [255, 0, 0, 1], 'rosybrown': [188, 143, 143, 1],
        'royalblue': [65, 105, 225, 1], 'saddlebrown': [139, 69, 19, 1],
        'salmon': [250, 128, 114, 1], 'sandybrown': [244, 164, 96, 1],
        'seagreen': [46, 139, 87, 1], 'seashell': [255, 245, 238, 1],
        'sienna': [160, 82, 45, 1], 'silver': [192, 192, 192, 1],
        'skyblue': [135, 206, 235, 1], 'slateblue': [106, 90, 205, 1],
        'slategray': [112, 128, 144, 1], 'slategrey': [112, 128, 144, 1],
        'snow': [255, 250, 250, 1], 'springgreen': [0, 255, 127, 1],
        'steelblue': [70, 130, 180, 1], 'tan': [210, 180, 140, 1],
        'teal': [0, 128, 128, 1], 'thistle': [216, 191, 216, 1],
        'tomato': [255, 99, 71, 1], 'turquoise': [64, 224, 208, 1],
        'violet': [238, 130, 238, 1], 'wheat': [245, 222, 179, 1],
        'white': [255, 255, 255, 1], 'whitesmoke': [245, 245, 245, 1],
        'yellow': [255, 255, 0, 1], 'yellowgreen': [154, 205, 50, 1]
    };
    function clampCssByte(i) {
        i = Math.round(i);
        return i < 0 ? 0 : i > 255 ? 255 : i;
    }
    function clampCssAngle(i) {
        i = Math.round(i);
        return i < 0 ? 0 : i > 360 ? 360 : i;
    }
    function clampCssFloat(f) {
        return f < 0 ? 0 : f > 1 ? 1 : f;
    }
    function parseCssInt(val) {
        var str = val;
        if (str.length && str.charAt(str.length - 1) === '%') {
            return clampCssByte(parseFloat(str) / 100 * 255);
        }
        return clampCssByte(parseInt(str, 10));
    }
    function parseCssFloat(val) {
        var str = val;
        if (str.length && str.charAt(str.length - 1) === '%') {
            return clampCssFloat(parseFloat(str) / 100);
        }
        return clampCssFloat(parseFloat(str));
    }
    function cssHueToRgb(m1, m2, h) {
        if (h < 0) {
            h += 1;
        }
        else if (h > 1) {
            h -= 1;
        }
        if (h * 6 < 1) {
            return m1 + (m2 - m1) * h * 6;
        }
        if (h * 2 < 1) {
            return m2;
        }
        if (h * 3 < 2) {
            return m1 + (m2 - m1) * (2 / 3 - h) * 6;
        }
        return m1;
    }
    function lerpNumber(a, b, p) {
        return a + (b - a) * p;
    }
    function setRgba(out, r, g, b, a) {
        out[0] = r;
        out[1] = g;
        out[2] = b;
        out[3] = a;
        return out;
    }
    function copyRgba(out, a) {
        out[0] = a[0];
        out[1] = a[1];
        out[2] = a[2];
        out[3] = a[3];
        return out;
    }
    var colorCache = new LRU(20);
    var lastRemovedArr = null;
    function putToCache(colorStr, rgbaArr) {
        if (lastRemovedArr) {
            copyRgba(lastRemovedArr, rgbaArr);
        }
        lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || (rgbaArr.slice()));
    }
    function parse(colorStr, rgbaArr) {
        if (!colorStr) {
            return;
        }
        rgbaArr = rgbaArr || [];
        var cached = colorCache.get(colorStr);
        if (cached) {
            return copyRgba(rgbaArr, cached);
        }
        colorStr = colorStr + '';
        var str = colorStr.replace(/ /g, '').toLowerCase();
        if (str in kCSSColorTable) {
            copyRgba(rgbaArr, kCSSColorTable[str]);
            putToCache(colorStr, rgbaArr);
            return rgbaArr;
        }
        var strLen = str.length;
        if (str.charAt(0) === '#') {
            if (strLen === 4 || strLen === 5) {
                var iv = parseInt(str.slice(1, 4), 16);
                if (!(iv >= 0 && iv <= 0xfff)) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                setRgba(rgbaArr, ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8), (iv & 0xf0) | ((iv & 0xf0) >> 4), (iv & 0xf) | ((iv & 0xf) << 4), strLen === 5 ? parseInt(str.slice(4), 16) / 0xf : 1);
                putToCache(colorStr, rgbaArr);
                return rgbaArr;
            }
            else if (strLen === 7 || strLen === 9) {
                var iv = parseInt(str.slice(1, 7), 16);
                if (!(iv >= 0 && iv <= 0xffffff)) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                setRgba(rgbaArr, (iv & 0xff0000) >> 16, (iv & 0xff00) >> 8, iv & 0xff, strLen === 9 ? parseInt(str.slice(7), 16) / 0xff : 1);
                putToCache(colorStr, rgbaArr);
                return rgbaArr;
            }
            return;
        }
        var op = str.indexOf('(');
        var ep = str.indexOf(')');
        if (op !== -1 && ep + 1 === strLen) {
            var fname = str.substr(0, op);
            var params = str.substr(op + 1, ep - (op + 1)).split(',');
            var alpha = 1;
            switch (fname) {
                case 'rgba':
                    if (params.length !== 4) {
                        return params.length === 3
                            ? setRgba(rgbaArr, +params[0], +params[1], +params[2], 1)
                            : setRgba(rgbaArr, 0, 0, 0, 1);
                    }
                    alpha = parseCssFloat(params.pop());
                case 'rgb':
                    if (params.length >= 3) {
                        setRgba(rgbaArr, parseCssInt(params[0]), parseCssInt(params[1]), parseCssInt(params[2]), params.length === 3 ? alpha : parseCssFloat(params[3]));
                        putToCache(colorStr, rgbaArr);
                        return rgbaArr;
                    }
                    else {
                        setRgba(rgbaArr, 0, 0, 0, 1);
                        return;
                    }
                case 'hsla':
                    if (params.length !== 4) {
                        setRgba(rgbaArr, 0, 0, 0, 1);
                        return;
                    }
                    params[3] = parseCssFloat(params[3]);
                    hsla2rgba(params, rgbaArr);
                    putToCache(colorStr, rgbaArr);
                    return rgbaArr;
                case 'hsl':
                    if (params.length !== 3) {
                        setRgba(rgbaArr, 0, 0, 0, 1);
                        return;
                    }
                    hsla2rgba(params, rgbaArr);
                    putToCache(colorStr, rgbaArr);
                    return rgbaArr;
                default:
                    return;
            }
        }
        setRgba(rgbaArr, 0, 0, 0, 1);
        return;
    }
    function hsla2rgba(hsla, rgba) {
        var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360;
        var s = parseCssFloat(hsla[1]);
        var l = parseCssFloat(hsla[2]);
        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
        var m1 = l * 2 - m2;
        rgba = rgba || [];
        setRgba(rgba, clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255), clampCssByte(cssHueToRgb(m1, m2, h) * 255), clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255), 1);
        if (hsla.length === 4) {
            rgba[3] = hsla[3];
        }
        return rgba;
    }
    function rgba2hsla(rgba) {
        if (!rgba) {
            return;
        }
        var R = rgba[0] / 255;
        var G = rgba[1] / 255;
        var B = rgba[2] / 255;
        var vMin = Math.min(R, G, B);
        var vMax = Math.max(R, G, B);
        var delta = vMax - vMin;
        var L = (vMax + vMin) / 2;
        var H;
        var S;
        if (delta === 0) {
            H = 0;
            S = 0;
        }
        else {
            if (L < 0.5) {
                S = delta / (vMax + vMin);
            }
            else {
                S = delta / (2 - vMax - vMin);
            }
            var deltaR = (((vMax - R) / 6) + (delta / 2)) / delta;
            var deltaG = (((vMax - G) / 6) + (delta / 2)) / delta;
            var deltaB = (((vMax - B) / 6) + (delta / 2)) / delta;
            if (R === vMax) {
                H = deltaB - deltaG;
            }
            else if (G === vMax) {
                H = (1 / 3) + deltaR - deltaB;
            }
            else if (B === vMax) {
                H = (2 / 3) + deltaG - deltaR;
            }
            if (H < 0) {
                H += 1;
            }
            if (H > 1) {
                H -= 1;
            }
        }
        var hsla = [H * 360, S, L];
        if (rgba[3] != null) {
            hsla.push(rgba[3]);
        }
        return hsla;
    }
    function lift(color, level) {
        var colorArr = parse(color);
        if (colorArr) {
            for (var i = 0; i < 3; i++) {
                if (level < 0) {
                    colorArr[i] = colorArr[i] * (1 - level) | 0;
                }
                else {
                    colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0;
                }
                if (colorArr[i] > 255) {
                    colorArr[i] = 255;
                }
                else if (colorArr[i] < 0) {
                    colorArr[i] = 0;
                }
            }
            return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
        }
    }
    function toHex(color) {
        var colorArr = parse(color);
        if (colorArr) {
            return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + (+colorArr[2])).toString(16).slice(1);
        }
    }
    function fastLerp(normalizedValue, colors, out) {
        if (!(colors && colors.length)
            || !(normalizedValue >= 0 && normalizedValue <= 1)) {
            return;
        }
        out = out || [];
        var value = normalizedValue * (colors.length - 1);
        var leftIndex = Math.floor(value);
        var rightIndex = Math.ceil(value);
        var leftColor = colors[leftIndex];
        var rightColor = colors[rightIndex];
        var dv = value - leftIndex;
        out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv));
        out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv));
        out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv));
        out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv));
        return out;
    }
    var fastMapToColor = fastLerp;
    function lerp$1(normalizedValue, colors, fullOutput) {
        if (!(colors && colors.length)
            || !(normalizedValue >= 0 && normalizedValue <= 1)) {
            return;
        }
        var value = normalizedValue * (colors.length - 1);
        var leftIndex = Math.floor(value);
        var rightIndex = Math.ceil(value);
        var leftColor = parse(colors[leftIndex]);
        var rightColor = parse(colors[rightIndex]);
        var dv = value - leftIndex;
        var color = stringify([
            clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)),
            clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)),
            clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)),
            clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv))
        ], 'rgba');
        return fullOutput
            ? {
                color: color,
                leftIndex: leftIndex,
                rightIndex: rightIndex,
                value: value
            }
            : color;
    }
    var mapToColor = lerp$1;
    function modifyHSL(color, h, s, l) {
        var colorArr = parse(color);
        if (color) {
            colorArr = rgba2hsla(colorArr);
            h != null && (colorArr[0] = clampCssAngle(h));
            s != null && (colorArr[1] = parseCssFloat(s));
            l != null && (colorArr[2] = parseCssFloat(l));
            return stringify(hsla2rgba(colorArr), 'rgba');
        }
    }
    function modifyAlpha(color, alpha) {
        var colorArr = parse(color);
        if (colorArr && alpha != null) {
            colorArr[3] = clampCssFloat(alpha);
            return stringify(colorArr, 'rgba');
        }
    }
    function stringify(arrColor, type) {
        if (!arrColor || !arrColor.length) {
            return;
        }
        var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
        if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
            colorStr += ',' + arrColor[3];
        }
        return type + '(' + colorStr + ')';
    }
    function lum(color, backgroundLum) {
        var arr = parse(color);
        return arr
            ? (0.299 * arr[0] + 0.587 * arr[1] + 0.114 * arr[2]) * arr[3] / 255
                + (1 - arr[3]) * backgroundLum
            : 0;
    }
    function random() {
        return stringify([
            Math.round(Math.random() * 255),
            Math.round(Math.random() * 255),
            Math.round(Math.random() * 255)
        ], 'rgb');
    }

    var color = /*#__PURE__*/Object.freeze({
        __proto__: null,
        parse: parse,
        lift: lift,
        toHex: toHex,
        fastLerp: fastLerp,
        fastMapToColor: fastMapToColor,
        lerp: lerp$1,
        mapToColor: mapToColor,
        modifyHSL: modifyHSL,
        modifyAlpha: modifyAlpha,
        stringify: stringify,
        lum: lum,
        random: random
    });

    var mathRound = Math.round;
    function normalizeColor(color) {
        var opacity;
        if (!color || color === 'transparent') {
            color = 'none';
        }
        else if (typeof color === 'string' && color.indexOf('rgba') > -1) {
            var arr = parse(color);
            if (arr) {
                color = 'rgb(' + arr[0] + ',' + arr[1] + ',' + arr[2] + ')';
                opacity = arr[3];
            }
        }
        return {
            color: color,
            opacity: opacity == null ? 1 : opacity
        };
    }
    var EPSILON$1 = 1e-4;
    function isAroundZero$1(transform) {
        return transform < EPSILON$1 && transform > -EPSILON$1;
    }
    function round3(transform) {
        return mathRound(transform * 1e3) / 1e3;
    }
    function round4(transform) {
        return mathRound(transform * 1e4) / 1e4;
    }
    function getMatrixStr(m) {
        return 'matrix('
            + round3(m[0]) + ','
            + round3(m[1]) + ','
            + round3(m[2]) + ','
            + round3(m[3]) + ','
            + round4(m[4]) + ','
            + round4(m[5])
            + ')';
    }
    var TEXT_ALIGN_TO_ANCHOR = {
        left: 'start',
        right: 'end',
        center: 'middle',
        middle: 'middle'
    };
    function adjustTextY(y, lineHeight, textBaseline) {
        if (textBaseline === 'top') {
            y += lineHeight / 2;
        }
        else if (textBaseline === 'bottom') {
            y -= lineHeight / 2;
        }
        return y;
    }
    function hasShadow(style) {
        return style
            && (style.shadowBlur || style.shadowOffsetX || style.shadowOffsetY);
    }
    function getShadowKey(displayable) {
        var style = displayable.style;
        var globalScale = displayable.getGlobalScale();
        return [
            style.shadowColor,
            (style.shadowBlur || 0).toFixed(2),
            (style.shadowOffsetX || 0).toFixed(2),
            (style.shadowOffsetY || 0).toFixed(2),
            globalScale[0],
            globalScale[1]
        ].join(',');
    }
    function isImagePattern(val) {
        return val && (!!val.image);
    }
    function isSVGPattern(val) {
        return val && (!!val.svgElement);
    }
    function isPattern(val) {
        return isImagePattern(val) || isSVGPattern(val);
    }
    function isLinearGradient(val) {
        return val.type === 'linear';
    }
    function isRadialGradient(val) {
        return val.type === 'radial';
    }
    function isGradient(val) {
        return val && (val.type === 'linear'
            || val.type === 'radial');
    }
    function getIdURL(id) {
        return "url(#" + id + ")";
    }
    function getPathPrecision(el) {
        var scale = el.getGlobalScale();
        var size = Math.max(scale[0], scale[1]);
        return Math.max(Math.ceil(Math.log(size) / Math.log(10)), 1);
    }
    function getSRTTransformString(transform) {
        var x = transform.x || 0;
        var y = transform.y || 0;
        var rotation = (transform.rotation || 0) * RADIAN_TO_DEGREE;
        var scaleX = retrieve2(transform.scaleX, 1);
        var scaleY = retrieve2(transform.scaleY, 1);
        var skewX = transform.skewX || 0;
        var skewY = transform.skewY || 0;
        var res = [];
        if (x || y) {
            res.push("translate(" + x + "px," + y + "px)");
        }
        if (rotation) {
            res.push("rotate(" + rotation + ")");
        }
        if (scaleX !== 1 || scaleY !== 1) {
            res.push("scale(" + scaleX + "," + scaleY + ")");
        }
        if (skewX || skewY) {
            res.push("skew(" + mathRound(skewX * RADIAN_TO_DEGREE) + "deg, " + mathRound(skewY * RADIAN_TO_DEGREE) + "deg)");
        }
        return res.join(' ');
    }
    var encodeBase64 = (function () {
        if (env.hasGlobalWindow && isFunction(window.btoa)) {
            return function (str) {
                return window.btoa(unescape(encodeURIComponent(str)));
            };
        }
        if (typeof Buffer !== 'undefined') {
            return function (str) {
                return Buffer.from(str).toString('base64');
            };
        }
        return function (str) {
            if ("development" !== 'production') {
                logError('Base64 isn\'t natively supported in the current environment.');
            }
            return null;
        };
    })();

    var arraySlice = Array.prototype.slice;
    function interpolateNumber(p0, p1, percent) {
        return (p1 - p0) * percent + p0;
    }
    function interpolate1DArray(out, p0, p1, percent) {
        var len = p0.length;
        for (var i = 0; i < len; i++) {
            out[i] = interpolateNumber(p0[i], p1[i], percent);
        }
        return out;
    }
    function interpolate2DArray(out, p0, p1, percent) {
        var len = p0.length;
        var len2 = len && p0[0].length;
        for (var i = 0; i < len; i++) {
            if (!out[i]) {
                out[i] = [];
            }
            for (var j = 0; j < len2; j++) {
                out[i][j] = interpolateNumber(p0[i][j], p1[i][j], percent);
            }
        }
        return out;
    }
    function add1DArray(out, p0, p1, sign) {
        var len = p0.length;
        for (var i = 0; i < len; i++) {
            out[i] = p0[i] + p1[i] * sign;
        }
        return out;
    }
    function add2DArray(out, p0, p1, sign) {
        var len = p0.length;
        var len2 = len && p0[0].length;
        for (var i = 0; i < len; i++) {
            if (!out[i]) {
                out[i] = [];
            }
            for (var j = 0; j < len2; j++) {
                out[i][j] = p0[i][j] + p1[i][j] * sign;
            }
        }
        return out;
    }
    function fillColorStops(val0, val1) {
        var len0 = val0.length;
        var len1 = val1.length;
        var shorterArr = len0 > len1 ? val1 : val0;
        var shorterLen = Math.min(len0, len1);
        var last = shorterArr[shorterLen - 1] || { color: [0, 0, 0, 0], offset: 0 };
        for (var i = shorterLen; i < Math.max(len0, len1); i++) {
            shorterArr.push({
                offset: last.offset,
                color: last.color.slice()
            });
        }
    }
    function fillArray(val0, val1, arrDim) {
        var arr0 = val0;
        var arr1 = val1;
        if (!arr0.push || !arr1.push) {
            return;
        }
        var arr0Len = arr0.length;
        var arr1Len = arr1.length;
        if (arr0Len !== arr1Len) {
            var isPreviousLarger = arr0Len > arr1Len;
            if (isPreviousLarger) {
                arr0.length = arr1Len;
            }
            else {
                for (var i = arr0Len; i < arr1Len; i++) {
                    arr0.push(arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i]));
                }
            }
        }
        var len2 = arr0[0] && arr0[0].length;
        for (var i = 0; i < arr0.length; i++) {
            if (arrDim === 1) {
                if (isNaN(arr0[i])) {
                    arr0[i] = arr1[i];
                }
            }
            else {
                for (var j = 0; j < len2; j++) {
                    if (isNaN(arr0[i][j])) {
                        arr0[i][j] = arr1[i][j];
                    }
                }
            }
        }
    }
    function cloneValue(value) {
        if (isArrayLike(value)) {
            var len = value.length;
            if (isArrayLike(value[0])) {
                var ret = [];
                for (var i = 0; i < len; i++) {
                    ret.push(arraySlice.call(value[i]));
                }
                return ret;
            }
            return arraySlice.call(value);
        }
        return value;
    }
    function rgba2String(rgba) {
        rgba[0] = Math.floor(rgba[0]) || 0;
        rgba[1] = Math.floor(rgba[1]) || 0;
        rgba[2] = Math.floor(rgba[2]) || 0;
        rgba[3] = rgba[3] == null ? 1 : rgba[3];
        return 'rgba(' + rgba.join(',') + ')';
    }
    function guessArrayDim(value) {
        return isArrayLike(value && value[0]) ? 2 : 1;
    }
    var VALUE_TYPE_NUMBER = 0;
    var VALUE_TYPE_1D_ARRAY = 1;
    var VALUE_TYPE_2D_ARRAY = 2;
    var VALUE_TYPE_COLOR = 3;
    var VALUE_TYPE_LINEAR_GRADIENT = 4;
    var VALUE_TYPE_RADIAL_GRADIENT = 5;
    var VALUE_TYPE_UNKOWN = 6;
    function isGradientValueType(valType) {
        return valType === VALUE_TYPE_LINEAR_GRADIENT || valType === VALUE_TYPE_RADIAL_GRADIENT;
    }
    function isArrayValueType(valType) {
        return valType === VALUE_TYPE_1D_ARRAY || valType === VALUE_TYPE_2D_ARRAY;
    }
    var tmpRgba = [0, 0, 0, 0];
    var Track = (function () {
        function Track(propName) {
            this.keyframes = [];
            this.discrete = false;
            this._invalid = false;
            this._needsSort = false;
            this._lastFr = 0;
            this._lastFrP = 0;
            this.propName = propName;
        }
        Track.prototype.isFinished = function () {
            return this._finished;
        };
        Track.prototype.setFinished = function () {
            this._finished = true;
            if (this._additiveTrack) {
                this._additiveTrack.setFinished();
            }
        };
        Track.prototype.needsAnimate = function () {
            return this.keyframes.length >= 1;
        };
        Track.prototype.getAdditiveTrack = function () {
            return this._additiveTrack;
        };
        Track.prototype.addKeyframe = function (time, rawValue, easing) {
            this._needsSort = true;
            var keyframes = this.keyframes;
            var len = keyframes.length;
            var discrete = false;
            var valType = VALUE_TYPE_UNKOWN;
            var value = rawValue;
            if (isArrayLike(rawValue)) {
                var arrayDim = guessArrayDim(rawValue);
                valType = arrayDim;
                if (arrayDim === 1 && !isNumber(rawValue[0])
                    || arrayDim === 2 && !isNumber(rawValue[0][0])) {
                    discrete = true;
                }
            }
            else {
                if (isNumber(rawValue) && !eqNaN(rawValue)) {
                    valType = VALUE_TYPE_NUMBER;
                }
                else if (isString(rawValue)) {
                    if (!isNaN(+rawValue)) {
                        valType = VALUE_TYPE_NUMBER;
                    }
                    else {
                        var colorArray = parse(rawValue);
                        if (colorArray) {
                            value = colorArray;
                            valType = VALUE_TYPE_COLOR;
                        }
                    }
                }
                else if (isGradientObject(rawValue)) {
                    var parsedGradient = extend({}, value);
                    parsedGradient.colorStops = map(rawValue.colorStops, function (colorStop) { return ({
                        offset: colorStop.offset,
                        color: parse(colorStop.color)
                    }); });
                    if (isLinearGradient(rawValue)) {
                        valType = VALUE_TYPE_LINEAR_GRADIENT;
                    }
                    else if (isRadialGradient(rawValue)) {
                        valType = VALUE_TYPE_RADIAL_GRADIENT;
                    }
                    value = parsedGradient;
                }
            }
            if (len === 0) {
                this.valType = valType;
            }
            else if (valType !== this.valType || valType === VALUE_TYPE_UNKOWN) {
                discrete = true;
            }
            this.discrete = this.discrete || discrete;
            var kf = {
                time: time,
                value: value,
                rawValue: rawValue,
                percent: 0
            };
            if (easing) {
                kf.easing = easing;
                kf.easingFunc = isFunction(easing)
                    ? easing
                    : easingFuncs[easing] || createCubicEasingFunc(easing);
            }
            keyframes.push(kf);
            return kf;
        };
        Track.prototype.prepare = function (maxTime, additiveTrack) {
            var kfs = this.keyframes;
            if (this._needsSort) {
                kfs.sort(function (a, b) {
                    return a.time - b.time;
                });
            }
            var valType = this.valType;
            var kfsLen = kfs.length;
            var lastKf = kfs[kfsLen - 1];
            var isDiscrete = this.discrete;
            var isArr = isArrayValueType(valType);
            var isGradient = isGradientValueType(valType);
            for (var i = 0; i < kfsLen; i++) {
                var kf = kfs[i];
                var value = kf.value;
                var lastValue = lastKf.value;
                kf.percent = kf.time / maxTime;
                if (!isDiscrete) {
                    if (isArr && i !== kfsLen - 1) {
                        fillArray(value, lastValue, valType);
                    }
                    else if (isGradient) {
                        fillColorStops(value.colorStops, lastValue.colorStops);
                    }
                }
            }
            if (!isDiscrete
                && valType !== VALUE_TYPE_RADIAL_GRADIENT
                && additiveTrack
                && this.needsAnimate()
                && additiveTrack.needsAnimate()
                && valType === additiveTrack.valType
                && !additiveTrack._finished) {
                this._additiveTrack = additiveTrack;
                var startValue = kfs[0].value;
                for (var i = 0; i < kfsLen; i++) {
                    if (valType === VALUE_TYPE_NUMBER) {
                        kfs[i].additiveValue = kfs[i].value - startValue;
                    }
                    else if (valType === VALUE_TYPE_COLOR) {
                        kfs[i].additiveValue =
                            add1DArray([], kfs[i].value, startValue, -1);
                    }
                    else if (isArrayValueType(valType)) {
                        kfs[i].additiveValue = valType === VALUE_TYPE_1D_ARRAY
                            ? add1DArray([], kfs[i].value, startValue, -1)
                            : add2DArray([], kfs[i].value, startValue, -1);
                    }
                }
            }
        };
        Track.prototype.step = function (target, percent) {
            if (this._finished) {
                return;
            }
            if (this._additiveTrack && this._additiveTrack._finished) {
                this._additiveTrack = null;
            }
            var isAdditive = this._additiveTrack != null;
            var valueKey = isAdditive ? 'additiveValue' : 'value';
            var valType = this.valType;
            var keyframes = this.keyframes;
            var kfsNum = keyframes.length;
            var propName = this.propName;
            var isValueColor = valType === VALUE_TYPE_COLOR;
            var frameIdx;
            var lastFrame = this._lastFr;
            var mathMin = Math.min;
            var frame;
            var nextFrame;
            if (kfsNum === 1) {
                frame = nextFrame = keyframes[0];
            }
            else {
                if (percent < 0) {
                    frameIdx = 0;
                }
                else if (percent < this._lastFrP) {
                    var start = mathMin(lastFrame + 1, kfsNum - 1);
                    for (frameIdx = start; frameIdx >= 0; frameIdx--) {
                        if (keyframes[frameIdx].percent <= percent) {
                            break;
                        }
                    }
                    frameIdx = mathMin(frameIdx, kfsNum - 2);
                }
                else {
                    for (frameIdx = lastFrame; frameIdx < kfsNum; frameIdx++) {
                        if (keyframes[frameIdx].percent > percent) {
                            break;
                        }
                    }
                    frameIdx = mathMin(frameIdx - 1, kfsNum - 2);
                }
                nextFrame = keyframes[frameIdx + 1];
                frame = keyframes[frameIdx];
            }
            if (!(frame && nextFrame)) {
                return;
            }
            this._lastFr = frameIdx;
            this._lastFrP = percent;
            var interval = (nextFrame.percent - frame.percent);
            var w = interval === 0 ? 1 : mathMin((percent - frame.percent) / interval, 1);
            if (nextFrame.easingFunc) {
                w = nextFrame.easingFunc(w);
            }
            var targetArr = isAdditive ? this._additiveValue
                : (isValueColor ? tmpRgba : target[propName]);
            if ((isArrayValueType(valType) || isValueColor) && !targetArr) {
                targetArr = this._additiveValue = [];
            }
            if (this.discrete) {
                target[propName] = w < 1 ? frame.rawValue : nextFrame.rawValue;
            }
            else if (isArrayValueType(valType)) {
                valType === VALUE_TYPE_1D_ARRAY
                    ? interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w)
                    : interpolate2DArray(targetArr, frame[valueKey], nextFrame[valueKey], w);
            }
            else if (isGradientValueType(valType)) {
                var val = frame[valueKey];
                var nextVal_1 = nextFrame[valueKey];
                var isLinearGradient_1 = valType === VALUE_TYPE_LINEAR_GRADIENT;
                target[propName] = {
                    type: isLinearGradient_1 ? 'linear' : 'radial',
                    x: interpolateNumber(val.x, nextVal_1.x, w),
                    y: interpolateNumber(val.y, nextVal_1.y, w),
                    colorStops: map(val.colorStops, function (colorStop, idx) {
                        var nextColorStop = nextVal_1.colorStops[idx];
                        return {
                            offset: interpolateNumber(colorStop.offset, nextColorStop.offset, w),
                            color: rgba2String(interpolate1DArray([], colorStop.color, nextColorStop.color, w))
                        };
                    }),
                    global: nextVal_1.global
                };
                if (isLinearGradient_1) {
                    target[propName].x2 = interpolateNumber(val.x2, nextVal_1.x2, w);
                    target[propName].y2 = interpolateNumber(val.y2, nextVal_1.y2, w);
                }
                else {
                    target[propName].r = interpolateNumber(val.r, nextVal_1.r, w);
                }
            }
            else if (isValueColor) {
                interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w);
                if (!isAdditive) {
                    target[propName] = rgba2String(targetArr);
                }
            }
            else {
                var value = interpolateNumber(frame[valueKey], nextFrame[valueKey], w);
                if (isAdditive) {
                    this._additiveValue = value;
                }
                else {
                    target[propName] = value;
                }
            }
            if (isAdditive) {
                this._addToTarget(target);
            }
        };
        Track.prototype._addToTarget = function (target) {
            var valType = this.valType;
            var propName = this.propName;
            var additiveValue = this._additiveValue;
            if (valType === VALUE_TYPE_NUMBER) {
                target[propName] = target[propName] + additiveValue;
            }
            else if (valType === VALUE_TYPE_COLOR) {
                parse(target[propName], tmpRgba);
                add1DArray(tmpRgba, tmpRgba, additiveValue, 1);
                target[propName] = rgba2String(tmpRgba);
            }
            else if (valType === VALUE_TYPE_1D_ARRAY) {
                add1DArray(target[propName], target[propName], additiveValue, 1);
            }
            else if (valType === VALUE_TYPE_2D_ARRAY) {
                add2DArray(target[propName], target[propName], additiveValue, 1);
            }
        };
        return Track;
    }());
    var Animator = (function () {
        function Animator(target, loop, allowDiscreteAnimation, additiveTo) {
            this._tracks = {};
            this._trackKeys = [];
            this._maxTime = 0;
            this._started = 0;
            this._clip = null;
            this._target = target;
            this._loop = loop;
            if (loop && additiveTo) {
                logError('Can\' use additive animation on looped animation.');
                return;
            }
            this._additiveAnimators = additiveTo;
            this._allowDiscrete = allowDiscreteAnimation;
        }
        Animator.prototype.getMaxTime = function () {
            return this._maxTime;
        };
        Animator.prototype.getDelay = function () {
            return this._delay;
        };
        Animator.prototype.getLoop = function () {
            return this._loop;
        };
        Animator.prototype.getTarget = function () {
            return this._target;
        };
        Animator.prototype.changeTarget = function (target) {
            this._target = target;
        };
        Animator.prototype.when = function (time, props, easing) {
            return this.whenWithKeys(time, props, keys(props), easing);
        };
        Animator.prototype.whenWithKeys = function (time, props, propNames, easing) {
            var tracks = this._tracks;
            for (var i = 0; i < propNames.length; i++) {
                var propName = propNames[i];
                var track = tracks[propName];
                if (!track) {
                    track = tracks[propName] = new Track(propName);
                    var initialValue = void 0;
                    var additiveTrack = this._getAdditiveTrack(propName);
                    if (additiveTrack) {
                        var addtiveTrackKfs = additiveTrack.keyframes;
                        var lastFinalKf = addtiveTrackKfs[addtiveTrackKfs.length - 1];
                        initialValue = lastFinalKf && lastFinalKf.value;
                        if (additiveTrack.valType === VALUE_TYPE_COLOR && initialValue) {
                            initialValue = rgba2String(initialValue);
                        }
                    }
                    else {
                        initialValue = this._target[propName];
                    }
                    if (initialValue == null) {
                        continue;
                    }
                    if (time > 0) {
                        track.addKeyframe(0, cloneValue(initialValue), easing);
                    }
                    this._trackKeys.push(propName);
                }
                track.addKeyframe(time, cloneValue(props[propName]), easing);
            }
            this._maxTime = Math.max(this._maxTime, time);
            return this;
        };
        Animator.prototype.pause = function () {
            this._clip.pause();
            this._paused = true;
        };
        Animator.prototype.resume = function () {
            this._clip.resume();
            this._paused = false;
        };
        Animator.prototype.isPaused = function () {
            return !!this._paused;
        };
        Animator.prototype.duration = function (duration) {
            this._maxTime = duration;
            this._force = true;
            return this;
        };
        Animator.prototype._doneCallback = function () {
            this._setTracksFinished();
            this._clip = null;
            var doneList = this._doneCbs;
            if (doneList) {
                var len = doneList.length;
                for (var i = 0; i < len; i++) {
                    doneList[i].call(this);
                }
            }
        };
        Animator.prototype._abortedCallback = function () {
            this._setTracksFinished();
            var animation = this.animation;
            var abortedList = this._abortedCbs;
            if (animation) {
                animation.removeClip(this._clip);
            }
            this._clip = null;
            if (abortedList) {
                for (var i = 0; i < abortedList.length; i++) {
                    abortedList[i].call(this);
                }
            }
        };
        Animator.prototype._setTracksFinished = function () {
            var tracks = this._tracks;
            var tracksKeys = this._trackKeys;
            for (var i = 0; i < tracksKeys.length; i++) {
                tracks[tracksKeys[i]].setFinished();
            }
        };
        Animator.prototype._getAdditiveTrack = function (trackName) {
            var additiveTrack;
            var additiveAnimators = this._additiveAnimators;
            if (additiveAnimators) {
                for (var i = 0; i < additiveAnimators.length; i++) {
                    var track = additiveAnimators[i].getTrack(trackName);
                    if (track) {
                        additiveTrack = track;
                    }
                }
            }
            return additiveTrack;
        };
        Animator.prototype.start = function (easing) {
            if (this._started > 0) {
                return;
            }
            this._started = 1;
            var self = this;
            var tracks = [];
            var maxTime = this._maxTime || 0;
            for (var i = 0; i < this._trackKeys.length; i++) {
                var propName = this._trackKeys[i];
                var track = this._tracks[propName];
                var additiveTrack = this._getAdditiveTrack(propName);
                var kfs = track.keyframes;
                var kfsNum = kfs.length;
                track.prepare(maxTime, additiveTrack);
                if (track.needsAnimate()) {
                    if (!this._allowDiscrete && track.discrete) {
                        var lastKf = kfs[kfsNum - 1];
                        if (lastKf) {
                            self._target[track.propName] = lastKf.rawValue;
                        }
                        track.setFinished();
                    }
                    else {
                        tracks.push(track);
                    }
                }
            }
            if (tracks.length || this._force) {
                var clip = new Clip({
                    life: maxTime,
                    loop: this._loop,
                    delay: this._delay || 0,
                    onframe: function (percent) {
                        self._started = 2;
                        var additiveAnimators = self._additiveAnimators;
                        if (additiveAnimators) {
                            var stillHasAdditiveAnimator = false;
                            for (var i = 0; i < additiveAnimators.length; i++) {
                                if (additiveAnimators[i]._clip) {
                                    stillHasAdditiveAnimator = true;
                                    break;
                                }
                            }
                            if (!stillHasAdditiveAnimator) {
                                self._additiveAnimators = null;
                            }
                        }
                        for (var i = 0; i < tracks.length; i++) {
                            tracks[i].step(self._target, percent);
                        }
                        var onframeList = self._onframeCbs;
                        if (onframeList) {
                            for (var i = 0; i < onframeList.length; i++) {
                                onframeList[i](self._target, percent);
                            }
                        }
                    },
                    ondestroy: function () {
                        self._doneCallback();
                    }
                });
                this._clip = clip;
                if (this.animation) {
                    this.animation.addClip(clip);
                }
                if (easing) {
                    clip.setEasing(easing);
                }
            }
            else {
                this._doneCallback();
            }
            return this;
        };
        Animator.prototype.stop = function (forwardToLast) {
            if (!this._clip) {
                return;
            }
            var clip = this._clip;
            if (forwardToLast) {
                clip.onframe(1);
            }
            this._abortedCallback();
        };
        Animator.prototype.delay = function (time) {
            this._delay = time;
            return this;
        };
        Animator.prototype.during = function (cb) {
            if (cb) {
                if (!this._onframeCbs) {
                    this._onframeCbs = [];
                }
                this._onframeCbs.push(cb);
            }
            return this;
        };
        Animator.prototype.done = function (cb) {
            if (cb) {
                if (!this._doneCbs) {
                    this._doneCbs = [];
                }
                this._doneCbs.push(cb);
            }
            return this;
        };
        Animator.prototype.aborted = function (cb) {
            if (cb) {
                if (!this._abortedCbs) {
                    this._abortedCbs = [];
                }
                this._abortedCbs.push(cb);
            }
            return this;
        };
        Animator.prototype.getClip = function () {
            return this._clip;
        };
        Animator.prototype.getTrack = function (propName) {
            return this._tracks[propName];
        };
        Animator.prototype.getTracks = function () {
            var _this = this;
            return map(this._trackKeys, function (key) { return _this._tracks[key]; });
        };
        Animator.prototype.stopTracks = function (propNames, forwardToLast) {
            if (!propNames.length || !this._clip) {
                return true;
            }
            var tracks = this._tracks;
            var tracksKeys = this._trackKeys;
            for (var i = 0; i < propNames.length; i++) {
                var track = tracks[propNames[i]];
                if (track && !track.isFinished()) {
                    if (forwardToLast) {
                        track.step(this._target, 1);
                    }
                    else if (this._started === 1) {
                        track.step(this._target, 0);
                    }
                    track.setFinished();
                }
            }
            var allAborted = true;
            for (var i = 0; i < tracksKeys.length; i++) {
                if (!tracks[tracksKeys[i]].isFinished()) {
                    allAborted = false;
                    break;
                }
            }
            if (allAborted) {
                this._abortedCallback();
            }
            return allAborted;
        };
        Animator.prototype.saveTo = function (target, trackKeys, firstOrLast) {
            if (!target) {
                return;
            }
            trackKeys = trackKeys || this._trackKeys;
            for (var i = 0; i < trackKeys.length; i++) {
                var propName = trackKeys[i];
                var track = this._tracks[propName];
                if (!track || track.isFinished()) {
                    continue;
                }
                var kfs = track.keyframes;
                var kf = kfs[firstOrLast ? 0 : kfs.length - 1];
                if (kf) {
                    target[propName] = cloneValue(kf.rawValue);
                }
            }
        };
        Animator.prototype.__changeFinalValue = function (finalProps, trackKeys) {
            trackKeys = trackKeys || keys(finalProps);
            for (var i = 0; i < trackKeys.length; i++) {
                var propName = trackKeys[i];
                var track = this._tracks[propName];
                if (!track) {
                    continue;
                }
                var kfs = track.keyframes;
                if (kfs.length > 1) {
                    var lastKf = kfs.pop();
                    track.addKeyframe(lastKf.time, finalProps[propName]);
                    track.prepare(this._maxTime, track.getAdditiveTrack());
                }
            }
        };
        return Animator;
    }());

    function getTime() {
        return new Date().getTime();
    }
    var Animation = (function (_super) {
        __extends(Animation, _super);
        function Animation(opts) {
            var _this = _super.call(this) || this;
            _this._running = false;
            _this._time = 0;
            _this._pausedTime = 0;
            _this._pauseStart = 0;
            _this._paused = false;
            opts = opts || {};
            _this.stage = opts.stage || {};
            return _this;
        }
        Animation.prototype.addClip = function (clip) {
            if (clip.animation) {
                this.removeClip(clip);
            }
            if (!this._head) {
                this._head = this._tail = clip;
            }
            else {
                this._tail.next = clip;
                clip.prev = this._tail;
                clip.next = null;
                this._tail = clip;
            }
            clip.animation = this;
        };
        Animation.prototype.addAnimator = function (animator) {
            animator.animation = this;
            var clip = animator.getClip();
            if (clip) {
                this.addClip(clip);
            }
        };
        Animation.prototype.removeClip = function (clip) {
            if (!clip.animation) {
                return;
            }
            var prev = clip.prev;
            var next = clip.next;
            if (prev) {
                prev.next = next;
            }
            else {
                this._head = next;
            }
            if (next) {
                next.prev = prev;
            }
            else {
                this._tail = prev;
            }
            clip.next = clip.prev = clip.animation = null;
        };
        Animation.prototype.removeAnimator = function (animator) {
            var clip = animator.getClip();
            if (clip) {
                this.removeClip(clip);
            }
            animator.animation = null;
        };
        Animation.prototype.update = function (notTriggerFrameAndStageUpdate) {
            var time = getTime() - this._pausedTime;
            var delta = time - this._time;
            var clip = this._head;
            while (clip) {
                var nextClip = clip.next;
                var finished = clip.step(time, delta);
                if (finished) {
                    clip.ondestroy();
                    this.removeClip(clip);
                    clip = nextClip;
                }
                else {
                    clip = nextClip;
                }
            }
            this._time = time;
            if (!notTriggerFrameAndStageUpdate) {
                this.trigger('frame', delta);
                this.stage.update && this.stage.update();
            }
        };
        Animation.prototype._startLoop = function () {
            var self = this;
            this._running = true;
            function step() {
                if (self._running) {
                    requestAnimationFrame$1(step);
                    !self._paused && self.update();
                }
            }
            requestAnimationFrame$1(step);
        };
        Animation.prototype.start = function () {
            if (this._running) {
                return;
            }
            this._time = getTime();
            this._pausedTime = 0;
            this._startLoop();
        };
        Animation.prototype.stop = function () {
            this._running = false;
        };
        Animation.prototype.pause = function () {
            if (!this._paused) {
                this._pauseStart = getTime();
                this._paused = true;
            }
        };
        Animation.prototype.resume = function () {
            if (this._paused) {
                this._pausedTime += getTime() - this._pauseStart;
                this._paused = false;
            }
        };
        Animation.prototype.clear = function () {
            var clip = this._head;
            while (clip) {
                var nextClip = clip.next;
                clip.prev = clip.next = clip.animation = null;
                clip = nextClip;
            }
            this._head = this._tail = null;
        };
        Animation.prototype.isFinished = function () {
            return this._head == null;
        };
        Animation.prototype.animate = function (target, options) {
            options = options || {};
            this.start();
            var animator = new Animator(target, options.loop);
            this.addAnimator(animator);
            return animator;
        };
        return Animation;
    }(Eventful));

    var TOUCH_CLICK_DELAY = 300;
    var globalEventSupported = env.domSupported;
    var localNativeListenerNames = (function () {
        var mouseHandlerNames = [
            'click', 'dblclick', 'mousewheel', 'wheel', 'mouseout',
            'mouseup', 'mousedown', 'mousemove', 'contextmenu'
        ];
        var touchHandlerNames = [
            'touchstart', 'touchend', 'touchmove'
        ];
        var pointerEventNameMap = {
            pointerdown: 1, pointerup: 1, pointermove: 1, pointerout: 1
        };
        var pointerHandlerNames = map(mouseHandlerNames, function (name) {
            var nm = name.replace('mouse', 'pointer');
            return pointerEventNameMap.hasOwnProperty(nm) ? nm : name;
        });
        return {
            mouse: mouseHandlerNames,
            touch: touchHandlerNames,
            pointer: pointerHandlerNames
        };
    })();
    var globalNativeListenerNames = {
        mouse: ['mousemove', 'mouseup'],
        pointer: ['pointermove', 'pointerup']
    };
    var wheelEventSupported = false;
    function isPointerFromTouch(event) {
        var pointerType = event.pointerType;
        return pointerType === 'pen' || pointerType === 'touch';
    }
    function setTouchTimer(scope) {
        scope.touching = true;
        if (scope.touchTimer != null) {
            clearTimeout(scope.touchTimer);
            scope.touchTimer = null;
        }
        scope.touchTimer = setTimeout(function () {
            scope.touching = false;
            scope.touchTimer = null;
        }, 700);
    }
    function markTouch(event) {
        event && (event.zrByTouch = true);
    }
    function normalizeGlobalEvent(instance, event) {
        return normalizeEvent(instance.dom, new FakeGlobalEvent(instance, event), true);
    }
    function isLocalEl(instance, el) {
        var elTmp = el;
        var isLocal = false;
        while (elTmp && elTmp.nodeType !== 9
            && !(isLocal = elTmp.domBelongToZr
                || (elTmp !== el && elTmp === instance.painterRoot))) {
            elTmp = elTmp.parentNode;
        }
        return isLocal;
    }
    var FakeGlobalEvent = (function () {
        function FakeGlobalEvent(instance, event) {
            this.stopPropagation = noop;
            this.stopImmediatePropagation = noop;
            this.preventDefault = noop;
            this.type = event.type;
            this.target = this.currentTarget = instance.dom;
            this.pointerType = event.pointerType;
            this.clientX = event.clientX;
            this.clientY = event.clientY;
        }
        return FakeGlobalEvent;
    }());
    var localDOMHandlers = {
        mousedown: function (event) {
            event = normalizeEvent(this.dom, event);
            this.__mayPointerCapture = [event.zrX, event.zrY];
            this.trigger('mousedown', event);
        },
        mousemove: function (event) {
            event = normalizeEvent(this.dom, event);
            var downPoint = this.__mayPointerCapture;
            if (downPoint && (event.zrX !== downPoint[0] || event.zrY !== downPoint[1])) {
                this.__togglePointerCapture(true);
            }
            this.trigger('mousemove', event);
        },
        mouseup: function (event) {
            event = normalizeEvent(this.dom, event);
            this.__togglePointerCapture(false);
            this.trigger('mouseup', event);
        },
        mouseout: function (event) {
            event = normalizeEvent(this.dom, event);
            var element = event.toElement || event.relatedTarget;
            if (!isLocalEl(this, element)) {
                if (this.__pointerCapturing) {
                    event.zrEventControl = 'no_globalout';
                }
                this.trigger('mouseout', event);
            }
        },
        wheel: function (event) {
            wheelEventSupported = true;
            event = normalizeEvent(this.dom, event);
            this.trigger('mousewheel', event);
        },
        mousewheel: function (event) {
            if (wheelEventSupported) {
                return;
            }
            event = normalizeEvent(this.dom, event);
            this.trigger('mousewheel', event);
        },
        touchstart: function (event) {
            event = normalizeEvent(this.dom, event);
            markTouch(event);
            this.__lastTouchMoment = new Date();
            this.handler.processGesture(event, 'start');
            localDOMHandlers.mousemove.call(this, event);
            localDOMHandlers.mousedown.call(this, event);
        },
        touchmove: function (event) {
            event = normalizeEvent(this.dom, event);
            markTouch(event);
            this.handler.processGesture(event, 'change');
            localDOMHandlers.mousemove.call(this, event);
        },
        touchend: function (event) {
            event = normalizeEvent(this.dom, event);
            markTouch(event);
            this.handler.processGesture(event, 'end');
            localDOMHandlers.mouseup.call(this, event);
            if (+new Date() - (+this.__lastTouchMoment) < TOUCH_CLICK_DELAY) {
                localDOMHandlers.click.call(this, event);
            }
        },
        pointerdown: function (event) {
            localDOMHandlers.mousedown.call(this, event);
        },
        pointermove: function (event) {
            if (!isPointerFromTouch(event)) {
                localDOMHandlers.mousemove.call(this, event);
            }
        },
        pointerup: function (event) {
            localDOMHandlers.mouseup.call(this, event);
        },
        pointerout: function (event) {
            if (!isPointerFromTouch(event)) {
                localDOMHandlers.mouseout.call(this, event);
            }
        }
    };
    each(['click', 'dblclick', 'contextmenu'], function (name) {
        localDOMHandlers[name] = function (event) {
            event = normalizeEvent(this.dom, event);
            this.trigger(name, event);
        };
    });
    var globalDOMHandlers = {
        pointermove: function (event) {
            if (!isPointerFromTouch(event)) {
                globalDOMHandlers.mousemove.call(this, event);
            }
        },
        pointerup: function (event) {
            globalDOMHandlers.mouseup.call(this, event);
        },
        mousemove: function (event) {
            this.trigger('mousemove', event);
        },
        mouseup: function (event) {
            var pointerCaptureReleasing = this.__pointerCapturing;
            this.__togglePointerCapture(false);
            this.trigger('mouseup', event);
            if (pointerCaptureReleasing) {
                event.zrEventControl = 'only_globalout';
                this.trigger('mouseout', event);
            }
        }
    };
    function mountLocalDOMEventListeners(instance, scope) {
        var domHandlers = scope.domHandlers;
        if (env.pointerEventsSupported) {
            each(localNativeListenerNames.pointer, function (nativeEventName) {
                mountSingleDOMEventListener(scope, nativeEventName, function (event) {
                    domHandlers[nativeEventName].call(instance, event);
                });
            });
        }
        else {
            if (env.touchEventsSupported) {
                each(localNativeListenerNames.touch, function (nativeEventName) {
                    mountSingleDOMEventListener(scope, nativeEventName, function (event) {
                        domHandlers[nativeEventName].call(instance, event);
                        setTouchTimer(scope);
                    });
                });
            }
            each(localNativeListenerNames.mouse, function (nativeEventName) {
                mountSingleDOMEventListener(scope, nativeEventName, function (event) {
                    event = getNativeEvent(event);
                    if (!scope.touching) {
                        domHandlers[nativeEventName].call(instance, event);
                    }
                });
            });
        }
    }
    function mountGlobalDOMEventListeners(instance, scope) {
        if (env.pointerEventsSupported) {
            each(globalNativeListenerNames.pointer, mount);
        }
        else if (!env.touchEventsSupported) {
            each(globalNativeListenerNames.mouse, mount);
        }
        function mount(nativeEventName) {
            function nativeEventListener(event) {
                event = getNativeEvent(event);
                if (!isLocalEl(instance, event.target)) {
                    event = normalizeGlobalEvent(instance, event);
                    scope.domHandlers[nativeEventName].call(instance, event);
                }
            }
            mountSingleDOMEventListener(scope, nativeEventName, nativeEventListener, { capture: true });
        }
    }
    function mountSingleDOMEventListener(scope, nativeEventName, listener, opt) {
        scope.mounted[nativeEventName] = listener;
        scope.listenerOpts[nativeEventName] = opt;
        addEventListener(scope.domTarget, nativeEventName, listener, opt);
    }
    function unmountDOMEventListeners(scope) {
        var mounted = scope.mounted;
        for (var nativeEventName in mounted) {
            if (mounted.hasOwnProperty(nativeEventName)) {
                removeEventListener(scope.domTarget, nativeEventName, mounted[nativeEventName], scope.listenerOpts[nativeEventName]);
            }
        }
        scope.mounted = {};
    }
    var DOMHandlerScope = (function () {
        function DOMHandlerScope(domTarget, domHandlers) {
            this.mounted = {};
            this.listenerOpts = {};
            this.touching = false;
            this.domTarget = domTarget;
            this.domHandlers = domHandlers;
        }
        return DOMHandlerScope;
    }());
    var HandlerDomProxy = (function (_super) {
        __extends(HandlerDomProxy, _super);
        function HandlerDomProxy(dom, painterRoot) {
            var _this = _super.call(this) || this;
            _this.__pointerCapturing = false;
            _this.dom = dom;
            _this.painterRoot = painterRoot;
            _this._localHandlerScope = new DOMHandlerScope(dom, localDOMHandlers);
            if (globalEventSupported) {
                _this._globalHandlerScope = new DOMHandlerScope(document, globalDOMHandlers);
            }
            mountLocalDOMEventListeners(_this, _this._localHandlerScope);
            return _this;
        }
        HandlerDomProxy.prototype.dispose = function () {
            unmountDOMEventListeners(this._localHandlerScope);
            if (globalEventSupported) {
                unmountDOMEventListeners(this._globalHandlerScope);
            }
        };
        HandlerDomProxy.prototype.setCursor = function (cursorStyle) {
            this.dom.style && (this.dom.style.cursor = cursorStyle || 'default');
        };
        HandlerDomProxy.prototype.__togglePointerCapture = function (isPointerCapturing) {
            this.__mayPointerCapture = null;
            if (globalEventSupported
                && ((+this.__pointerCapturing) ^ (+isPointerCapturing))) {
                this.__pointerCapturing = isPointerCapturing;
                var globalHandlerScope = this._globalHandlerScope;
                isPointerCapturing
                    ? mountGlobalDOMEventListeners(this, globalHandlerScope)
                    : unmountDOMEventListeners(globalHandlerScope);
            }
        };
        return HandlerDomProxy;
    }(Eventful));

    var dpr = 1;
    if (env.hasGlobalWindow) {
        dpr = Math.max(window.devicePixelRatio
            || (window.screen && window.screen.deviceXDPI / window.screen.logicalXDPI)
            || 1, 1);
    }
    var devicePixelRatio = dpr;
    var DARK_MODE_THRESHOLD = 0.4;
    var DARK_LABEL_COLOR = '#333';
    var LIGHT_LABEL_COLOR = '#ccc';
    var LIGHTER_LABEL_COLOR = '#eee';

    var mIdentity = identity;
    var EPSILON$2 = 5e-5;
    function isNotAroundZero$1(val) {
        return val > EPSILON$2 || val < -EPSILON$2;
    }
    var scaleTmp = [];
    var tmpTransform = [];
    var originTransform = create$1();
    var abs = Math.abs;
    var Transformable = (function () {
        function Transformable() {
        }
        Transformable.prototype.getLocalTransform = function (m) {
            return Transformable.getLocalTransform(this, m);
        };
        Transformable.prototype.setPosition = function (arr) {
            this.x = arr[0];
            this.y = arr[1];
        };
        Transformable.prototype.setScale = function (arr) {
            this.scaleX = arr[0];
            this.scaleY = arr[1];
        };
        Transformable.prototype.setSkew = function (arr) {
            this.skewX = arr[0];
            this.skewY = arr[1];
        };
        Transformable.prototype.setOrigin = function (arr) {
            this.originX = arr[0];
            this.originY = arr[1];
        };
        Transformable.prototype.needLocalTransform = function () {
            return isNotAroundZero$1(this.rotation)
                || isNotAroundZero$1(this.x)
                || isNotAroundZero$1(this.y)
                || isNotAroundZero$1(this.scaleX - 1)
                || isNotAroundZero$1(this.scaleY - 1)
                || isNotAroundZero$1(this.skewX)
                || isNotAroundZero$1(this.skewY);
        };
        Transformable.prototype.updateTransform = function () {
            var parentTransform = this.parent && this.parent.transform;
            var needLocalTransform = this.needLocalTransform();
            var m = this.transform;
            if (!(needLocalTransform || parentTransform)) {
                m && mIdentity(m);
                return;
            }
            m = m || create$1();
            if (needLocalTransform) {
                this.getLocalTransform(m);
            }
            else {
                mIdentity(m);
            }
            if (parentTransform) {
                if (needLocalTransform) {
                    mul$1(m, parentTransform, m);
                }
                else {
                    copy$1(m, parentTransform);
                }
            }
            this.transform = m;
            this._resolveGlobalScaleRatio(m);
        };
        Transformable.prototype._resolveGlobalScaleRatio = function (m) {
            var globalScaleRatio = this.globalScaleRatio;
            if (globalScaleRatio != null && globalScaleRatio !== 1) {
                this.getGlobalScale(scaleTmp);
                var relX = scaleTmp[0] < 0 ? -1 : 1;
                var relY = scaleTmp[1] < 0 ? -1 : 1;
                var sx = ((scaleTmp[0] - relX) * globalScaleRatio + relX) / scaleTmp[0] || 0;
                var sy = ((scaleTmp[1] - relY) * globalScaleRatio + relY) / scaleTmp[1] || 0;
                m[0] *= sx;
                m[1] *= sx;
                m[2] *= sy;
                m[3] *= sy;
            }
            this.invTransform = this.invTransform || create$1();
            invert(this.invTransform, m);
        };
        Transformable.prototype.getComputedTransform = function () {
            var transformNode = this;
            var ancestors = [];
            while (transformNode) {
                ancestors.push(transformNode);
                transformNode = transformNode.parent;
            }
            while (transformNode = ancestors.pop()) {
                transformNode.updateTransform();
            }
            return this.transform;
        };
        Transformable.prototype.setLocalTransform = function (m) {
            if (!m) {
                return;
            }
            var sx = m[0] * m[0] + m[1] * m[1];
            var sy = m[2] * m[2] + m[3] * m[3];
            var rotation = Math.atan2(m[1], m[0]);
            var shearX = Math.PI / 2 + rotation - Math.atan2(m[3], m[2]);
            sy = Math.sqrt(sy) * Math.cos(shearX);
            sx = Math.sqrt(sx);
            this.skewX = shearX;
            this.skewY = 0;
            this.rotation = -rotation;
            this.x = +m[4];
            this.y = +m[5];
            this.scaleX = sx;
            this.scaleY = sy;
            this.originX = 0;
            this.originY = 0;
        };
        Transformable.prototype.decomposeTransform = function () {
            if (!this.transform) {
                return;
            }
            var parent = this.parent;
            var m = this.transform;
            if (parent && parent.transform) {
                mul$1(tmpTransform, parent.invTransform, m);
                m = tmpTransform;
            }
            var ox = this.originX;
            var oy = this.originY;
            if (ox || oy) {
                originTransform[4] = ox;
                originTransform[5] = oy;
                mul$1(tmpTransform, m, originTransform);
                tmpTransform[4] -= ox;
                tmpTransform[5] -= oy;
                m = tmpTransform;
            }
            this.setLocalTransform(m);
        };
        Transformable.prototype.getGlobalScale = function (out) {
            var m = this.transform;
            out = out || [];
            if (!m) {
                out[0] = 1;
                out[1] = 1;
                return out;
            }
            out[0] = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
            out[1] = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
            if (m[0] < 0) {
                out[0] = -out[0];
            }
            if (m[3] < 0) {
                out[1] = -out[1];
            }
            return out;
        };
        Transformable.prototype.transformCoordToLocal = function (x, y) {
            var v2 = [x, y];
            var invTransform = this.invTransform;
            if (invTransform) {
                applyTransform(v2, v2, invTransform);
            }
            return v2;
        };
        Transformable.prototype.transformCoordToGlobal = function (x, y) {
            var v2 = [x, y];
            var transform = this.transform;
            if (transform) {
                applyTransform(v2, v2, transform);
            }
            return v2;
        };
        Transformable.prototype.getLineScale = function () {
            var m = this.transform;
            return m && abs(m[0] - 1) > 1e-10 && abs(m[3] - 1) > 1e-10
                ? Math.sqrt(abs(m[0] * m[3] - m[2] * m[1]))
                : 1;
        };
        Transformable.prototype.copyTransform = function (source) {
            copyTransform(this, source);
        };
        Transformable.getLocalTransform = function (target, m) {
            m = m || [];
            var ox = target.originX || 0;
            var oy = target.originY || 0;
            var sx = target.scaleX;
            var sy = target.scaleY;
            var ax = target.anchorX;
            var ay = target.anchorY;
            var rotation = target.rotation || 0;
            var x = target.x;
            var y = target.y;
            var skewX = target.skewX ? Math.tan(target.skewX) : 0;
            var skewY = target.skewY ? Math.tan(-target.skewY) : 0;
            if (ox || oy || ax || ay) {
                var dx = ox + ax;
                var dy = oy + ay;
                m[4] = -dx * sx - skewX * dy * sy;
                m[5] = -dy * sy - skewY * dx * sx;
            }
            else {
                m[4] = m[5] = 0;
            }
            m[0] = sx;
            m[3] = sy;
            m[1] = skewY * sx;
            m[2] = skewX * sy;
            rotation && rotate(m, m, rotation);
            m[4] += ox + x;
            m[5] += oy + y;
            return m;
        };
        Transformable.initDefaultProps = (function () {
            var proto = Transformable.prototype;
            proto.scaleX =
                proto.scaleY =
                    proto.globalScaleRatio = 1;
            proto.x =
                proto.y =
                    proto.originX =
                        proto.originY =
                            proto.skewX =
                                proto.skewY =
                                    proto.rotation =
                                        proto.anchorX =
                                            proto.anchorY = 0;
        })();
        return Transformable;
    }());
    var TRANSFORMABLE_PROPS = [
        'x', 'y', 'originX', 'originY', 'anchorX', 'anchorY', 'rotation', 'scaleX', 'scaleY', 'skewX', 'skewY'
    ];
    function copyTransform(target, source) {
        for (var i = 0; i < TRANSFORMABLE_PROPS.length; i++) {
            var propName = TRANSFORMABLE_PROPS[i];
            target[propName] = source[propName];
        }
    }

    var textWidthCache = {};
    function getWidth(text, font) {
        font = font || DEFAULT_FONT;
        var cacheOfFont = textWidthCache[font];
        if (!cacheOfFont) {
            cacheOfFont = textWidthCache[font] = new LRU(500);
        }
        var width = cacheOfFont.get(text);
        if (width == null) {
            width = platformApi.measureText(text, font).width;
            cacheOfFont.put(text, width);
        }
        return width;
    }
    function innerGetBoundingRect(text, font, textAlign, textBaseline) {
        var width = getWidth(text, font);
        var height = getLineHeight(font);
        var x = adjustTextX(0, width, textAlign);
        var y = adjustTextY$1(0, height, textBaseline);
        var rect = new BoundingRect(x, y, width, height);
        return rect;
    }
    function getBoundingRect(text, font, textAlign, textBaseline) {
        var textLines = ((text || '') + '').split('\n');
        var len = textLines.length;
        if (len === 1) {
            return innerGetBoundingRect(textLines[0], font, textAlign, textBaseline);
        }
        else {
            var uniondRect = new BoundingRect(0, 0, 0, 0);
            for (var i = 0; i < textLines.length; i++) {
                var rect = innerGetBoundingRect(textLines[i], font, textAlign, textBaseline);
                i === 0 ? uniondRect.copy(rect) : uniondRect.union(rect);
            }
            return uniondRect;
        }
    }
    function adjustTextX(x, width, textAlign) {
        if (textAlign === 'right') {
            x -= width;
        }
        else if (textAlign === 'center') {
            x -= width / 2;
        }
        return x;
    }
    function adjustTextY$1(y, height, verticalAlign) {
        if (verticalAlign === 'middle') {
            y -= height / 2;
        }
        else if (verticalAlign === 'bottom') {
            y -= height;
        }
        return y;
    }
    function getLineHeight(font) {
        return getWidth('国', font);
    }
    function parsePercent(value, maxValue) {
        if (typeof value === 'string') {
            if (value.lastIndexOf('%') >= 0) {
                return parseFloat(value) / 100 * maxValue;
            }
            return parseFloat(value);
        }
        return value;
    }
    function calculateTextPosition(out, opts, rect) {
        var textPosition = opts.position || 'inside';
        var distance = opts.distance != null ? opts.distance : 5;
        var height = rect.height;
        var width = rect.width;
        var halfHeight = height / 2;
        var x = rect.x;
        var y = rect.y;
        var textAlign = 'left';
        var textVerticalAlign = 'top';
        if (textPosition instanceof Array) {
            x += parsePercent(textPosition[0], rect.width);
            y += parsePercent(textPosition[1], rect.height);
            textAlign = null;
            textVerticalAlign = null;
        }
        else {
            switch (textPosition) {
                case 'left':
                    x -= distance;
                    y += halfHeight;
                    textAlign = 'right';
                    textVerticalAlign = 'middle';
                    break;
                case 'right':
                    x += distance + width;
                    y += halfHeight;
                    textVerticalAlign = 'middle';
                    break;
                case 'top':
                    x += width / 2;
                    y -= distance;
                    textAlign = 'center';
                    textVerticalAlign = 'bottom';
                    break;
                case 'bottom':
                    x += width / 2;
                    y += height + distance;
                    textAlign = 'center';
                    break;
                case 'inside':
                    x += width / 2;
                    y += halfHeight;
                    textAlign = 'center';
                    textVerticalAlign = 'middle';
                    break;
                case 'insideLeft':
                    x += distance;
                    y += halfHeight;
                    textVerticalAlign = 'middle';
                    break;
                case 'insideRight':
                    x += width - distance;
                    y += halfHeight;
                    textAlign = 'right';
                    textVerticalAlign = 'middle';
                    break;
                case 'insideTop':
                    x += width / 2;
                    y += distance;
                    textAlign = 'center';
                    break;
                case 'insideBottom':
                    x += width / 2;
                    y += height - distance;
                    textAlign = 'center';
                    textVerticalAlign = 'bottom';
                    break;
                case 'insideTopLeft':
                    x += distance;
                    y += distance;
                    break;
                case 'insideTopRight':
                    x += width - distance;
                    y += distance;
                    textAlign = 'right';
                    break;
                case 'insideBottomLeft':
                    x += distance;
                    y += height - distance;
                    textVerticalAlign = 'bottom';
                    break;
                case 'insideBottomRight':
                    x += width - distance;
                    y += height - distance;
                    textAlign = 'right';
                    textVerticalAlign = 'bottom';
                    break;
            }
        }
        out = out || {};
        out.x = x;
        out.y = y;
        out.align = textAlign;
        out.verticalAlign = textVerticalAlign;
        return out;
    }

    var PRESERVED_NORMAL_STATE = '__zr_normal__';
    var PRIMARY_STATES_KEYS = TRANSFORMABLE_PROPS.concat(['ignore']);
    var DEFAULT_ANIMATABLE_MAP = reduce(TRANSFORMABLE_PROPS, function (obj, key) {
        obj[key] = true;
        return obj;
    }, { ignore: false });
    var tmpTextPosCalcRes = {};
    var tmpBoundingRect = new BoundingRect(0, 0, 0, 0);
    var Element = (function () {
        function Element(props) {
            this.id = guid();
            this.animators = [];
            this.currentStates = [];
            this.states = {};
            this._init(props);
        }
        Element.prototype._init = function (props) {
            this.attr(props);
        };
        Element.prototype.drift = function (dx, dy, e) {
            switch (this.draggable) {
                case 'horizontal':
                    dy = 0;
                    break;
                case 'vertical':
                    dx = 0;
                    break;
            }
            var m = this.transform;
            if (!m) {
                m = this.transform = [1, 0, 0, 1, 0, 0];
            }
            m[4] += dx;
            m[5] += dy;
            this.decomposeTransform();
            this.markRedraw();
        };
        Element.prototype.beforeUpdate = function () { };
        Element.prototype.afterUpdate = function () { };
        Element.prototype.update = function () {
            this.updateTransform();
            if (this.__dirty) {
                this.updateInnerText();
            }
        };
        Element.prototype.updateInnerText = function (forceUpdate) {
            var textEl = this._textContent;
            if (textEl && (!textEl.ignore || forceUpdate)) {
                if (!this.textConfig) {
                    this.textConfig = {};
                }
                var textConfig = this.textConfig;
                var isLocal = textConfig.local;
                var innerTransformable = textEl.innerTransformable;
                var textAlign = void 0;
                var textVerticalAlign = void 0;
                var textStyleChanged = false;
                innerTransformable.parent = isLocal ? this : null;
                var innerOrigin = false;
                innerTransformable.copyTransform(textEl);
                if (textConfig.position != null) {
                    var layoutRect = tmpBoundingRect;
                    if (textConfig.layoutRect) {
                        layoutRect.copy(textConfig.layoutRect);
                    }
                    else {
                        layoutRect.copy(this.getBoundingRect());
                    }
                    if (!isLocal) {
                        layoutRect.applyTransform(this.transform);
                    }
                    if (this.calculateTextPosition) {
                        this.calculateTextPosition(tmpTextPosCalcRes, textConfig, layoutRect);
                    }
                    else {
                        calculateTextPosition(tmpTextPosCalcRes, textConfig, layoutRect);
                    }
                    innerTransformable.x = tmpTextPosCalcRes.x;
                    innerTransformable.y = tmpTextPosCalcRes.y;
                    textAlign = tmpTextPosCalcRes.align;
                    textVerticalAlign = tmpTextPosCalcRes.verticalAlign;
                    var textOrigin = textConfig.origin;
                    if (textOrigin && textConfig.rotation != null) {
                        var relOriginX = void 0;
                        var relOriginY = void 0;
                        if (textOrigin === 'center') {
                            relOriginX = layoutRect.width * 0.5;
                            relOriginY = layoutRect.height * 0.5;
                        }
                        else {
                            relOriginX = parsePercent(textOrigin[0], layoutRect.width);
                            relOriginY = parsePercent(textOrigin[1], layoutRect.height);
                        }
                        innerOrigin = true;
                        innerTransformable.originX = -innerTransformable.x + relOriginX + (isLocal ? 0 : layoutRect.x);
                        innerTransformable.originY = -innerTransformable.y + relOriginY + (isLocal ? 0 : layoutRect.y);
                    }
                }
                if (textConfig.rotation != null) {
                    innerTransformable.rotation = textConfig.rotation;
                }
                var textOffset = textConfig.offset;
                if (textOffset) {
                    innerTransformable.x += textOffset[0];
                    innerTransformable.y += textOffset[1];
                    if (!innerOrigin) {
                        innerTransformable.originX = -textOffset[0];
                        innerTransformable.originY = -textOffset[1];
                    }
                }
                var isInside = textConfig.inside == null
                    ? (typeof textConfig.position === 'string' && textConfig.position.indexOf('inside') >= 0)
                    : textConfig.inside;
                var innerTextDefaultStyle = this._innerTextDefaultStyle || (this._innerTextDefaultStyle = {});
                var textFill = void 0;
                var textStroke = void 0;
                var autoStroke = void 0;
                if (isInside && this.canBeInsideText()) {
                    textFill = textConfig.insideFill;
                    textStroke = textConfig.insideStroke;
                    if (textFill == null || textFill === 'auto') {
                        textFill = this.getInsideTextFill();
                    }
                    if (textStroke == null || textStroke === 'auto') {
                        textStroke = this.getInsideTextStroke(textFill);
                        autoStroke = true;
                    }
                }
                else {
                    textFill = textConfig.outsideFill;
                    textStroke = textConfig.outsideStroke;
                    if (textFill == null || textFill === 'auto') {
                        textFill = this.getOutsideFill();
                    }
                    if (textStroke == null || textStroke === 'auto') {
                        textStroke = this.getOutsideStroke(textFill);
                        autoStroke = true;
                    }
                }
                textFill = textFill || '#000';
                if (textFill !== innerTextDefaultStyle.fill
                    || textStroke !== innerTextDefaultStyle.stroke
                    || autoStroke !== innerTextDefaultStyle.autoStroke
                    || textAlign !== innerTextDefaultStyle.align
                    || textVerticalAlign !== innerTextDefaultStyle.verticalAlign) {
                    textStyleChanged = true;
                    innerTextDefaultStyle.fill = textFill;
                    innerTextDefaultStyle.stroke = textStroke;
                    innerTextDefaultStyle.autoStroke = autoStroke;
                    innerTextDefaultStyle.align = textAlign;
                    innerTextDefaultStyle.verticalAlign = textVerticalAlign;
                    textEl.setDefaultTextStyle(innerTextDefaultStyle);
                }
                textEl.__dirty |= REDRAW_BIT;
                if (textStyleChanged) {
                    textEl.dirtyStyle(true);
                }
            }
        };
        Element.prototype.canBeInsideText = function () {
            return true;
        };
        Element.prototype.getInsideTextFill = function () {
            return '#fff';
        };
        Element.prototype.getInsideTextStroke = function (textFill) {
            return '#000';
        };
        Element.prototype.getOutsideFill = function () {
            return this.__zr && this.__zr.isDarkMode() ? LIGHT_LABEL_COLOR : DARK_LABEL_COLOR;
        };
        Element.prototype.getOutsideStroke = function (textFill) {
            var backgroundColor = this.__zr && this.__zr.getBackgroundColor();
            var colorArr = typeof backgroundColor === 'string' && parse(backgroundColor);
            if (!colorArr) {
                colorArr = [255, 255, 255, 1];
            }
            var alpha = colorArr[3];
            var isDark = this.__zr.isDarkMode();
            for (var i = 0; i < 3; i++) {
                colorArr[i] = colorArr[i] * alpha + (isDark ? 0 : 255) * (1 - alpha);
            }
            colorArr[3] = 1;
            return stringify(colorArr, 'rgba');
        };
        Element.prototype.traverse = function (cb, context) { };
        Element.prototype.attrKV = function (key, value) {
            if (key === 'textConfig') {
                this.setTextConfig(value);
            }
            else if (key === 'textContent') {
                this.setTextContent(value);
            }
            else if (key === 'clipPath') {
                this.setClipPath(value);
            }
            else if (key === 'extra') {
                this.extra = this.extra || {};
                extend(this.extra, value);
            }
            else {
                this[key] = value;
            }
        };
        Element.prototype.hide = function () {
            this.ignore = true;
            this.markRedraw();
        };
        Element.prototype.show = function () {
            this.ignore = false;
            this.markRedraw();
        };
        Element.prototype.attr = function (keyOrObj, value) {
            if (typeof keyOrObj === 'string') {
                this.attrKV(keyOrObj, value);
            }
            else if (isObject(keyOrObj)) {
                var obj = keyOrObj;
                var keysArr = keys(obj);
                for (var i = 0; i < keysArr.length; i++) {
                    var key = keysArr[i];
                    this.attrKV(key, keyOrObj[key]);
                }
            }
            this.markRedraw();
            return this;
        };
        Element.prototype.saveCurrentToNormalState = function (toState) {
            this._innerSaveToNormal(toState);
            var normalState = this._normalState;
            for (var i = 0; i < this.animators.length; i++) {
                var animator = this.animators[i];
                var fromStateTransition = animator.__fromStateTransition;
                if (animator.getLoop() || fromStateTransition && fromStateTransition !== PRESERVED_NORMAL_STATE) {
                    continue;
                }
                var targetName = animator.targetName;
                var target = targetName
                    ? normalState[targetName] : normalState;
                animator.saveTo(target);
            }
        };
        Element.prototype._innerSaveToNormal = function (toState) {
            var normalState = this._normalState;
            if (!normalState) {
                normalState = this._normalState = {};
            }
            if (toState.textConfig && !normalState.textConfig) {
                normalState.textConfig = this.textConfig;
            }
            this._savePrimaryToNormal(toState, normalState, PRIMARY_STATES_KEYS);
        };
        Element.prototype._savePrimaryToNormal = function (toState, normalState, primaryKeys) {
            for (var i = 0; i < primaryKeys.length; i++) {
                var key = primaryKeys[i];
                if (toState[key] != null && !(key in normalState)) {
                    normalState[key] = this[key];
                }
            }
        };
        Element.prototype.hasState = function () {
            return this.currentStates.length > 0;
        };
        Element.prototype.getState = function (name) {
            return this.states[name];
        };
        Element.prototype.ensureState = function (name) {
            var states = this.states;
            if (!states[name]) {
                states[name] = {};
            }
            return states[name];
        };
        Element.prototype.clearStates = function (noAnimation) {
            this.useState(PRESERVED_NORMAL_STATE, false, noAnimation);
        };
        Element.prototype.useState = function (stateName, keepCurrentStates, noAnimation, forceUseHoverLayer) {
            var toNormalState = stateName === PRESERVED_NORMAL_STATE;
            var hasStates = this.hasState();
            if (!hasStates && toNormalState) {
                return;
            }
            var currentStates = this.currentStates;
            var animationCfg = this.stateTransition;
            if (indexOf(currentStates, stateName) >= 0 && (keepCurrentStates || currentStates.length === 1)) {
                return;
            }
            var state;
            if (this.stateProxy && !toNormalState) {
                state = this.stateProxy(stateName);
            }
            if (!state) {
                state = (this.states && this.states[stateName]);
            }
            if (!state && !toNormalState) {
                logError("State " + stateName + " not exists.");
                return;
            }
            if (!toNormalState) {
                this.saveCurrentToNormalState(state);
            }
            var useHoverLayer = !!((state && state.hoverLayer) || forceUseHoverLayer);
            if (useHoverLayer) {
                this._toggleHoverLayerFlag(true);
            }
            this._applyStateObj(stateName, state, this._normalState, keepCurrentStates, !noAnimation && !this.__inHover && animationCfg && animationCfg.duration > 0, animationCfg);
            var textContent = this._textContent;
            var textGuide = this._textGuide;
            if (textContent) {
                textContent.useState(stateName, keepCurrentStates, noAnimation, useHoverLayer);
            }
            if (textGuide) {
                textGuide.useState(stateName, keepCurrentStates, noAnimation, useHoverLayer);
            }
            if (toNormalState) {
                this.currentStates = [];
                this._normalState = {};
            }
            else {
                if (!keepCurrentStates) {
                    this.currentStates = [stateName];
                }
                else {
                    this.currentStates.push(stateName);
                }
            }
            this._updateAnimationTargets();
            this.markRedraw();
            if (!useHoverLayer && this.__inHover) {
                this._toggleHoverLayerFlag(false);
                this.__dirty &= ~REDRAW_BIT;
            }
            return state;
        };
        Element.prototype.useStates = function (states, noAnimation, forceUseHoverLayer) {
            if (!states.length) {
                this.clearStates();
            }
            else {
                var stateObjects = [];
                var currentStates = this.currentStates;
                var len = states.length;
                var notChange = len === currentStates.length;
                if (notChange) {
                    for (var i = 0; i < len; i++) {
                        if (states[i] !== currentStates[i]) {
                            notChange = false;
                            break;
                        }
                    }
                }
                if (notChange) {
                    return;
                }
                for (var i = 0; i < len; i++) {
                    var stateName = states[i];
                    var stateObj = void 0;
                    if (this.stateProxy) {
                        stateObj = this.stateProxy(stateName, states);
                    }
                    if (!stateObj) {
                        stateObj = this.states[stateName];
                    }
                    if (stateObj) {
                        stateObjects.push(stateObj);
                    }
                }
                var lastStateObj = stateObjects[len - 1];
                var useHoverLayer = !!((lastStateObj && lastStateObj.hoverLayer) || forceUseHoverLayer);
                if (useHoverLayer) {
                    this._toggleHoverLayerFlag(true);
                }
                var mergedState = this._mergeStates(stateObjects);
                var animationCfg = this.stateTransition;
                this.saveCurrentToNormalState(mergedState);
                this._applyStateObj(states.join(','), mergedState, this._normalState, false, !noAnimation && !this.__inHover && animationCfg && animationCfg.duration > 0, animationCfg);
                var textContent = this._textContent;
                var textGuide = this._textGuide;
                if (textContent) {
                    textContent.useStates(states, noAnimation, useHoverLayer);
                }
                if (textGuide) {
                    textGuide.useStates(states, noAnimation, useHoverLayer);
                }
                this._updateAnimationTargets();
                this.currentStates = states.slice();
                this.markRedraw();
                if (!useHoverLayer && this.__inHover) {
                    this._toggleHoverLayerFlag(false);
                    this.__dirty &= ~REDRAW_BIT;
                }
            }
        };
        Element.prototype._updateAnimationTargets = function () {
            for (var i = 0; i < this.animators.length; i++) {
                var animator = this.animators[i];
                if (animator.targetName) {
                    animator.changeTarget(this[animator.targetName]);
                }
            }
        };
        Element.prototype.removeState = function (state) {
            var idx = indexOf(this.currentStates, state);
            if (idx >= 0) {
                var currentStates = this.currentStates.slice();
                currentStates.splice(idx, 1);
                this.useStates(currentStates);
            }
        };
        Element.prototype.replaceState = function (oldState, newState, forceAdd) {
            var currentStates = this.currentStates.slice();
            var idx = indexOf(currentStates, oldState);
            var newStateExists = indexOf(currentStates, newState) >= 0;
            if (idx >= 0) {
                if (!newStateExists) {
                    currentStates[idx] = newState;
                }
                else {
                    currentStates.splice(idx, 1);
                }
            }
            else if (forceAdd && !newStateExists) {
                currentStates.push(newState);
            }
            this.useStates(currentStates);
        };
        Element.prototype.toggleState = function (state, enable) {
            if (enable) {
                this.useState(state, true);
            }
            else {
                this.removeState(state);
            }
        };
        Element.prototype._mergeStates = function (states) {
            var mergedState = {};
            var mergedTextConfig;
            for (var i = 0; i < states.length; i++) {
                var state = states[i];
                extend(mergedState, state);
                if (state.textConfig) {
                    mergedTextConfig = mergedTextConfig || {};
                    extend(mergedTextConfig, state.textConfig);
                }
            }
            if (mergedTextConfig) {
                mergedState.textConfig = mergedTextConfig;
            }
            return mergedState;
        };
        Element.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) {
            var needsRestoreToNormal = !(state && keepCurrentStates);
            if (state && state.textConfig) {
                this.textConfig = extend({}, keepCurrentStates ? this.textConfig : normalState.textConfig);
                extend(this.textConfig, state.textConfig);
            }
            else if (needsRestoreToNormal) {
                if (normalState.textConfig) {
                    this.textConfig = normalState.textConfig;
                }
            }
            var transitionTarget = {};
            var hasTransition = false;
            for (var i = 0; i < PRIMARY_STATES_KEYS.length; i++) {
                var key = PRIMARY_STATES_KEYS[i];
                var propNeedsTransition = transition && DEFAULT_ANIMATABLE_MAP[key];
                if (state && state[key] != null) {
                    if (propNeedsTransition) {
                        hasTransition = true;
                        transitionTarget[key] = state[key];
                    }
                    else {
                        this[key] = state[key];
                    }
                }
                else if (needsRestoreToNormal) {
                    if (normalState[key] != null) {
                        if (propNeedsTransition) {
                            hasTransition = true;
                            transitionTarget[key] = normalState[key];
                        }
                        else {
                            this[key] = normalState[key];
                        }
                    }
                }
            }
            if (!transition) {
                for (var i = 0; i < this.animators.length; i++) {
                    var animator = this.animators[i];
                    var targetName = animator.targetName;
                    if (!animator.getLoop()) {
                        animator.__changeFinalValue(targetName
                            ? (state || normalState)[targetName]
                            : (state || normalState));
                    }
                }
            }
            if (hasTransition) {
                this._transitionState(stateName, transitionTarget, animationCfg);
            }
        };
        Element.prototype._attachComponent = function (componentEl) {
            if (componentEl.__zr && !componentEl.__hostTarget) {
                if ("development" !== 'production') {
                    throw new Error('Text element has been added to zrender.');
                }
                return;
            }
            if (componentEl === this) {
                if ("development" !== 'production') {
                    throw new Error('Recursive component attachment.');
                }
                return;
            }
            var zr = this.__zr;
            if (zr) {
                componentEl.addSelfToZr(zr);
            }
            componentEl.__zr = zr;
            componentEl.__hostTarget = this;
        };
        Element.prototype._detachComponent = function (componentEl) {
            if (componentEl.__zr) {
                componentEl.removeSelfFromZr(componentEl.__zr);
            }
            componentEl.__zr = null;
            componentEl.__hostTarget = null;
        };
        Element.prototype.getClipPath = function () {
            return this._clipPath;
        };
        Element.prototype.setClipPath = function (clipPath) {
            if (this._clipPath && this._clipPath !== clipPath) {
                this.removeClipPath();
            }
            this._attachComponent(clipPath);
            this._clipPath = clipPath;
            this.markRedraw();
        };
        Element.prototype.removeClipPath = function () {
            var clipPath = this._clipPath;
            if (clipPath) {
                this._detachComponent(clipPath);
                this._clipPath = null;
                this.markRedraw();
            }
        };
        Element.prototype.getTextContent = function () {
            return this._textContent;
        };
        Element.prototype.setTextContent = function (textEl) {
            var previousTextContent = this._textContent;
            if (previousTextContent === textEl) {
                return;
            }
            if (previousTextContent && previousTextContent !== textEl) {
                this.removeTextContent();
            }
            if ("development" !== 'production') {
                if (textEl.__zr && !textEl.__hostTarget) {
                    throw new Error('Text element has been added to zrender.');
                }
            }
            textEl.innerTransformable = new Transformable();
            this._attachComponent(textEl);
            this._textContent = textEl;
            this.markRedraw();
        };
        Element.prototype.setTextConfig = function (cfg) {
            if (!this.textConfig) {
                this.textConfig = {};
            }
            extend(this.textConfig, cfg);
            this.markRedraw();
        };
        Element.prototype.removeTextConfig = function () {
            this.textConfig = null;
            this.markRedraw();
        };
        Element.prototype.removeTextContent = function () {
            var textEl = this._textContent;
            if (textEl) {
                textEl.innerTransformable = null;
                this._detachComponent(textEl);
                this._textContent = null;
                this._innerTextDefaultStyle = null;
                this.markRedraw();
            }
        };
        Element.prototype.getTextGuideLine = function () {
            return this._textGuide;
        };
        Element.prototype.setTextGuideLine = function (guideLine) {
            if (this._textGuide && this._textGuide !== guideLine) {
                this.removeTextGuideLine();
            }
            this._attachComponent(guideLine);
            this._textGuide = guideLine;
            this.markRedraw();
        };
        Element.prototype.removeTextGuideLine = function () {
            var textGuide = this._textGuide;
            if (textGuide) {
                this._detachComponent(textGuide);
                this._textGuide = null;
                this.markRedraw();
            }
        };
        Element.prototype.markRedraw = function () {
            this.__dirty |= REDRAW_BIT;
            var zr = this.__zr;
            if (zr) {
                if (this.__inHover) {
                    zr.refreshHover();
                }
                else {
                    zr.refresh();
                }
            }
            if (this.__hostTarget) {
                this.__hostTarget.markRedraw();
            }
        };
        Element.prototype.dirty = function () {
            this.markRedraw();
        };
        Element.prototype._toggleHoverLayerFlag = function (inHover) {
            this.__inHover = inHover;
            var textContent = this._textContent;
            var textGuide = this._textGuide;
            if (textContent) {
                textContent.__inHover = inHover;
            }
            if (textGuide) {
                textGuide.__inHover = inHover;
            }
        };
        Element.prototype.addSelfToZr = function (zr) {
            if (this.__zr === zr) {
                return;
            }
            this.__zr = zr;
            var animators = this.animators;
            if (animators) {
                for (var i = 0; i < animators.length; i++) {
                    zr.animation.addAnimator(animators[i]);
                }
            }
            if (this._clipPath) {
                this._clipPath.addSelfToZr(zr);
            }
            if (this._textContent) {
                this._textContent.addSelfToZr(zr);
            }
            if (this._textGuide) {
                this._textGuide.addSelfToZr(zr);
            }
        };
        Element.prototype.removeSelfFromZr = function (zr) {
            if (!this.__zr) {
                return;
            }
            this.__zr = null;
            var animators = this.animators;
            if (animators) {
                for (var i = 0; i < animators.length; i++) {
                    zr.animation.removeAnimator(animators[i]);
                }
            }
            if (this._clipPath) {
                this._clipPath.removeSelfFromZr(zr);
            }
            if (this._textContent) {
                this._textContent.removeSelfFromZr(zr);
            }
            if (this._textGuide) {
                this._textGuide.removeSelfFromZr(zr);
            }
        };
        Element.prototype.animate = function (key, loop, allowDiscreteAnimation) {
            var target = key ? this[key] : this;
            if ("development" !== 'production') {
                if (!target) {
                    logError('Property "'
                        + key
                        + '" is not existed in element '
                        + this.id);
                    return;
                }
            }
            var animator = new Animator(target, loop, allowDiscreteAnimation);
            key && (animator.targetName = key);
            this.addAnimator(animator, key);
            return animator;
        };
        Element.prototype.addAnimator = function (animator, key) {
            var zr = this.__zr;
            var el = this;
            animator.during(function () {
                el.updateDuringAnimation(key);
            }).done(function () {
                var animators = el.animators;
                var idx = indexOf(animators, animator);
                if (idx >= 0) {
                    animators.splice(idx, 1);
                }
            });
            this.animators.push(animator);
            if (zr) {
                zr.animation.addAnimator(animator);
            }
            zr && zr.wakeUp();
        };
        Element.prototype.updateDuringAnimation = function (key) {
            this.markRedraw();
        };
        Element.prototype.stopAnimation = function (scope, forwardToLast) {
            var animators = this.animators;
            var len = animators.length;
            var leftAnimators = [];
            for (var i = 0; i < len; i++) {
                var animator = animators[i];
                if (!scope || scope === animator.scope) {
                    animator.stop(forwardToLast);
                }
                else {
                    leftAnimators.push(animator);
                }
            }
            this.animators = leftAnimators;
            return this;
        };
        Element.prototype.animateTo = function (target, cfg, animationProps) {
            animateTo(this, target, cfg, animationProps);
        };
        Element.prototype.animateFrom = function (target, cfg, animationProps) {
            animateTo(this, target, cfg, animationProps, true);
        };
        Element.prototype._transitionState = function (stateName, target, cfg, animationProps) {
            var animators = animateTo(this, target, cfg, animationProps);
            for (var i = 0; i < animators.length; i++) {
                animators[i].__fromStateTransition = stateName;
            }
        };
        Element.prototype.getBoundingRect = function () {
            return null;
        };
        Element.prototype.getPaintRect = function () {
            return null;
        };
        Element.initDefaultProps = (function () {
            var elProto = Element.prototype;
            elProto.type = 'element';
            elProto.name = '';
            elProto.ignore =
                elProto.silent =
                    elProto.isGroup =
                        elProto.draggable =
                            elProto.dragging =
                                elProto.ignoreClip =
                                    elProto.__inHover = false;
            elProto.__dirty = REDRAW_BIT;
            var logs = {};
            function logDeprecatedError(key, xKey, yKey) {
                if (!logs[key + xKey + yKey]) {
                    console.warn("DEPRECATED: '" + key + "' has been deprecated. use '" + xKey + "', '" + yKey + "' instead");
                    logs[key + xKey + yKey] = true;
                }
            }
            function createLegacyProperty(key, privateKey, xKey, yKey) {
                Object.defineProperty(elProto, key, {
                    get: function () {
                        if ("development" !== 'production') {
                            logDeprecatedError(key, xKey, yKey);
                        }
                        if (!this[privateKey]) {
                            var pos = this[privateKey] = [];
                            enhanceArray(this, pos);
                        }
                        return this[privateKey];
                    },
                    set: function (pos) {
                        if ("development" !== 'production') {
                            logDeprecatedError(key, xKey, yKey);
                        }
                        this[xKey] = pos[0];
                        this[yKey] = pos[1];
                        this[privateKey] = pos;
                        enhanceArray(this, pos);
                    }
                });
                function enhanceArray(self, pos) {
                    Object.defineProperty(pos, 0, {
                        get: function () {
                            return self[xKey];
                        },
                        set: function (val) {
                            self[xKey] = val;
                        }
                    });
                    Object.defineProperty(pos, 1, {
                        get: function () {
                            return self[yKey];
                        },
                        set: function (val) {
                            self[yKey] = val;
                        }
                    });
                }
            }
            if (Object.defineProperty) {
                createLegacyProperty('position', '_legacyPos', 'x', 'y');
                createLegacyProperty('scale', '_legacyScale', 'scaleX', 'scaleY');
                createLegacyProperty('origin', '_legacyOrigin', 'originX', 'originY');
            }
        })();
        return Element;
    }());
    mixin(Element, Eventful);
    mixin(Element, Transformable);
    function animateTo(animatable, target, cfg, animationProps, reverse) {
        cfg = cfg || {};
        var animators = [];
        animateToShallow(animatable, '', animatable, target, cfg, animationProps, animators, reverse);
        var finishCount = animators.length;
        var doneHappened = false;
        var cfgDone = cfg.done;
        var cfgAborted = cfg.aborted;
        var doneCb = function () {
            doneHappened = true;
            finishCount--;
            if (finishCount <= 0) {
                doneHappened
                    ? (cfgDone && cfgDone())
                    : (cfgAborted && cfgAborted());
            }
        };
        var abortedCb = function () {
            finishCount--;
            if (finishCount <= 0) {
                doneHappened
                    ? (cfgDone && cfgDone())
                    : (cfgAborted && cfgAborted());
            }
        };
        if (!finishCount) {
            cfgDone && cfgDone();
        }
        if (animators.length > 0 && cfg.during) {
            animators[0].during(function (target, percent) {
                cfg.during(percent);
            });
        }
        for (var i = 0; i < animators.length; i++) {
            var animator = animators[i];
            if (doneCb) {
                animator.done(doneCb);
            }
            if (abortedCb) {
                animator.aborted(abortedCb);
            }
            if (cfg.force) {
                animator.duration(cfg.duration);
            }
            animator.start(cfg.easing);
        }
        return animators;
    }
    function copyArrShallow(source, target, len) {
        for (var i = 0; i < len; i++) {
            source[i] = target[i];
        }
    }
    function is2DArray(value) {
        return isArrayLike(value[0]);
    }
    function copyValue(target, source, key) {
        if (isArrayLike(source[key])) {
            if (!isArrayLike(target[key])) {
                target[key] = [];
            }
            if (isTypedArray(source[key])) {
                var len = source[key].length;
                if (target[key].length !== len) {
                    target[key] = new (source[key].constructor)(len);
                    copyArrShallow(target[key], source[key], len);
                }
            }
            else {
                var sourceArr = source[key];
                var targetArr = target[key];
                var len0 = sourceArr.length;
                if (is2DArray(sourceArr)) {
                    var len1 = sourceArr[0].length;
                    for (var i = 0; i < len0; i++) {
                        if (!targetArr[i]) {
                            targetArr[i] = Array.prototype.slice.call(sourceArr[i]);
                        }
                        else {
                            copyArrShallow(targetArr[i], sourceArr[i], len1);
                        }
                    }
                }
                else {
                    copyArrShallow(targetArr, sourceArr, len0);
                }
                targetArr.length = sourceArr.length;
            }
        }
        else {
            target[key] = source[key];
        }
    }
    function isValueSame(val1, val2) {
        return val1 === val2
            || isArrayLike(val1) && isArrayLike(val2) && is1DArraySame(val1, val2);
    }
    function is1DArraySame(arr0, arr1) {
        var len = arr0.length;
        if (len !== arr1.length) {
            return false;
        }
        for (var i = 0; i < len; i++) {
            if (arr0[i] !== arr1[i]) {
                return false;
            }
        }
        return true;
    }
    function animateToShallow(animatable, topKey, animateObj, target, cfg, animationProps, animators, reverse) {
        var targetKeys = keys(target);
        var duration = cfg.duration;
        var delay = cfg.delay;
        var additive = cfg.additive;
        var setToFinal = cfg.setToFinal;
        var animateAll = !isObject(animationProps);
        var existsAnimators = animatable.animators;
        var animationKeys = [];
        for (var k = 0; k < targetKeys.length; k++) {
            var innerKey = targetKeys[k];
            var targetVal = target[innerKey];
            if (targetVal != null && animateObj[innerKey] != null
                && (animateAll || animationProps[innerKey])) {
                if (isObject(targetVal)
                    && !isArrayLike(targetVal)
                    && !isGradientObject(targetVal)) {
                    if (topKey) {
                        if (!reverse) {
                            animateObj[innerKey] = targetVal;
                            animatable.updateDuringAnimation(topKey);
                        }
                        continue;
                    }
                    animateToShallow(animatable, innerKey, animateObj[innerKey], targetVal, cfg, animationProps && animationProps[innerKey], animators, reverse);
                }
                else {
                    animationKeys.push(innerKey);
                }
            }
            else if (!reverse) {
                animateObj[innerKey] = targetVal;
                animatable.updateDuringAnimation(topKey);
                animationKeys.push(innerKey);
            }
        }
        var keyLen = animationKeys.length;
        if (!additive && keyLen) {
            for (var i = 0; i < existsAnimators.length; i++) {
                var animator = existsAnimators[i];
                if (animator.targetName === topKey) {
                    var allAborted = animator.stopTracks(animationKeys);
                    if (allAborted) {
                        var idx = indexOf(existsAnimators, animator);
                        existsAnimators.splice(idx, 1);
                    }
                }
            }
        }
        if (!cfg.force) {
            animationKeys = filter(animationKeys, function (key) { return !isValueSame(target[key], animateObj[key]); });
            keyLen = animationKeys.length;
        }
        if (keyLen > 0
            || (cfg.force && !animators.length)) {
            var revertedSource = void 0;
            var reversedTarget = void 0;
            var sourceClone = void 0;
            if (reverse) {
                reversedTarget = {};
                if (setToFinal) {
                    revertedSource = {};
                }
                for (var i = 0; i < keyLen; i++) {
                    var innerKey = animationKeys[i];
                    reversedTarget[innerKey] = animateObj[innerKey];
                    if (setToFinal) {
                        revertedSource[innerKey] = target[innerKey];
                    }
                    else {
                        animateObj[innerKey] = target[innerKey];
                    }
                }
            }
            else if (setToFinal) {
                sourceClone = {};
                for (var i = 0; i < keyLen; i++) {
                    var innerKey = animationKeys[i];
                    sourceClone[innerKey] = cloneValue(animateObj[innerKey]);
                    copyValue(animateObj, target, innerKey);
                }
            }
            var animator = new Animator(animateObj, false, false, additive ? filter(existsAnimators, function (animator) { return animator.targetName === topKey; }) : null);
            animator.targetName = topKey;
            if (cfg.scope) {
                animator.scope = cfg.scope;
            }
            if (setToFinal && revertedSource) {
                animator.whenWithKeys(0, revertedSource, animationKeys);
            }
            if (sourceClone) {
                animator.whenWithKeys(0, sourceClone, animationKeys);
            }
            animator.whenWithKeys(duration == null ? 500 : duration, reverse ? reversedTarget : target, animationKeys).delay(delay || 0);
            animatable.addAnimator(animator, topKey);
            animators.push(animator);
        }
    }

    var Group = (function (_super) {
        __extends(Group, _super);
        function Group(opts) {
            var _this = _super.call(this) || this;
            _this.isGroup = true;
            _this._children = [];
            _this.attr(opts);
            return _this;
        }
        Group.prototype.childrenRef = function () {
            return this._children;
        };
        Group.prototype.children = function () {
            return this._children.slice();
        };
        Group.prototype.childAt = function (idx) {
            return this._children[idx];
        };
        Group.prototype.childOfName = function (name) {
            var children = this._children;
            for (var i = 0; i < children.length; i++) {
                if (children[i].name === name) {
                    return children[i];
                }
            }
        };
        Group.prototype.childCount = function () {
            return this._children.length;
        };
        Group.prototype.add = function (child) {
            if (child) {
                if (child !== this && child.parent !== this) {
                    this._children.push(child);
                    this._doAdd(child);
                }
                if ("development" !== 'production') {
                    if (child.__hostTarget) {
                        throw 'This elemenet has been used as an attachment';
                    }
                }
            }
            return this;
        };
        Group.prototype.addBefore = function (child, nextSibling) {
            if (child && child !== this && child.parent !== this
                && nextSibling && nextSibling.parent === this) {
                var children = this._children;
                var idx = children.indexOf(nextSibling);
                if (idx >= 0) {
                    children.splice(idx, 0, child);
                    this._doAdd(child);
                }
            }
            return this;
        };
        Group.prototype.replace = function (oldChild, newChild) {
            var idx = indexOf(this._children, oldChild);
            if (idx >= 0) {
                this.replaceAt(newChild, idx);
            }
            return this;
        };
        Group.prototype.replaceAt = function (child, index) {
            var children = this._children;
            var old = children[index];
            if (child && child !== this && child.parent !== this && child !== old) {
                children[index] = child;
                old.parent = null;
                var zr = this.__zr;
                if (zr) {
                    old.removeSelfFromZr(zr);
                }
                this._doAdd(child);
            }
            return this;
        };
        Group.prototype._doAdd = function (child) {
            if (child.parent) {
                child.parent.remove(child);
            }
            child.parent = this;
            var zr = this.__zr;
            if (zr && zr !== child.__zr) {
                child.addSelfToZr(zr);
            }
            zr && zr.refresh();
        };
        Group.prototype.remove = function (child) {
            var zr = this.__zr;
            var children = this._children;
            var idx = indexOf(children, child);
            if (idx < 0) {
                return this;
            }
            children.splice(idx, 1);
            child.parent = null;
            if (zr) {
                child.removeSelfFromZr(zr);
            }
            zr && zr.refresh();
            return this;
        };
        Group.prototype.removeAll = function () {
            var children = this._children;
            var zr = this.__zr;
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                if (zr) {
                    child.removeSelfFromZr(zr);
                }
                child.parent = null;
            }
            children.length = 0;
            return this;
        };
        Group.prototype.eachChild = function (cb, context) {
            var children = this._children;
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                cb.call(context, child, i);
            }
            return this;
        };
        Group.prototype.traverse = function (cb, context) {
            for (var i = 0; i < this._children.length; i++) {
                var child = this._children[i];
                var stopped = cb.call(context, child);
                if (child.isGroup && !stopped) {
                    child.traverse(cb, context);
                }
            }
            return this;
        };
        Group.prototype.addSelfToZr = function (zr) {
            _super.prototype.addSelfToZr.call(this, zr);
            for (var i = 0; i < this._children.length; i++) {
                var child = this._children[i];
                child.addSelfToZr(zr);
            }
        };
        Group.prototype.removeSelfFromZr = function (zr) {
            _super.prototype.removeSelfFromZr.call(this, zr);
            for (var i = 0; i < this._children.length; i++) {
                var child = this._children[i];
                child.removeSelfFromZr(zr);
            }
        };
        Group.prototype.getBoundingRect = function (includeChildren) {
            var tmpRect = new BoundingRect(0, 0, 0, 0);
            var children = includeChildren || this._children;
            var tmpMat = [];
            var rect = null;
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                if (child.ignore || child.invisible) {
                    continue;
                }
                var childRect = child.getBoundingRect();
                var transform = child.getLocalTransform(tmpMat);
                if (transform) {
                    BoundingRect.applyTransform(tmpRect, childRect, transform);
                    rect = rect || tmpRect.clone();
                    rect.union(tmpRect);
                }
                else {
                    rect = rect || childRect.clone();
                    rect.union(childRect);
                }
            }
            return rect || tmpRect;
        };
        return Group;
    }(Element));
    Group.prototype.type = 'group';

    /*!
    * ZRender, a high performance 2d drawing library.
    *
    * Copyright (c) 2013, Baidu Inc.
    * All rights reserved.
    *
    * LICENSE
    * https://github.com/ecomfe/zrender/blob/master/LICENSE.txt
    */
    var painterCtors = {};
    var instances = {};
    function delInstance(id) {
        delete instances[id];
    }
    function isDarkMode(backgroundColor) {
        if (!backgroundColor) {
            return false;
        }
        if (typeof backgroundColor === 'string') {
            return lum(backgroundColor, 1) < DARK_MODE_THRESHOLD;
        }
        else if (backgroundColor.colorStops) {
            var colorStops = backgroundColor.colorStops;
            var totalLum = 0;
            var len = colorStops.length;
            for (var i = 0; i < len; i++) {
                totalLum += lum(colorStops[i].color, 1);
            }
            totalLum /= len;
            return totalLum < DARK_MODE_THRESHOLD;
        }
        return false;
    }
    var ZRender = (function () {
        function ZRender(id, dom, opts) {
            var _this = this;
            this._sleepAfterStill = 10;
            this._stillFrameAccum = 0;
            this._needsRefresh = true;
            this._needsRefreshHover = true;
            this._darkMode = false;
            opts = opts || {};
            this.dom = dom;
            this.id = id;
            var storage = new Storage();
            var rendererType = opts.renderer || 'canvas';
            if (!painterCtors[rendererType]) {
                rendererType = keys(painterCtors)[0];
            }
            if ("development" !== 'production') {
                if (!painterCtors[rendererType]) {
                    throw new Error("Renderer '" + rendererType + "' is not imported. Please import it first.");
                }
            }
            opts.useDirtyRect = opts.useDirtyRect == null
                ? false
                : opts.useDirtyRect;
            var painter = new painterCtors[rendererType](dom, storage, opts, id);
            var ssrMode = opts.ssr || painter.ssrOnly;
            this.storage = storage;
            this.painter = painter;
            var handerProxy = (!env.node && !env.worker && !ssrMode)
                ? new HandlerDomProxy(painter.getViewportRoot(), painter.root)
                : null;
            var useCoarsePointer = opts.useCoarsePointer;
            var usePointerSize = (useCoarsePointer == null || useCoarsePointer === 'auto')
                ? env.touchEventsSupported
                : !!useCoarsePointer;
            var defaultPointerSize = 44;
            var pointerSize;
            if (usePointerSize) {
                pointerSize = retrieve2(opts.pointerSize, defaultPointerSize);
            }
            this.handler = new Handler(storage, painter, handerProxy, painter.root, pointerSize);
            this.animation = new Animation({
                stage: {
                    update: ssrMode ? null : function () { return _this._flush(true); }
                }
            });
            if (!ssrMode) {
                this.animation.start();
            }
        }
        ZRender.prototype.add = function (el) {
            if (!el) {
                return;
            }
            this.storage.addRoot(el);
            el.addSelfToZr(this);
            this.refresh();
        };
        ZRender.prototype.remove = function (el) {
            if (!el) {
                return;
            }
            this.storage.delRoot(el);
            el.removeSelfFromZr(this);
            this.refresh();
        };
        ZRender.prototype.configLayer = function (zLevel, config) {
            if (this.painter.configLayer) {
                this.painter.configLayer(zLevel, config);
            }
            this.refresh();
        };
        ZRender.prototype.setBackgroundColor = function (backgroundColor) {
            if (this.painter.setBackgroundColor) {
                this.painter.setBackgroundColor(backgroundColor);
            }
            this.refresh();
            this._backgroundColor = backgroundColor;
            this._darkMode = isDarkMode(backgroundColor);
        };
        ZRender.prototype.getBackgroundColor = function () {
            return this._backgroundColor;
        };
        ZRender.prototype.setDarkMode = function (darkMode) {
            this._darkMode = darkMode;
        };
        ZRender.prototype.isDarkMode = function () {
            return this._darkMode;
        };
        ZRender.prototype.refreshImmediately = function (fromInside) {
            if (!fromInside) {
                this.animation.update(true);
            }
            this._needsRefresh = false;
            this.painter.refresh();
            this._needsRefresh = false;
        };
        ZRender.prototype.refresh = function () {
            this._needsRefresh = true;
            this.animation.start();
        };
        ZRender.prototype.flush = function () {
            this._flush(false);
        };
        ZRender.prototype._flush = function (fromInside) {
            var triggerRendered;
            var start = getTime();
            if (this._needsRefresh) {
                triggerRendered = true;
                this.refreshImmediately(fromInside);
            }
            if (this._needsRefreshHover) {
                triggerRendered = true;
                this.refreshHoverImmediately();
            }
            var end = getTime();
            if (triggerRendered) {
                this._stillFrameAccum = 0;
                this.trigger('rendered', {
                    elapsedTime: end - start
                });
            }
            else if (this._sleepAfterStill > 0) {
                this._stillFrameAccum++;
                if (this._stillFrameAccum > this._sleepAfterStill) {
                    this.animation.stop();
                }
            }
        };
        ZRender.prototype.setSleepAfterStill = function (stillFramesCount) {
            this._sleepAfterStill = stillFramesCount;
        };
        ZRender.prototype.wakeUp = function () {
            this.animation.start();
            this._stillFrameAccum = 0;
        };
        ZRender.prototype.refreshHover = function () {
            this._needsRefreshHover = true;
        };
        ZRender.prototype.refreshHoverImmediately = function () {
            this._needsRefreshHover = false;
            if (this.painter.refreshHover && this.painter.getType() === 'canvas') {
                this.painter.refreshHover();
            }
        };
        ZRender.prototype.resize = function (opts) {
            opts = opts || {};
            this.painter.resize(opts.width, opts.height);
            this.handler.resize();
        };
        ZRender.prototype.clearAnimation = function () {
            this.animation.clear();
        };
        ZRender.prototype.getWidth = function () {
            return this.painter.getWidth();
        };
        ZRender.prototype.getHeight = function () {
            return this.painter.getHeight();
        };
        ZRender.prototype.setCursorStyle = function (cursorStyle) {
            this.handler.setCursorStyle(cursorStyle);
        };
        ZRender.prototype.findHover = function (x, y) {
            return this.handler.findHover(x, y);
        };
        ZRender.prototype.on = function (eventName, eventHandler, context) {
            this.handler.on(eventName, eventHandler, context);
            return this;
        };
        ZRender.prototype.off = function (eventName, eventHandler) {
            this.handler.off(eventName, eventHandler);
        };
        ZRender.prototype.trigger = function (eventName, event) {
            this.handler.trigger(eventName, event);
        };
        ZRender.prototype.clear = function () {
            var roots = this.storage.getRoots();
            for (var i = 0; i < roots.length; i++) {
                if (roots[i] instanceof Group) {
                    roots[i].removeSelfFromZr(this);
                }
            }
            this.storage.delAllRoots();
            this.painter.clear();
        };
        ZRender.prototype.dispose = function () {
            this.animation.stop();
            this.clear();
            this.storage.dispose();
            this.painter.dispose();
            this.handler.dispose();
            this.animation =
                this.storage =
                    this.painter =
                        this.handler = null;
            delInstance(this.id);
        };
        return ZRender;
    }());
    function init(dom, opts) {
        var zr = new ZRender(guid(), dom, opts);
        instances[zr.id] = zr;
        return zr;
    }
    function dispose(zr) {
        zr.dispose();
    }
    function disposeAll() {
        for (var key in instances) {
            if (instances.hasOwnProperty(key)) {
                instances[key].dispose();
            }
        }
        instances = {};
    }
    function getInstance(id) {
        return instances[id];
    }
    function registerPainter(name, Ctor) {
        painterCtors[name] = Ctor;
    }
    var version = '5.4.1-dev.20221104';

    var zrender = /*#__PURE__*/Object.freeze({
        __proto__: null,
        init: init,
        dispose: dispose,
        disposeAll: disposeAll,
        getInstance: getInstance,
        registerPainter: registerPainter,
        version: version
    });

    var RADIAN_EPSILON = 1e-4; // Although chrome already enlarge this number to 100 for `toFixed`, but
    // we sill follow the spec for compatibility.

    var ROUND_SUPPORTED_PRECISION_MAX = 20;

    function _trim(str) {
      return str.replace(/^\s+|\s+$/g, '');
    }
    /**
     * Linear mapping a value from domain to range
     * @param  val
     * @param  domain Domain extent domain[0] can be bigger than domain[1]
     * @param  range  Range extent range[0] can be bigger than range[1]
     * @param  clamp Default to be false
     */


    function linearMap(val, domain, range, clamp) {
      var d0 = domain[0];
      var d1 = domain[1];
      var r0 = range[0];
      var r1 = range[1];
      var subDomain = d1 - d0;
      var subRange = r1 - r0;

      if (subDomain === 0) {
        return subRange === 0 ? r0 : (r0 + r1) / 2;
      } // Avoid accuracy problem in edge, such as
      // 146.39 - 62.83 === 83.55999999999999.
      // See echarts/test/ut/spec/util/number.js#linearMap#accuracyError
      // It is a little verbose for efficiency considering this method
      // is a hotspot.


      if (clamp) {
        if (subDomain > 0) {
          if (val <= d0) {
            return r0;
          } else if (val >= d1) {
            return r1;
          }
        } else {
          if (val >= d0) {
            return r0;
          } else if (val <= d1) {
            return r1;
          }
        }
      } else {
        if (val === d0) {
          return r0;
        }

        if (val === d1) {
          return r1;
        }
      }

      return (val - d0) / subDomain * subRange + r0;
    }
    /**
     * Convert a percent string to absolute number.
     * Returns NaN if percent is not a valid string or number
     */

    function parsePercent$1(percent, all) {
      switch (percent) {
        case 'center':
        case 'middle':
          percent = '50%';
          break;

        case 'left':
        case 'top':
          percent = '0%';
          break;

        case 'right':
        case 'bottom':
          percent = '100%';
          break;
      }

      if (isString(percent)) {
        if (_trim(percent).match(/%$/)) {
          return parseFloat(percent) / 100 * all;
        }

        return parseFloat(percent);
      }

      return percent == null ? NaN : +percent;
    }
    function round(x, precision, returnStr) {
      if (precision == null) {
        precision = 10;
      } // Avoid range error


      precision = Math.min(Math.max(0, precision), ROUND_SUPPORTED_PRECISION_MAX); // PENDING: 1.005.toFixed(2) is '1.00' rather than '1.01'

      x = (+x).toFixed(precision);
      return returnStr ? x : +x;
    }
    /**
     * Inplacd asc sort arr.
     * The input arr will be modified.
     */

    function asc(arr) {
      arr.sort(function (a, b) {
        return a - b;
      });
      return arr;
    }
    /**
     * Get precision.
     */

    function getPrecision(val) {
      val = +val;

      if (isNaN(val)) {
        return 0;
      } // It is much faster than methods converting number to string as follows
      //      let tmp = val.toString();
      //      return tmp.length - 1 - tmp.indexOf('.');
      // especially when precision is low
      // Notice:
      // (1) If the loop count is over about 20, it is slower than `getPrecisionSafe`.
      //     (see https://jsbench.me/2vkpcekkvw/1)
      // (2) If the val is less than for example 1e-15, the result may be incorrect.
      //     (see test/ut/spec/util/number.test.ts `getPrecision_equal_random`)


      if (val > 1e-14) {
        var e = 1;

        for (var i = 0; i < 15; i++, e *= 10) {
          if (Math.round(val * e) / e === val) {
            return i;
          }
        }
      }

      return getPrecisionSafe(val);
    }
    /**
     * Get precision with slow but safe method
     */

    function getPrecisionSafe(val) {
      // toLowerCase for: '3.4E-12'
      var str = val.toString().toLowerCase(); // Consider scientific notation: '3.4e-12' '3.4e+12'

      var eIndex = str.indexOf('e');
      var exp = eIndex > 0 ? +str.slice(eIndex + 1) : 0;
      var significandPartLen = eIndex > 0 ? eIndex : str.length;
      var dotIndex = str.indexOf('.');
      var decimalPartLen = dotIndex < 0 ? 0 : significandPartLen - 1 - dotIndex;
      return Math.max(0, decimalPartLen - exp);
    }
    /**
     * Minimal dicernible data precisioin according to a single pixel.
     */

    function getPixelPrecision(dataExtent, pixelExtent) {
      var log = Math.log;
      var LN10 = Math.LN10;
      var dataQuantity = Math.floor(log(dataExtent[1] - dataExtent[0]) / LN10);
      var sizeQuantity = Math.round(log(Math.abs(pixelExtent[1] - pixelExtent[0])) / LN10); // toFixed() digits argument must be between 0 and 20.

      var precision = Math.min(Math.max(-dataQuantity + sizeQuantity, 0), 20);
      return !isFinite(precision) ? 20 : precision;
    }
    /**
     * Get a data of given precision, assuring the sum of percentages
     * in valueList is 1.
     * The largest remainder method is used.
     * https://en.wikipedia.org/wiki/Largest_remainder_method
     *
     * @param valueList a list of all data
     * @param idx index of the data to be processed in valueList
     * @param precision integer number showing digits of precision
     * @return percent ranging from 0 to 100
     */

    function getPercentWithPrecision(valueList, idx, precision) {
      if (!valueList[idx]) {
        return 0;
      }

      var seats = getPercentSeats(valueList, precision);
      return seats[idx] || 0;
    }
    /**
     * Get a data of given precision, assuring the sum of percentages
     * in valueList is 1.
     * The largest remainder method is used.
     * https://en.wikipedia.org/wiki/Largest_remainder_method
     *
     * @param valueList a list of all data
     * @param precision integer number showing digits of precision
     * @return {Array<number>}
     */

    function getPercentSeats(valueList, precision) {
      var sum = reduce(valueList, function (acc, val) {
        return acc + (isNaN(val) ? 0 : val);
      }, 0);

      if (sum === 0) {
        return [];
      }

      var digits = Math.pow(10, precision);
      var votesPerQuota = map(valueList, function (val) {
        return (isNaN(val) ? 0 : val) / sum * digits * 100;
      });
      var targetSeats = digits * 100;
      var seats = map(votesPerQuota, function (votes) {
        // Assign automatic seats.
        return Math.floor(votes);
      });
      var currentSum = reduce(seats, function (acc, val) {
        return acc + val;
      }, 0);
      var remainder = map(votesPerQuota, function (votes, idx) {
        return votes - seats[idx];
      }); // Has remainding votes.

      while (currentSum < targetSeats) {
        // Find next largest remainder.
        var max = Number.NEGATIVE_INFINITY;
        var maxId = null;

        for (var i = 0, len = remainder.length; i < len; ++i) {
          if (remainder[i] > max) {
            max = remainder[i];
            maxId = i;
          }
        } // Add a vote to max remainder.


        ++seats[maxId];
        remainder[maxId] = 0;
        ++currentSum;
      }

      return map(seats, function (seat) {
        return seat / digits;
      });
    }
    /**
     * Solve the floating point adding problem like 0.1 + 0.2 === 0.30000000000000004
     * See <http://0.30000000000000004.com/>
     */

    function addSafe(val0, val1) {
      var maxPrecision = Math.max(getPrecision(val0), getPrecision(val1)); // const multiplier = Math.pow(10, maxPrecision);
      // return (Math.round(val0 * multiplier) + Math.round(val1 * multiplier)) / multiplier;

      var sum = val0 + val1; // // PENDING: support more?

      return maxPrecision > ROUND_SUPPORTED_PRECISION_MAX ? sum : round(sum, maxPrecision);
    } // Number.MAX_SAFE_INTEGER, ie do not support.

    var MAX_SAFE_INTEGER = 9007199254740991;
    /**
     * To 0 - 2 * PI, considering negative radian.
     */

    function remRadian(radian) {
      var pi2 = Math.PI * 2;
      return (radian % pi2 + pi2) % pi2;
    }
    /**
     * @param {type} radian
     * @return {boolean}
     */

    function isRadianAroundZero(val) {
      return val > -RADIAN_EPSILON && val < RADIAN_EPSILON;
    } // eslint-disable-next-line

    var TIME_REG = /^(?:(\d{4})(?:[-\/](\d{1,2})(?:[-\/](\d{1,2})(?:[T ](\d{1,2})(?::(\d{1,2})(?::(\d{1,2})(?:[.,](\d+))?)?)?(Z|[\+\-]\d\d:?\d\d)?)?)?)?)?$/; // jshint ignore:line

    /**
     * @param value valid type: number | string | Date, otherwise return `new Date(NaN)`
     *   These values can be accepted:
     *   + An instance of Date, represent a time in its own time zone.
     *   + Or string in a subset of ISO 8601, only including:
     *     + only year, month, date: '2012-03', '2012-03-01', '2012-03-01 05', '2012-03-01 05:06',
     *     + separated with T or space: '2012-03-01T12:22:33.123', '2012-03-01 12:22:33.123',
     *     + time zone: '2012-03-01T12:22:33Z', '2012-03-01T12:22:33+8000', '2012-03-01T12:22:33-05:00',
     *     all of which will be treated as local time if time zone is not specified
     *     (see <https://momentjs.com/>).
     *   + Or other string format, including (all of which will be treated as local time):
     *     '2012', '2012-3-1', '2012/3/1', '2012/03/01',
     *     '2009/6/12 2:00', '2009/6/12 2:05:08', '2009/6/12 2:05:08.123'
     *   + a timestamp, which represent a time in UTC.
     * @return date Never be null/undefined. If invalid, return `new Date(NaN)`.
     */

    function parseDate(value) {
      if (value instanceof Date) {
        return value;
      } else if (isString(value)) {
        // Different browsers parse date in different way, so we parse it manually.
        // Some other issues:
        // new Date('1970-01-01') is UTC,
        // new Date('1970/01/01') and new Date('1970-1-01') is local.
        // See issue #3623
        var match = TIME_REG.exec(value);

        if (!match) {
          // return Invalid Date.
          return new Date(NaN);
        } // Use local time when no timezone offset is specified.


        if (!match[8]) {
          // match[n] can only be string or undefined.
          // But take care of '12' + 1 => '121'.
          return new Date(+match[1], +(match[2] || 1) - 1, +match[3] || 1, +match[4] || 0, +(match[5] || 0), +match[6] || 0, match[7] ? +match[7].substring(0, 3) : 0);
        } // Timezoneoffset of Javascript Date has considered DST (Daylight Saving Time,
        // https://tc39.github.io/ecma262/#sec-daylight-saving-time-adjustment).
        // For example, system timezone is set as "Time Zone: America/Toronto",
        // then these code will get different result:
        // `new Date(1478411999999).getTimezoneOffset();  // get 240`
        // `new Date(1478412000000).getTimezoneOffset();  // get 300`
        // So we should not use `new Date`, but use `Date.UTC`.
        else {
            var hour = +match[4] || 0;

            if (match[8].toUpperCase() !== 'Z') {
              hour -= +match[8].slice(0, 3);
            }

            return new Date(Date.UTC(+match[1], +(match[2] || 1) - 1, +match[3] || 1, hour, +(match[5] || 0), +match[6] || 0, match[7] ? +match[7].substring(0, 3) : 0));
          }
      } else if (value == null) {
        return new Date(NaN);
      }

      return new Date(Math.round(value));
    }
    /**
     * Quantity of a number. e.g. 0.1, 1, 10, 100
     *
     * @param val
     * @return
     */

    function quantity(val) {
      return Math.pow(10, quantityExponent(val));
    }
    /**
     * Exponent of the quantity of a number
     * e.g., 1234 equals to 1.234*10^3, so quantityExponent(1234) is 3
     *
     * @param val non-negative value
     * @return
     */

    function quantityExponent(val) {
      if (val === 0) {
        return 0;
      }

      var exp = Math.floor(Math.log(val) / Math.LN10);
      /**
       * exp is expected to be the rounded-down result of the base-10 log of val.
       * But due to the precision loss with Math.log(val), we need to restore it
       * using 10^exp to make sure we can get val back from exp. #11249
       */

      if (val / Math.pow(10, exp) >= 10) {
        exp++;
      }

      return exp;
    }
    /**
     * find a “nice” number approximately equal to x. Round the number if round = true,
     * take ceiling if round = false. The primary observation is that the “nicest”
     * numbers in decimal are 1, 2, and 5, and all power-of-ten multiples of these numbers.
     *
     * See "Nice Numbers for Graph Labels" of Graphic Gems.
     *
     * @param  val Non-negative value.
     * @param  round
     * @return Niced number
     */

    function nice(val, round) {
      var exponent = quantityExponent(val);
      var exp10 = Math.pow(10, exponent);
      var f = val / exp10; // 1 <= f < 10

      var nf;

      if (round) {
        if (f < 1.5) {
          nf = 1;
        } else if (f < 2.5) {
          nf = 2;
        } else if (f < 4) {
          nf = 3;
        } else if (f < 7) {
          nf = 5;
        } else {
          nf = 10;
        }
      } else {
        if (f < 1) {
          nf = 1;
        } else if (f < 2) {
          nf = 2;
        } else if (f < 3) {
          nf = 3;
        } else if (f < 5) {
          nf = 5;
        } else {
          nf = 10;
        }
      }

      val = nf * exp10; // Fix 3 * 0.1 === 0.30000000000000004 issue (see IEEE 754).
      // 20 is the uppper bound of toFixed.

      return exponent >= -20 ? +val.toFixed(exponent < 0 ? -exponent : 0) : val;
    }
    /**
     * This code was copied from "d3.js"
     * <https://github.com/d3/d3/blob/9cc9a875e636a1dcf36cc1e07bdf77e1ad6e2c74/src/arrays/quantile.js>.
     * See the license statement at the head of this file.
     * @param ascArr
     */

    function quantile(ascArr, p) {
      var H = (ascArr.length - 1) * p + 1;
      var h = Math.floor(H);
      var v = +ascArr[h - 1];
      var e = H - h;
      return e ? v + e * (ascArr[h] - v) : v;
    }
    /**
     * Order intervals asc, and split them when overlap.
     * expect(numberUtil.reformIntervals([
     *     {interval: [18, 62], close: [1, 1]},
     *     {interval: [-Infinity, -70], close: [0, 0]},
     *     {interval: [-70, -26], close: [1, 1]},
     *     {interval: [-26, 18], close: [1, 1]},
     *     {interval: [62, 150], close: [1, 1]},
     *     {interval: [106, 150], close: [1, 1]},
     *     {interval: [150, Infinity], close: [0, 0]}
     * ])).toEqual([
     *     {interval: [-Infinity, -70], close: [0, 0]},
     *     {interval: [-70, -26], close: [1, 1]},
     *     {interval: [-26, 18], close: [0, 1]},
     *     {interval: [18, 62], close: [0, 1]},
     *     {interval: [62, 150], close: [0, 1]},
     *     {interval: [150, Infinity], close: [0, 0]}
     * ]);
     * @param list, where `close` mean open or close
     *        of the interval, and Infinity can be used.
     * @return The origin list, which has been reformed.
     */

    function reformIntervals(list) {
      list.sort(function (a, b) {
        return littleThan(a, b, 0) ? -1 : 1;
      });
      var curr = -Infinity;
      var currClose = 1;

      for (var i = 0; i < list.length;) {
        var interval = list[i].interval;
        var close_1 = list[i].close;

        for (var lg = 0; lg < 2; lg++) {
          if (interval[lg] <= curr) {
            interval[lg] = curr;
            close_1[lg] = !lg ? 1 - currClose : 1;
          }

          curr = interval[lg];
          currClose = close_1[lg];
        }

        if (interval[0] === interval[1] && close_1[0] * close_1[1] !== 1) {
          list.splice(i, 1);
        } else {
          i++;
        }
      }

      return list;

      function littleThan(a, b, lg) {
        return a.interval[lg] < b.interval[lg] || a.interval[lg] === b.interval[lg] && (a.close[lg] - b.close[lg] === (!lg ? 1 : -1) || !lg && littleThan(a, b, 1));
      }
    }
    /**
     * [Numeric is defined as]:
     *     `parseFloat(val) == val`
     * For example:
     * numeric:
     *     typeof number except NaN, '-123', '123', '2e3', '-2e3', '011', 'Infinity', Infinity,
     *     and they rounded by white-spaces or line-terminal like ' -123 \n ' (see es spec)
     * not-numeric:
     *     null, undefined, [], {}, true, false, 'NaN', NaN, '123ab',
     *     empty string, string with only white-spaces or line-terminal (see es spec),
     *     0x12, '0x12', '-0x12', 012, '012', '-012',
     *     non-string, ...
     *
     * @test See full test cases in `test/ut/spec/util/number.js`.
     * @return Must be a typeof number. If not numeric, return NaN.
     */

    function numericToNumber(val) {
      var valFloat = parseFloat(val);
      return valFloat == val // eslint-disable-line eqeqeq
      && (valFloat !== 0 || !isString(val) || val.indexOf('x') <= 0) // For case ' 0x0 '.
      ? valFloat : NaN;
    }
    /**
     * Definition of "numeric": see `numericToNumber`.
     */

    function isNumeric(val) {
      return !isNaN(numericToNumber(val));
    }
    /**
     * Use random base to prevent users hard code depending on
     * this auto generated marker id.
     * @return An positive integer.
     */

    function getRandomIdBase() {
      return Math.round(Math.random() * 9);
    }
    /**
     * Get the greatest common divisor.
     *
     * @param {number} a one number
     * @param {number} b the other number
     */

    function getGreatestCommonDividor(a, b) {
      if (b === 0) {
        return a;
      }

      return getGreatestCommonDividor(b, a % b);
    }
    /**
     * Get the least common multiple.
     *
     * @param {number} a one number
     * @param {number} b the other number
     */

    function getLeastCommonMultiple(a, b) {
      if (a == null) {
        return b;
      }

      if (b == null) {
        return a;
      }

      return a * b / getGreatestCommonDividor(a, b);
    }

    var ECHARTS_PREFIX = '[ECharts] ';
    var storedLogs = {};
    var hasConsole = typeof console !== 'undefined' // eslint-disable-next-line
    && console.warn && console.log;

    function outputLog(type, str, onlyOnce) {
      if (hasConsole) {
        if (onlyOnce) {
          if (storedLogs[str]) {
            return;
          }

          storedLogs[str] = true;
        } // eslint-disable-next-line


        console[type](ECHARTS_PREFIX + str);
      }
    }

    function log(str, onlyOnce) {
      outputLog('log', str, onlyOnce);
    }
    function warn(str, onlyOnce) {
      outputLog('warn', str, onlyOnce);
    }
    function error(str, onlyOnce) {
      outputLog('error', str, onlyOnce);
    }
    function deprecateLog(str) {
      if ("development" !== 'production') {
        // Not display duplicate message.
        outputLog('warn', 'DEPRECATED: ' + str, true);
      }
    }
    function deprecateReplaceLog(oldOpt, newOpt, scope) {
      if ("development" !== 'production') {
        deprecateLog((scope ? "[" + scope + "]" : '') + (oldOpt + " is deprecated, use " + newOpt + " instead."));
      }
    }
    /**
     * If in __DEV__ environment, get console printable message for users hint.
     * Parameters are separated by ' '.
     * @usage
     * makePrintable('This is an error on', someVar, someObj);
     *
     * @param hintInfo anything about the current execution context to hint users.
     * @throws Error
     */

    function makePrintable() {
      var hintInfo = [];

      for (var _i = 0; _i < arguments.length; _i++) {
        hintInfo[_i] = arguments[_i];
      }

      var msg = '';

      if ("development" !== 'production') {
        // Fuzzy stringify for print.
        // This code only exist in dev environment.
        var makePrintableStringIfPossible_1 = function (val) {
          return val === void 0 ? 'undefined' : val === Infinity ? 'Infinity' : val === -Infinity ? '-Infinity' : eqNaN(val) ? 'NaN' : val instanceof Date ? 'Date(' + val.toISOString() + ')' : isFunction(val) ? 'function () { ... }' : isRegExp(val) ? val + '' : null;
        };

        msg = map(hintInfo, function (arg) {
          if (isString(arg)) {
            // Print without quotation mark for some statement.
            return arg;
          } else {
            var printableStr = makePrintableStringIfPossible_1(arg);

            if (printableStr != null) {
              return printableStr;
            } else if (typeof JSON !== 'undefined' && JSON.stringify) {
              try {
                return JSON.stringify(arg, function (n, val) {
                  var printableStr = makePrintableStringIfPossible_1(val);
                  return printableStr == null ? val : printableStr;
                }); // In most cases the info object is small, so do not line break.
              } catch (err) {
                return '?';
              }
            } else {
              return '?';
            }
          }
        }).join(' ');
      }

      return msg;
    }
    /**
     * @throws Error
     */

    function throwError(msg) {
      throw new Error(msg);
    }

    function interpolateNumber$1(p0, p1, percent) {
      return (p1 - p0) * percent + p0;
    }
    /**
     * Make the name displayable. But we should
     * make sure it is not duplicated with user
     * specified name, so use '\0';
     */


    var DUMMY_COMPONENT_NAME_PREFIX = 'series\0';
    var INTERNAL_COMPONENT_ID_PREFIX = '\0_ec_\0';
    /**
     * If value is not array, then translate it to array.
     * @param  {*} value
     * @return {Array} [value] or value
     */

    function normalizeToArray(value) {
      return value instanceof Array ? value : value == null ? [] : [value];
    }
    /**
     * Sync default option between normal and emphasis like `position` and `show`
     * In case some one will write code like
     *     label: {
     *          show: false,
     *          position: 'outside',
     *          fontSize: 18
     *     },
     *     emphasis: {
     *          label: { show: true }
     *     }
     */

    function defaultEmphasis(opt, key, subOpts) {
      // Caution: performance sensitive.
      if (opt) {
        opt[key] = opt[key] || {};
        opt.emphasis = opt.emphasis || {};
        opt.emphasis[key] = opt.emphasis[key] || {}; // Default emphasis option from normal

        for (var i = 0, len = subOpts.length; i < len; i++) {
          var subOptName = subOpts[i];

          if (!opt.emphasis[key].hasOwnProperty(subOptName) && opt[key].hasOwnProperty(subOptName)) {
            opt.emphasis[key][subOptName] = opt[key][subOptName];
          }
        }
      }
    }
    var TEXT_STYLE_OPTIONS = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'rich', 'tag', 'color', 'textBorderColor', 'textBorderWidth', 'width', 'height', 'lineHeight', 'align', 'verticalAlign', 'baseline', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY', 'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY', 'backgroundColor', 'borderColor', 'borderWidth', 'borderRadius', 'padding']; // modelUtil.LABEL_OPTIONS = modelUtil.TEXT_STYLE_OPTIONS.concat([
    //     'position', 'offset', 'rotate', 'origin', 'show', 'distance', 'formatter',
    //     'fontStyle', 'fontWeight', 'fontSize', 'fontFamily',
    //     // FIXME: deprecated, check and remove it.
    //     'textStyle'
    // ]);

    /**
     * The method does not ensure performance.
     * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
     * This helper method retrieves value from data.
     */

    function getDataItemValue(dataItem) {
      return isObject(dataItem) && !isArray(dataItem) && !(dataItem instanceof Date) ? dataItem.value : dataItem;
    }
    /**
     * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
     * This helper method determine if dataItem has extra option besides value
     */

    function isDataItemOption(dataItem) {
      return isObject(dataItem) && !(dataItem instanceof Array); // // markLine data can be array
      // && !(dataItem[0] && isObject(dataItem[0]) && !(dataItem[0] instanceof Array));
    }
    /**
     * Mapping to existings for merge.
     *
     * Mode "normalMege":
     *     The mapping result (merge result) will keep the order of the existing
     *     component, rather than the order of new option. Because we should ensure
     *     some specified index reference (like xAxisIndex) keep work.
     *     And in most cases, "merge option" is used to update partial option but not
     *     be expected to change the order.
     *
     * Mode "replaceMege":
     *     (1) Only the id mapped components will be merged.
     *     (2) Other existing components (except internal components) will be removed.
     *     (3) Other new options will be used to create new component.
     *     (4) The index of the existing components will not be modified.
     *     That means their might be "hole" after the removal.
     *     The new components are created first at those available index.
     *
     * Mode "replaceAll":
     *     This mode try to support that reproduce an echarts instance from another
     *     echarts instance (via `getOption`) in some simple cases.
     *     In this scenario, the `result` index are exactly the consistent with the `newCmptOptions`,
     *     which ensures the component index referring (like `xAxisIndex: ?`) corrent. That is,
     *     the "hole" in `newCmptOptions` will also be kept.
     *     On the contrary, other modes try best to eliminate holes.
     *     PENDING: This is an experimental mode yet.
     *
     * @return See the comment of <MappingResult>.
     */

    function mappingToExists(existings, newCmptOptions, mode) {
      var isNormalMergeMode = mode === 'normalMerge';
      var isReplaceMergeMode = mode === 'replaceMerge';
      var isReplaceAllMode = mode === 'replaceAll';
      existings = existings || [];
      newCmptOptions = (newCmptOptions || []).slice();
      var existingIdIdxMap = createHashMap(); // Validate id and name on user input option.

      each(newCmptOptions, function (cmptOption, index) {
        if (!isObject(cmptOption)) {
          newCmptOptions[index] = null;
          return;
        }

        if ("development" !== 'production') {
          // There is some legacy case that name is set as `false`.
          // But should work normally rather than throw error.
          if (cmptOption.id != null && !isValidIdOrName(cmptOption.id)) {
            warnInvalidateIdOrName(cmptOption.id);
          }

          if (cmptOption.name != null && !isValidIdOrName(cmptOption.name)) {
            warnInvalidateIdOrName(cmptOption.name);
          }
        }
      });
      var result = prepareResult(existings, existingIdIdxMap, mode);

      if (isNormalMergeMode || isReplaceMergeMode) {
        mappingById(result, existings, existingIdIdxMap, newCmptOptions);
      }

      if (isNormalMergeMode) {
        mappingByName(result, newCmptOptions);
      }

      if (isNormalMergeMode || isReplaceMergeMode) {
        mappingByIndex(result, newCmptOptions, isReplaceMergeMode);
      } else if (isReplaceAllMode) {
        mappingInReplaceAllMode(result, newCmptOptions);
      }

      makeIdAndName(result); // The array `result` MUST NOT contain elided items, otherwise the
      // forEach will omit those items and result in incorrect result.

      return result;
    }

    function prepareResult(existings, existingIdIdxMap, mode) {
      var result = [];

      if (mode === 'replaceAll') {
        return result;
      } // Do not use native `map` to in case that the array `existings`
      // contains elided items, which will be omitted.


      for (var index = 0; index < existings.length; index++) {
        var existing = existings[index]; // Because of replaceMerge, `existing` may be null/undefined.

        if (existing && existing.id != null) {
          existingIdIdxMap.set(existing.id, index);
        } // For non-internal-componnets:
        //     Mode "normalMerge": all existings kept.
        //     Mode "replaceMerge": all existing removed unless mapped by id.
        // For internal-components:
        //     go with "replaceMerge" approach in both mode.


        result.push({
          existing: mode === 'replaceMerge' || isComponentIdInternal(existing) ? null : existing,
          newOption: null,
          keyInfo: null,
          brandNew: null
        });
      }

      return result;
    }

    function mappingById(result, existings, existingIdIdxMap, newCmptOptions) {
      // Mapping by id if specified.
      each(newCmptOptions, function (cmptOption, index) {
        if (!cmptOption || cmptOption.id == null) {
          return;
        }

        var optionId = makeComparableKey(cmptOption.id);
        var existingIdx = existingIdIdxMap.get(optionId);

        if (existingIdx != null) {
          var resultItem = result[existingIdx];
          assert(!resultItem.newOption, 'Duplicated option on id "' + optionId + '".');
          resultItem.newOption = cmptOption; // In both mode, if id matched, new option will be merged to
          // the existings rather than creating new component model.

          resultItem.existing = existings[existingIdx];
          newCmptOptions[index] = null;
        }
      });
    }

    function mappingByName(result, newCmptOptions) {
      // Mapping by name if specified.
      each(newCmptOptions, function (cmptOption, index) {
        if (!cmptOption || cmptOption.name == null) {
          return;
        }

        for (var i = 0; i < result.length; i++) {
          var existing = result[i].existing;

          if (!result[i].newOption // Consider name: two map to one.
          // Can not match when both ids existing but different.
          && existing && (existing.id == null || cmptOption.id == null) && !isComponentIdInternal(cmptOption) && !isComponentIdInternal(existing) && keyExistAndEqual('name', existing, cmptOption)) {
            result[i].newOption = cmptOption;
            newCmptOptions[index] = null;
            return;
          }
        }
      });
    }

    function mappingByIndex(result, newCmptOptions, brandNew) {
      each(newCmptOptions, function (cmptOption) {
        if (!cmptOption) {
          return;
        } // Find the first place that not mapped by id and not internal component (consider the "hole").


        var resultItem;
        var nextIdx = 0;

        while ( // Be `!resultItem` only when `nextIdx >= result.length`.
        (resultItem = result[nextIdx]) && ( // (1) Existing models that already have id should be able to mapped to. Because
        // after mapping performed, model will always be assigned with an id if user not given.
        // After that all models have id.
        // (2) If new option has id, it can only set to a hole or append to the last. It should
        // not be merged to the existings with different id. Because id should not be overwritten.
        // (3) Name can be overwritten, because axis use name as 'show label text'.
        resultItem.newOption || isComponentIdInternal(resultItem.existing) || // In mode "replaceMerge", here no not-mapped-non-internal-existing.
        resultItem.existing && cmptOption.id != null && !keyExistAndEqual('id', cmptOption, resultItem.existing))) {
          nextIdx++;
        }

        if (resultItem) {
          resultItem.newOption = cmptOption;
          resultItem.brandNew = brandNew;
        } else {
          result.push({
            newOption: cmptOption,
            brandNew: brandNew,
            existing: null,
            keyInfo: null
          });
        }

        nextIdx++;
      });
    }

    function mappingInReplaceAllMode(result, newCmptOptions) {
      each(newCmptOptions, function (cmptOption) {
        // The feature "reproduce" requires "hole" will also reproduced
        // in case that component index referring are broken.
        result.push({
          newOption: cmptOption,
          brandNew: true,
          existing: null,
          keyInfo: null
        });
      });
    }
    /**
     * Make id and name for mapping result (result of mappingToExists)
     * into `keyInfo` field.
     */


    function makeIdAndName(mapResult) {
      // We use this id to hash component models and view instances
      // in echarts. id can be specified by user, or auto generated.
      // The id generation rule ensures new view instance are able
      // to mapped to old instance when setOption are called in
      // no-merge mode. So we generate model id by name and plus
      // type in view id.
      // name can be duplicated among components, which is convenient
      // to specify multi components (like series) by one name.
      // Ensure that each id is distinct.
      var idMap = createHashMap();
      each(mapResult, function (item) {
        var existing = item.existing;
        existing && idMap.set(existing.id, item);
      });
      each(mapResult, function (item) {
        var opt = item.newOption; // Force ensure id not duplicated.

        assert(!opt || opt.id == null || !idMap.get(opt.id) || idMap.get(opt.id) === item, 'id duplicates: ' + (opt && opt.id));
        opt && opt.id != null && idMap.set(opt.id, item);
        !item.keyInfo && (item.keyInfo = {});
      }); // Make name and id.

      each(mapResult, function (item, index) {
        var existing = item.existing;
        var opt = item.newOption;
        var keyInfo = item.keyInfo;

        if (!isObject(opt)) {
          return;
        } // Name can be overwritten. Consider case: axis.name = '20km'.
        // But id generated by name will not be changed, which affect
        // only in that case: setOption with 'not merge mode' and view
        // instance will be recreated, which can be accepted.


        keyInfo.name = opt.name != null ? makeComparableKey(opt.name) : existing ? existing.name // Avoid that different series has the same name,
        // because name may be used like in color pallet.
        : DUMMY_COMPONENT_NAME_PREFIX + index;

        if (existing) {
          keyInfo.id = makeComparableKey(existing.id);
        } else if (opt.id != null) {
          keyInfo.id = makeComparableKey(opt.id);
        } else {
          // Consider this situatoin:
          //  optionA: [{name: 'a'}, {name: 'a'}, {..}]
          //  optionB [{..}, {name: 'a'}, {name: 'a'}]
          // Series with the same name between optionA and optionB
          // should be mapped.
          var idNum = 0;

          do {
            keyInfo.id = '\0' + keyInfo.name + '\0' + idNum++;
          } while (idMap.get(keyInfo.id));
        }

        idMap.set(keyInfo.id, item);
      });
    }

    function keyExistAndEqual(attr, obj1, obj2) {
      var key1 = convertOptionIdName(obj1[attr], null);
      var key2 = convertOptionIdName(obj2[attr], null); // See `MappingExistingItem`. `id` and `name` trade string equals to number.

      return key1 != null && key2 != null && key1 === key2;
    }
    /**
     * @return return null if not exist.
     */


    function makeComparableKey(val) {
      if ("development" !== 'production') {
        if (val == null) {
          throw new Error();
        }
      }

      return convertOptionIdName(val, '');
    }

    function convertOptionIdName(idOrName, defaultValue) {
      if (idOrName == null) {
        return defaultValue;
      }

      return isString(idOrName) ? idOrName : isNumber(idOrName) || isStringSafe(idOrName) ? idOrName + '' : defaultValue;
    }

    function warnInvalidateIdOrName(idOrName) {
      if ("development" !== 'production') {
        warn('`' + idOrName + '` is invalid id or name. Must be a string or number.');
      }
    }

    function isValidIdOrName(idOrName) {
      return isStringSafe(idOrName) || isNumeric(idOrName);
    }

    function isNameSpecified(componentModel) {
      var name = componentModel.name; // Is specified when `indexOf` get -1 or > 0.

      return !!(name && name.indexOf(DUMMY_COMPONENT_NAME_PREFIX));
    }
    /**
     * @public
     * @param {Object} cmptOption
     * @return {boolean}
     */

    function isComponentIdInternal(cmptOption) {
      return cmptOption && cmptOption.id != null && makeComparableKey(cmptOption.id).indexOf(INTERNAL_COMPONENT_ID_PREFIX) === 0;
    }
    function makeInternalComponentId(idSuffix) {
      return INTERNAL_COMPONENT_ID_PREFIX + idSuffix;
    }
    function setComponentTypeToKeyInfo(mappingResult, mainType, componentModelCtor) {
      // Set mainType and complete subType.
      each(mappingResult, function (item) {
        var newOption = item.newOption;

        if (isObject(newOption)) {
          item.keyInfo.mainType = mainType;
          item.keyInfo.subType = determineSubType(mainType, newOption, item.existing, componentModelCtor);
        }
      });
    }

    function determineSubType(mainType, newCmptOption, existComponent, componentModelCtor) {
      var subType = newCmptOption.type ? newCmptOption.type : existComponent ? existComponent.subType // Use determineSubType only when there is no existComponent.
      : componentModelCtor.determineSubType(mainType, newCmptOption); // tooltip, markline, markpoint may always has no subType

      return subType;
    }
    /**
     * @param payload Contains dataIndex (means rawIndex) / dataIndexInside / name
     *                         each of which can be Array or primary type.
     * @return dataIndex If not found, return undefined/null.
     */

    function queryDataIndex(data, payload) {
      if (payload.dataIndexInside != null) {
        return payload.dataIndexInside;
      } else if (payload.dataIndex != null) {
        return isArray(payload.dataIndex) ? map(payload.dataIndex, function (value) {
          return data.indexOfRawIndex(value);
        }) : data.indexOfRawIndex(payload.dataIndex);
      } else if (payload.name != null) {
        return isArray(payload.name) ? map(payload.name, function (value) {
          return data.indexOfName(value);
        }) : data.indexOfName(payload.name);
      }
    }
    /**
     * Enable property storage to any host object.
     * Notice: Serialization is not supported.
     *
     * For example:
     * let inner = zrUitl.makeInner();
     *
     * function some1(hostObj) {
     *      inner(hostObj).someProperty = 1212;
     *      ...
     * }
     * function some2() {
     *      let fields = inner(this);
     *      fields.someProperty1 = 1212;
     *      fields.someProperty2 = 'xx';
     *      ...
     * }
     *
     * @return {Function}
     */

    function makeInner() {
      var key = '__ec_inner_' + innerUniqueIndex++;
      return function (hostObj) {
        return hostObj[key] || (hostObj[key] = {});
      };
    }
    var innerUniqueIndex = getRandomIdBase();
    /**
     * The same behavior as `component.getReferringComponents`.
     */

    function parseFinder(ecModel, finderInput, opt) {
      var _a = preParseFinder(finderInput, opt),
          mainTypeSpecified = _a.mainTypeSpecified,
          queryOptionMap = _a.queryOptionMap,
          others = _a.others;

      var result = others;
      var defaultMainType = opt ? opt.defaultMainType : null;

      if (!mainTypeSpecified && defaultMainType) {
        queryOptionMap.set(defaultMainType, {});
      }

      queryOptionMap.each(function (queryOption, mainType) {
        var queryResult = queryReferringComponents(ecModel, mainType, queryOption, {
          useDefault: defaultMainType === mainType,
          enableAll: opt && opt.enableAll != null ? opt.enableAll : true,
          enableNone: opt && opt.enableNone != null ? opt.enableNone : true
        });
        result[mainType + 'Models'] = queryResult.models;
        result[mainType + 'Model'] = queryResult.models[0];
      });
      return result;
    }
    function preParseFinder(finderInput, opt) {
      var finder;

      if (isString(finderInput)) {
        var obj = {};
        obj[finderInput + 'Index'] = 0;
        finder = obj;
      } else {
        finder = finderInput;
      }

      var queryOptionMap = createHashMap();
      var others = {};
      var mainTypeSpecified = false;
      each(finder, function (value, key) {
        // Exclude 'dataIndex' and other illgal keys.
        if (key === 'dataIndex' || key === 'dataIndexInside') {
          others[key] = value;
          return;
        }

        var parsedKey = key.match(/^(\w+)(Index|Id|Name)$/) || [];
        var mainType = parsedKey[1];
        var queryType = (parsedKey[2] || '').toLowerCase();

        if (!mainType || !queryType || opt && opt.includeMainTypes && indexOf(opt.includeMainTypes, mainType) < 0) {
          return;
        }

        mainTypeSpecified = mainTypeSpecified || !!mainType;
        var queryOption = queryOptionMap.get(mainType) || queryOptionMap.set(mainType, {});
        queryOption[queryType] = value;
      });
      return {
        mainTypeSpecified: mainTypeSpecified,
        queryOptionMap: queryOptionMap,
        others: others
      };
    }
    var SINGLE_REFERRING = {
      useDefault: true,
      enableAll: false,
      enableNone: false
    };
    var MULTIPLE_REFERRING = {
      useDefault: false,
      enableAll: true,
      enableNone: true
    };
    function queryReferringComponents(ecModel, mainType, userOption, opt) {
      opt = opt || SINGLE_REFERRING;
      var indexOption = userOption.index;
      var idOption = userOption.id;
      var nameOption = userOption.name;
      var result = {
        models: null,
        specified: indexOption != null || idOption != null || nameOption != null
      };

      if (!result.specified) {
        // Use the first as default if `useDefault`.
        var firstCmpt = void 0;
        result.models = opt.useDefault && (firstCmpt = ecModel.getComponent(mainType)) ? [firstCmpt] : [];
        return result;
      }

      if (indexOption === 'none' || indexOption === false) {
        assert(opt.enableNone, '`"none"` or `false` is not a valid value on index option.');
        result.models = [];
        return result;
      } // `queryComponents` will return all components if
      // both all of index/id/name are null/undefined.


      if (indexOption === 'all') {
        assert(opt.enableAll, '`"all"` is not a valid value on index option.');
        indexOption = idOption = nameOption = null;
      }

      result.models = ecModel.queryComponents({
        mainType: mainType,
        index: indexOption,
        id: idOption,
        name: nameOption
      });
      return result;
    }
    function setAttribute(dom, key, value) {
      dom.setAttribute ? dom.setAttribute(key, value) : dom[key] = value;
    }
    function getAttribute(dom, key) {
      return dom.getAttribute ? dom.getAttribute(key) : dom[key];
    }
    function getTooltipRenderMode(renderModeOption) {
      if (renderModeOption === 'auto') {
        // Using html when `document` exists, use richText otherwise
        return env.domSupported ? 'html' : 'richText';
      } else {
        return renderModeOption || 'html';
      }
    }
    /**
     * Interpolate raw values of a series with percent
     *
     * @param data         data
     * @param labelModel   label model of the text element
     * @param sourceValue  start value. May be null/undefined when init.
     * @param targetValue  end value
     * @param percent      0~1 percentage; 0 uses start value while 1 uses end value
     * @return             interpolated values
     *                     If `sourceValue` and `targetValue` are `number`, return `number`.
     *                     If `sourceValue` and `targetValue` are `string`, return `string`.
     *                     If `sourceValue` and `targetValue` are `(string | number)[]`, return `(string | number)[]`.
     *                     Other cases do not supported.
     */

    function interpolateRawValues(data, precision, sourceValue, targetValue, percent) {
      var isAutoPrecision = precision == null || precision === 'auto';

      if (targetValue == null) {
        return targetValue;
      }

      if (isNumber(targetValue)) {
        var value = interpolateNumber$1(sourceValue || 0, targetValue, percent);
        return round(value, isAutoPrecision ? Math.max(getPrecision(sourceValue || 0), getPrecision(targetValue)) : precision);
      } else if (isString(targetValue)) {
        return percent < 1 ? sourceValue : targetValue;
      } else {
        var interpolated = [];
        var leftArr = sourceValue;
        var rightArr = targetValue;
        var length_1 = Math.max(leftArr ? leftArr.length : 0, rightArr.length);

        for (var i = 0; i < length_1; ++i) {
          var info = data.getDimensionInfo(i); // Don't interpolate ordinal dims

          if (info && info.type === 'ordinal') {
            // In init, there is no `sourceValue`, but should better not to get undefined result.
            interpolated[i] = (percent < 1 && leftArr ? leftArr : rightArr)[i];
          } else {
            var leftVal = leftArr && leftArr[i] ? leftArr[i] : 0;
            var rightVal = rightArr[i];
            var value = interpolateNumber$1(leftVal, rightVal, percent);
            interpolated[i] = round(value, isAutoPrecision ? Math.max(getPrecision(leftVal), getPrecision(rightVal)) : precision);
          }
        }

        return interpolated;
      }
    }

    var TYPE_DELIMITER = '.';
    var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___';
    var IS_EXTENDED_CLASS = '___EC__EXTENDED_CLASS___';
    /**
     * Notice, parseClassType('') should returns {main: '', sub: ''}
     * @public
     */

    function parseClassType(componentType) {
      var ret = {
        main: '',
        sub: ''
      };

      if (componentType) {
        var typeArr = componentType.split(TYPE_DELIMITER);
        ret.main = typeArr[0] || '';
        ret.sub = typeArr[1] || '';
      }

      return ret;
    }
    /**
     * @public
     */

    function checkClassType(componentType) {
      assert(/^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(componentType), 'componentType "' + componentType + '" illegal');
    }

    function isExtendedClass(clz) {
      return !!(clz && clz[IS_EXTENDED_CLASS]);
    }
    /**
     * Implements `ExtendableConstructor` for `rootClz`.
     *
     * @usage
     * ```ts
     * class Xxx {}
     * type XxxConstructor = typeof Xxx & ExtendableConstructor
     * enableClassExtend(Xxx as XxxConstructor);
     * ```
     */

    function enableClassExtend(rootClz, mandatoryMethods) {
      rootClz.$constructor = rootClz; // FIXME: not necessary?

      rootClz.extend = function (proto) {
        if ("development" !== 'production') {
          each(mandatoryMethods, function (method) {
            if (!proto[method]) {
              console.warn('Method `' + method + '` should be implemented' + (proto.type ? ' in ' + proto.type : '') + '.');
            }
          });
        }

        var superClass = this;
        var ExtendedClass;

        if (isESClass(superClass)) {
          ExtendedClass =
          /** @class */
          function (_super) {
            __extends(class_1, _super);

            function class_1() {
              return _super.apply(this, arguments) || this;
            }

            return class_1;
          }(superClass);
        } else {
          // For backward compat, we both support ts class inheritance and this
          // "extend" approach.
          // The constructor should keep the same behavior as ts class inheritance:
          // If this constructor/$constructor is not declared, auto invoke the super
          // constructor.
          // If this constructor/$constructor is declared, it is responsible for
          // calling the super constructor.
          ExtendedClass = function () {
            (proto.$constructor || superClass).apply(this, arguments);
          };

          inherits(ExtendedClass, this);
        }

        extend(ExtendedClass.prototype, proto);
        ExtendedClass[IS_EXTENDED_CLASS] = true;
        ExtendedClass.extend = this.extend;
        ExtendedClass.superCall = superCall;
        ExtendedClass.superApply = superApply;
        ExtendedClass.superClass = superClass;
        return ExtendedClass;
      };
    }

    function isESClass(fn) {
      return isFunction(fn) && /^class\s/.test(Function.prototype.toString.call(fn));
    }
    /**
     * A work around to both support ts extend and this extend mechanism.
     * on sub-class.
     * @usage
     * ```ts
     * class Component { ... }
     * classUtil.enableClassExtend(Component);
     * classUtil.enableClassManagement(Component, {registerWhenExtend: true});
     *
     * class Series extends Component { ... }
     * // Without calling `markExtend`, `registerWhenExtend` will not work.
     * Component.markExtend(Series);
     * ```
     */


    function mountExtend(SubClz, SupperClz) {
      SubClz.extend = SupperClz.extend;
    } // A random offset.

    var classBase = Math.round(Math.random() * 10);
    /**
     * Implements `CheckableConstructor` for `target`.
     * Can not use instanceof, consider different scope by
     * cross domain or es module import in ec extensions.
     * Mount a method "isInstance()" to Clz.
     *
     * @usage
     * ```ts
     * class Xxx {}
     * type XxxConstructor = typeof Xxx & CheckableConstructor;
     * enableClassCheck(Xxx as XxxConstructor)
     * ```
     */

    function enableClassCheck(target) {
      var classAttr = ['__\0is_clz', classBase++].join('_');
      target.prototype[classAttr] = true;

      if ("development" !== 'production') {
        assert(!target.isInstance, 'The method "is" can not be defined.');
      }

      target.isInstance = function (obj) {
        return !!(obj && obj[classAttr]);
      };
    } // superCall should have class info, which can not be fetched from 'this'.
    // Consider this case:
    // class A has method f,
    // class B inherits class A, overrides method f, f call superApply('f'),
    // class C inherits class B, does not override method f,
    // then when method of class C is called, dead loop occurred.

    function superCall(context, methodName) {
      var args = [];

      for (var _i = 2; _i < arguments.length; _i++) {
        args[_i - 2] = arguments[_i];
      }

      return this.superClass.prototype[methodName].apply(context, args);
    }

    function superApply(context, methodName, args) {
      return this.superClass.prototype[methodName].apply(context, args);
    }
    /**
     * Implements `ClassManager` for `target`
     *
     * @usage
     * ```ts
     * class Xxx {}
     * type XxxConstructor = typeof Xxx & ClassManager
     * enableClassManagement(Xxx as XxxConstructor);
     * ```
     */


    function enableClassManagement(target) {
      /**
       * Component model classes
       * key: componentType,
       * value:
       *     componentClass, when componentType is 'a'
       *     or Object.<subKey, componentClass>, when componentType is 'a.b'
       */
      var storage = {};

      target.registerClass = function (clz) {
        // `type` should not be a "instance member".
        // If using TS class, should better declared as `static type = 'series.pie'`.
        // otherwise users have to mount `type` on prototype manually.
        // For backward compat and enable instance visit type via `this.type`,
        // we still support fetch `type` from prototype.
        var componentFullType = clz.type || clz.prototype.type;

        if (componentFullType) {
          checkClassType(componentFullType); // If only static type declared, we assign it to prototype mandatorily.

          clz.prototype.type = componentFullType;
          var componentTypeInfo = parseClassType(componentFullType);

          if (!componentTypeInfo.sub) {
            if ("development" !== 'production') {
              if (storage[componentTypeInfo.main]) {
                console.warn(componentTypeInfo.main + ' exists.');
              }
            }

            storage[componentTypeInfo.main] = clz;
          } else if (componentTypeInfo.sub !== IS_CONTAINER) {
            var container = makeContainer(componentTypeInfo);
            container[componentTypeInfo.sub] = clz;
          }
        }

        return clz;
      };

      target.getClass = function (mainType, subType, throwWhenNotFound) {
        var clz = storage[mainType];

        if (clz && clz[IS_CONTAINER]) {
          clz = subType ? clz[subType] : null;
        }

        if (throwWhenNotFound && !clz) {
          throw new Error(!subType ? mainType + '.' + 'type should be specified.' : 'Component ' + mainType + '.' + (subType || '') + ' is used but not imported.');
        }

        return clz;
      };

      target.getClassesByMainType = function (componentType) {
        var componentTypeInfo = parseClassType(componentType);
        var result = [];
        var obj = storage[componentTypeInfo.main];

        if (obj && obj[IS_CONTAINER]) {
          each(obj, function (o, type) {
            type !== IS_CONTAINER && result.push(o);
          });
        } else {
          result.push(obj);
        }

        return result;
      };

      target.hasClass = function (componentType) {
        // Just consider componentType.main.
        var componentTypeInfo = parseClassType(componentType);
        return !!storage[componentTypeInfo.main];
      };
      /**
       * @return Like ['aa', 'bb'], but can not be ['aa.xx']
       */


      target.getAllClassMainTypes = function () {
        var types = [];
        each(storage, function (obj, type) {
          types.push(type);
        });
        return types;
      };
      /**
       * If a main type is container and has sub types
       */


      target.hasSubTypes = function (componentType) {
        var componentTypeInfo = parseClassType(componentType);
        var obj = storage[componentTypeInfo.main];
        return obj && obj[IS_CONTAINER];
      };

      function makeContainer(componentTypeInfo) {
        var container = storage[componentTypeInfo.main];

        if (!container || !container[IS_CONTAINER]) {
          container = storage[componentTypeInfo.main] = {};
          container[IS_CONTAINER] = true;
        }

        return container;
      }
    } // /**
    //  * @param {string|Array.<string>} properties
    //  */
    // export function setReadOnly(obj, properties) {
    // FIXME It seems broken in IE8 simulation of IE11
    // if (!zrUtil.isArray(properties)) {
    //     properties = properties != null ? [properties] : [];
    // }
    // zrUtil.each(properties, function (prop) {
    //     let value = obj[prop];
    //     Object.defineProperty
    //         && Object.defineProperty(obj, prop, {
    //             value: value, writable: false
    //         });
    //     zrUtil.isArray(obj[prop])
    //         && Object.freeze
    //         && Object.freeze(obj[prop]);
    // });
    // }

    function makeStyleMapper(properties, ignoreParent) {
      // Normalize
      for (var i = 0; i < properties.length; i++) {
        if (!properties[i][1]) {
          properties[i][1] = properties[i][0];
        }
      }

      ignoreParent = ignoreParent || false;
      return function (model, excludes, includes) {
        var style = {};

        for (var i = 0; i < properties.length; i++) {
          var propName = properties[i][1];

          if (excludes && indexOf(excludes, propName) >= 0 || includes && indexOf(includes, propName) < 0) {
            continue;
          }

          var val = model.getShallow(propName, ignoreParent);

          if (val != null) {
            style[properties[i][0]] = val;
          }
        } // TODO Text or image?


        return style;
      };
    }

    var AREA_STYLE_KEY_MAP = [['fill', 'color'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['opacity'], ['shadowColor'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
    // So do not transfer decal directly.
    ];
    var getAreaStyle = makeStyleMapper(AREA_STYLE_KEY_MAP);

    var AreaStyleMixin =
    /** @class */
    function () {
      function AreaStyleMixin() {}

      AreaStyleMixin.prototype.getAreaStyle = function (excludes, includes) {
        return getAreaStyle(this, excludes, includes);
      };

      return AreaStyleMixin;
    }();

    var globalImageCache = new LRU(50);
    function findExistImage(newImageOrSrc) {
        if (typeof newImageOrSrc === 'string') {
            var cachedImgObj = globalImageCache.get(newImageOrSrc);
            return cachedImgObj && cachedImgObj.image;
        }
        else {
            return newImageOrSrc;
        }
    }
    function createOrUpdateImage(newImageOrSrc, image, hostEl, onload, cbPayload) {
        if (!newImageOrSrc) {
            return image;
        }
        else if (typeof newImageOrSrc === 'string') {
            if ((image && image.__zrImageSrc === newImageOrSrc) || !hostEl) {
                return image;
            }
            var cachedImgObj = globalImageCache.get(newImageOrSrc);
            var pendingWrap = { hostEl: hostEl, cb: onload, cbPayload: cbPayload };
            if (cachedImgObj) {
                image = cachedImgObj.image;
                !isImageReady(image) && cachedImgObj.pending.push(pendingWrap);
            }
            else {
                image = platformApi.loadImage(newImageOrSrc, imageOnLoad, imageOnLoad);
                image.__zrImageSrc = newImageOrSrc;
                globalImageCache.put(newImageOrSrc, image.__cachedImgObj = {
                    image: image,
                    pending: [pendingWrap]
                });
            }
            return image;
        }
        else {
            return newImageOrSrc;
        }
    }
    function imageOnLoad() {
        var cachedImgObj = this.__cachedImgObj;
        this.onload = this.onerror = this.__cachedImgObj = null;
        for (var i = 0; i < cachedImgObj.pending.length; i++) {
            var pendingWrap = cachedImgObj.pending[i];
            var cb = pendingWrap.cb;
            cb && cb(this, pendingWrap.cbPayload);
            pendingWrap.hostEl.dirty();
        }
        cachedImgObj.pending.length = 0;
    }
    function isImageReady(image) {
        return image && image.width && image.height;
    }

    var STYLE_REG = /\{([a-zA-Z0-9_]+)\|([^}]*)\}/g;
    function truncateText(text, containerWidth, font, ellipsis, options) {
        if (!containerWidth) {
            return '';
        }
        var textLines = (text + '').split('\n');
        options = prepareTruncateOptions(containerWidth, font, ellipsis, options);
        for (var i = 0, len = textLines.length; i < len; i++) {
            textLines[i] = truncateSingleLine(textLines[i], options);
        }
        return textLines.join('\n');
    }
    function prepareTruncateOptions(containerWidth, font, ellipsis, options) {
        options = options || {};
        var preparedOpts = extend({}, options);
        preparedOpts.font = font;
        ellipsis = retrieve2(ellipsis, '...');
        preparedOpts.maxIterations = retrieve2(options.maxIterations, 2);
        var minChar = preparedOpts.minChar = retrieve2(options.minChar, 0);
        preparedOpts.cnCharWidth = getWidth('国', font);
        var ascCharWidth = preparedOpts.ascCharWidth = getWidth('a', font);
        preparedOpts.placeholder = retrieve2(options.placeholder, '');
        var contentWidth = containerWidth = Math.max(0, containerWidth - 1);
        for (var i = 0; i < minChar && contentWidth >= ascCharWidth; i++) {
            contentWidth -= ascCharWidth;
        }
        var ellipsisWidth = getWidth(ellipsis, font);
        if (ellipsisWidth > contentWidth) {
            ellipsis = '';
            ellipsisWidth = 0;
        }
        contentWidth = containerWidth - ellipsisWidth;
        preparedOpts.ellipsis = ellipsis;
        preparedOpts.ellipsisWidth = ellipsisWidth;
        preparedOpts.contentWidth = contentWidth;
        preparedOpts.containerWidth = containerWidth;
        return preparedOpts;
    }
    function truncateSingleLine(textLine, options) {
        var containerWidth = options.containerWidth;
        var font = options.font;
        var contentWidth = options.contentWidth;
        if (!containerWidth) {
            return '';
        }
        var lineWidth = getWidth(textLine, font);
        if (lineWidth <= containerWidth) {
            return textLine;
        }
        for (var j = 0;; j++) {
            if (lineWidth <= contentWidth || j >= options.maxIterations) {
                textLine += options.ellipsis;
                break;
            }
            var subLength = j === 0
                ? estimateLength(textLine, contentWidth, options.ascCharWidth, options.cnCharWidth)
                : lineWidth > 0
                    ? Math.floor(textLine.length * contentWidth / lineWidth)
                    : 0;
            textLine = textLine.substr(0, subLength);
            lineWidth = getWidth(textLine, font);
        }
        if (textLine === '') {
            textLine = options.placeholder;
        }
        return textLine;
    }
    function estimateLength(text, contentWidth, ascCharWidth, cnCharWidth) {
        var width = 0;
        var i = 0;
        for (var len = text.length; i < len && width < contentWidth; i++) {
            var charCode = text.charCodeAt(i);
            width += (0 <= charCode && charCode <= 127) ? ascCharWidth : cnCharWidth;
        }
        return i;
    }
    function parsePlainText(text, style) {
        text != null && (text += '');
        var overflow = style.overflow;
        var padding = style.padding;
        var font = style.font;
        var truncate = overflow === 'truncate';
        var calculatedLineHeight = getLineHeight(font);
        var lineHeight = retrieve2(style.lineHeight, calculatedLineHeight);
        var bgColorDrawn = !!(style.backgroundColor);
        var truncateLineOverflow = style.lineOverflow === 'truncate';
        var width = style.width;
        var lines;
        if (width != null && (overflow === 'break' || overflow === 'breakAll')) {
            lines = text ? wrapText(text, style.font, width, overflow === 'breakAll', 0).lines : [];
        }
        else {
            lines = text ? text.split('\n') : [];
        }
        var contentHeight = lines.length * lineHeight;
        var height = retrieve2(style.height, contentHeight);
        if (contentHeight > height && truncateLineOverflow) {
            var lineCount = Math.floor(height / lineHeight);
            lines = lines.slice(0, lineCount);
        }
        if (text && truncate && width != null) {
            var options = prepareTruncateOptions(width, font, style.ellipsis, {
                minChar: style.truncateMinChar,
                placeholder: style.placeholder
            });
            for (var i = 0; i < lines.length; i++) {
                lines[i] = truncateSingleLine(lines[i], options);
            }
        }
        var outerHeight = height;
        var contentWidth = 0;
        for (var i = 0; i < lines.length; i++) {
            contentWidth = Math.max(getWidth(lines[i], font), contentWidth);
        }
        if (width == null) {
            width = contentWidth;
        }
        var outerWidth = contentWidth;
        if (padding) {
            outerHeight += padding[0] + padding[2];
            outerWidth += padding[1] + padding[3];
            width += padding[1] + padding[3];
        }
        if (bgColorDrawn) {
            outerWidth = width;
        }
        return {
            lines: lines,
            height: height,
            outerWidth: outerWidth,
            outerHeight: outerHeight,
            lineHeight: lineHeight,
            calculatedLineHeight: calculatedLineHeight,
            contentWidth: contentWidth,
            contentHeight: contentHeight,
            width: width
        };
    }
    var RichTextToken = (function () {
        function RichTextToken() {
        }
        return RichTextToken;
    }());
    var RichTextLine = (function () {
        function RichTextLine(tokens) {
            this.tokens = [];
            if (tokens) {
                this.tokens = tokens;
            }
        }
        return RichTextLine;
    }());
    var RichTextContentBlock = (function () {
        function RichTextContentBlock() {
            this.width = 0;
            this.height = 0;
            this.contentWidth = 0;
            this.contentHeight = 0;
            this.outerWidth = 0;
            this.outerHeight = 0;
            this.lines = [];
        }
        return RichTextContentBlock;
    }());
    function parseRichText(text, style) {
        var contentBlock = new RichTextContentBlock();
        text != null && (text += '');
        if (!text) {
            return contentBlock;
        }
        var topWidth = style.width;
        var topHeight = style.height;
        var overflow = style.overflow;
        var wrapInfo = (overflow === 'break' || overflow === 'breakAll') && topWidth != null
            ? { width: topWidth, accumWidth: 0, breakAll: overflow === 'breakAll' }
            : null;
        var lastIndex = STYLE_REG.lastIndex = 0;
        var result;
        while ((result = STYLE_REG.exec(text)) != null) {
            var matchedIndex = result.index;
            if (matchedIndex > lastIndex) {
                pushTokens(contentBlock, text.substring(lastIndex, matchedIndex), style, wrapInfo);
            }
            pushTokens(contentBlock, result[2], style, wrapInfo, result[1]);
            lastIndex = STYLE_REG.lastIndex;
        }
        if (lastIndex < text.length) {
            pushTokens(contentBlock, text.substring(lastIndex, text.length), style, wrapInfo);
        }
        var pendingList = [];
        var calculatedHeight = 0;
        var calculatedWidth = 0;
        var stlPadding = style.padding;
        var truncate = overflow === 'truncate';
        var truncateLine = style.lineOverflow === 'truncate';
        function finishLine(line, lineWidth, lineHeight) {
            line.width = lineWidth;
            line.lineHeight = lineHeight;
            calculatedHeight += lineHeight;
            calculatedWidth = Math.max(calculatedWidth, lineWidth);
        }
        outer: for (var i = 0; i < contentBlock.lines.length; i++) {
            var line = contentBlock.lines[i];
            var lineHeight = 0;
            var lineWidth = 0;
            for (var j = 0; j < line.tokens.length; j++) {
                var token = line.tokens[j];
                var tokenStyle = token.styleName && style.rich[token.styleName] || {};
                var textPadding = token.textPadding = tokenStyle.padding;
                var paddingH = textPadding ? textPadding[1] + textPadding[3] : 0;
                var font = token.font = tokenStyle.font || style.font;
                token.contentHeight = getLineHeight(font);
                var tokenHeight = retrieve2(tokenStyle.height, token.contentHeight);
                token.innerHeight = tokenHeight;
                textPadding && (tokenHeight += textPadding[0] + textPadding[2]);
                token.height = tokenHeight;
                token.lineHeight = retrieve3(tokenStyle.lineHeight, style.lineHeight, tokenHeight);
                token.align = tokenStyle && tokenStyle.align || style.align;
                token.verticalAlign = tokenStyle && tokenStyle.verticalAlign || 'middle';
                if (truncateLine && topHeight != null && calculatedHeight + token.lineHeight > topHeight) {
                    if (j > 0) {
                        line.tokens = line.tokens.slice(0, j);
                        finishLine(line, lineWidth, lineHeight);
                        contentBlock.lines = contentBlock.lines.slice(0, i + 1);
                    }
                    else {
                        contentBlock.lines = contentBlock.lines.slice(0, i);
                    }
                    break outer;
                }
                var styleTokenWidth = tokenStyle.width;
                var tokenWidthNotSpecified = styleTokenWidth == null || styleTokenWidth === 'auto';
                if (typeof styleTokenWidth === 'string' && styleTokenWidth.charAt(styleTokenWidth.length - 1) === '%') {
                    token.percentWidth = styleTokenWidth;
                    pendingList.push(token);
                    token.contentWidth = getWidth(token.text, font);
                }
                else {
                    if (tokenWidthNotSpecified) {
                        var textBackgroundColor = tokenStyle.backgroundColor;
                        var bgImg = textBackgroundColor && textBackgroundColor.image;
                        if (bgImg) {
                            bgImg = findExistImage(bgImg);
                            if (isImageReady(bgImg)) {
                                token.width = Math.max(token.width, bgImg.width * tokenHeight / bgImg.height);
                            }
                        }
                    }
                    var remainTruncWidth = truncate && topWidth != null
                        ? topWidth - lineWidth : null;
                    if (remainTruncWidth != null && remainTruncWidth < token.width) {
                        if (!tokenWidthNotSpecified || remainTruncWidth < paddingH) {
                            token.text = '';
                            token.width = token.contentWidth = 0;
                        }
                        else {
                            token.text = truncateText(token.text, remainTruncWidth - paddingH, font, style.ellipsis, { minChar: style.truncateMinChar });
                            token.width = token.contentWidth = getWidth(token.text, font);
                        }
                    }
                    else {
                        token.contentWidth = getWidth(token.text, font);
                    }
                }
                token.width += paddingH;
                lineWidth += token.width;
                tokenStyle && (lineHeight = Math.max(lineHeight, token.lineHeight));
            }
            finishLine(line, lineWidth, lineHeight);
        }
        contentBlock.outerWidth = contentBlock.width = retrieve2(topWidth, calculatedWidth);
        contentBlock.outerHeight = contentBlock.height = retrieve2(topHeight, calculatedHeight);
        contentBlock.contentHeight = calculatedHeight;
        contentBlock.contentWidth = calculatedWidth;
        if (stlPadding) {
            contentBlock.outerWidth += stlPadding[1] + stlPadding[3];
            contentBlock.outerHeight += stlPadding[0] + stlPadding[2];
        }
        for (var i = 0; i < pendingList.length; i++) {
            var token = pendingList[i];
            var percentWidth = token.percentWidth;
            token.width = parseInt(percentWidth, 10) / 100 * contentBlock.width;
        }
        return contentBlock;
    }
    function pushTokens(block, str, style, wrapInfo, styleName) {
        var isEmptyStr = str === '';
        var tokenStyle = styleName && style.rich[styleName] || {};
        var lines = block.lines;
        var font = tokenStyle.font || style.font;
        var newLine = false;
        var strLines;
        var linesWidths;
        if (wrapInfo) {
            var tokenPadding = tokenStyle.padding;
            var tokenPaddingH = tokenPadding ? tokenPadding[1] + tokenPadding[3] : 0;
            if (tokenStyle.width != null && tokenStyle.width !== 'auto') {
                var outerWidth_1 = parsePercent(tokenStyle.width, wrapInfo.width) + tokenPaddingH;
                if (lines.length > 0) {
                    if (outerWidth_1 + wrapInfo.accumWidth > wrapInfo.width) {
                        strLines = str.split('\n');
                        newLine = true;
                    }
                }
                wrapInfo.accumWidth = outerWidth_1;
            }
            else {
                var res = wrapText(str, font, wrapInfo.width, wrapInfo.breakAll, wrapInfo.accumWidth);
                wrapInfo.accumWidth = res.accumWidth + tokenPaddingH;
                linesWidths = res.linesWidths;
                strLines = res.lines;
            }
        }
        else {
            strLines = str.split('\n');
        }
        for (var i = 0; i < strLines.length; i++) {
            var text = strLines[i];
            var token = new RichTextToken();
            token.styleName = styleName;
            token.text = text;
            token.isLineHolder = !text && !isEmptyStr;
            if (typeof tokenStyle.width === 'number') {
                token.width = tokenStyle.width;
            }
            else {
                token.width = linesWidths
                    ? linesWidths[i]
                    : getWidth(text, font);
            }
            if (!i && !newLine) {
                var tokens = (lines[lines.length - 1] || (lines[0] = new RichTextLine())).tokens;
                var tokensLen = tokens.length;
                (tokensLen === 1 && tokens[0].isLineHolder)
                    ? (tokens[0] = token)
                    : ((text || !tokensLen || isEmptyStr) && tokens.push(token));
            }
            else {
                lines.push(new RichTextLine([token]));
            }
        }
    }
    function isLatin(ch) {
        var code = ch.charCodeAt(0);
        return code >= 0x21 && code <= 0x17F;
    }
    var breakCharMap = reduce(',&?/;] '.split(''), function (obj, ch) {
        obj[ch] = true;
        return obj;
    }, {});
    function isWordBreakChar(ch) {
        if (isLatin(ch)) {
            if (breakCharMap[ch]) {
                return true;
            }
            return false;
        }
        return true;
    }
    function wrapText(text, font, lineWidth, isBreakAll, lastAccumWidth) {
        var lines = [];
        var linesWidths = [];
        var line = '';
        var currentWord = '';
        var currentWordWidth = 0;
        var accumWidth = 0;
        for (var i = 0; i < text.length; i++) {
            var ch = text.charAt(i);
            if (ch === '\n') {
                if (currentWord) {
                    line += currentWord;
                    accumWidth += currentWordWidth;
                }
                lines.push(line);
                linesWidths.push(accumWidth);
                line = '';
                currentWord = '';
                currentWordWidth = 0;
                accumWidth = 0;
                continue;
            }
            var chWidth = getWidth(ch, font);
            var inWord = isBreakAll ? false : !isWordBreakChar(ch);
            if (!lines.length
                ? lastAccumWidth + accumWidth + chWidth > lineWidth
                : accumWidth + chWidth > lineWidth) {
                if (!accumWidth) {
                    if (inWord) {
                        lines.push(currentWord);
                        linesWidths.push(currentWordWidth);
                        currentWord = ch;
                        currentWordWidth = chWidth;
                    }
                    else {
                        lines.push(ch);
                        linesWidths.push(chWidth);
                    }
                }
                else if (line || currentWord) {
                    if (inWord) {
                        if (!line) {
                            line = currentWord;
                            currentWord = '';
                            currentWordWidth = 0;
                            accumWidth = currentWordWidth;
                        }
                        lines.push(line);
                        linesWidths.push(accumWidth - currentWordWidth);
                        currentWord += ch;
                        currentWordWidth += chWidth;
                        line = '';
                        accumWidth = currentWordWidth;
                    }
                    else {
                        if (currentWord) {
                            line += currentWord;
                            currentWord = '';
                            currentWordWidth = 0;
                        }
                        lines.push(line);
                        linesWidths.push(accumWidth);
                        line = ch;
                        accumWidth = chWidth;
                    }
                }
                continue;
            }
            accumWidth += chWidth;
            if (inWord) {
                currentWord += ch;
                currentWordWidth += chWidth;
            }
            else {
                if (currentWord) {
                    line += currentWord;
                    currentWord = '';
                    currentWordWidth = 0;
                }
                line += ch;
            }
        }
        if (!lines.length && !line) {
            line = text;
            currentWord = '';
            currentWordWidth = 0;
        }
        if (currentWord) {
            line += currentWord;
        }
        if (line) {
            lines.push(line);
            linesWidths.push(accumWidth);
        }
        if (lines.length === 1) {
            accumWidth += lastAccumWidth;
        }
        return {
            accumWidth: accumWidth,
            lines: lines,
            linesWidths: linesWidths
        };
    }

    var STYLE_MAGIC_KEY = '__zr_style_' + Math.round((Math.random() * 10));
    var DEFAULT_COMMON_STYLE = {
        shadowBlur: 0,
        shadowOffsetX: 0,
        shadowOffsetY: 0,
        shadowColor: '#000',
        opacity: 1,
        blend: 'source-over'
    };
    var DEFAULT_COMMON_ANIMATION_PROPS = {
        style: {
            shadowBlur: true,
            shadowOffsetX: true,
            shadowOffsetY: true,
            shadowColor: true,
            opacity: true
        }
    };
    DEFAULT_COMMON_STYLE[STYLE_MAGIC_KEY] = true;
    var PRIMARY_STATES_KEYS$1 = ['z', 'z2', 'invisible'];
    var PRIMARY_STATES_KEYS_IN_HOVER_LAYER = ['invisible'];
    var Displayable = (function (_super) {
        __extends(Displayable, _super);
        function Displayable(props) {
            return _super.call(this, props) || this;
        }
        Displayable.prototype._init = function (props) {
            var keysArr = keys(props);
            for (var i = 0; i < keysArr.length; i++) {
                var key = keysArr[i];
                if (key === 'style') {
                    this.useStyle(props[key]);
                }
                else {
                    _super.prototype.attrKV.call(this, key, props[key]);
                }
            }
            if (!this.style) {
                this.useStyle({});
            }
        };
        Displayable.prototype.beforeBrush = function () { };
        Displayable.prototype.afterBrush = function () { };
        Displayable.prototype.innerBeforeBrush = function () { };
        Displayable.prototype.innerAfterBrush = function () { };
        Displayable.prototype.shouldBePainted = function (viewWidth, viewHeight, considerClipPath, considerAncestors) {
            var m = this.transform;
            if (this.ignore
                || this.invisible
                || this.style.opacity === 0
                || (this.culling
                    && isDisplayableCulled(this, viewWidth, viewHeight))
                || (m && !m[0] && !m[3])) {
                return false;
            }
            if (considerClipPath && this.__clipPaths) {
                for (var i = 0; i < this.__clipPaths.length; ++i) {
                    if (this.__clipPaths[i].isZeroArea()) {
                        return false;
                    }
                }
            }
            if (considerAncestors && this.parent) {
                var parent_1 = this.parent;
                while (parent_1) {
                    if (parent_1.ignore) {
                        return false;
                    }
                    parent_1 = parent_1.parent;
                }
            }
            return true;
        };
        Displayable.prototype.contain = function (x, y) {
            return this.rectContain(x, y);
        };
        Displayable.prototype.traverse = function (cb, context) {
            cb.call(context, this);
        };
        Displayable.prototype.rectContain = function (x, y) {
            var coord = this.transformCoordToLocal(x, y);
            var rect = this.getBoundingRect();
            return rect.contain(coord[0], coord[1]);
        };
        Displayable.prototype.getPaintRect = function () {
            var rect = this._paintRect;
            if (!this._paintRect || this.__dirty) {
                var transform = this.transform;
                var elRect = this.getBoundingRect();
                var style = this.style;
                var shadowSize = style.shadowBlur || 0;
                var shadowOffsetX = style.shadowOffsetX || 0;
                var shadowOffsetY = style.shadowOffsetY || 0;
                rect = this._paintRect || (this._paintRect = new BoundingRect(0, 0, 0, 0));
                if (transform) {
                    BoundingRect.applyTransform(rect, elRect, transform);
                }
                else {
                    rect.copy(elRect);
                }
                if (shadowSize || shadowOffsetX || shadowOffsetY) {
                    rect.width += shadowSize * 2 + Math.abs(shadowOffsetX);
                    rect.height += shadowSize * 2 + Math.abs(shadowOffsetY);
                    rect.x = Math.min(rect.x, rect.x + shadowOffsetX - shadowSize);
                    rect.y = Math.min(rect.y, rect.y + shadowOffsetY - shadowSize);
                }
                var tolerance = this.dirtyRectTolerance;
                if (!rect.isZero()) {
                    rect.x = Math.floor(rect.x - tolerance);
                    rect.y = Math.floor(rect.y - tolerance);
                    rect.width = Math.ceil(rect.width + 1 + tolerance * 2);
                    rect.height = Math.ceil(rect.height + 1 + tolerance * 2);
                }
            }
            return rect;
        };
        Displayable.prototype.setPrevPaintRect = function (paintRect) {
            if (paintRect) {
                this._prevPaintRect = this._prevPaintRect || new BoundingRect(0, 0, 0, 0);
                this._prevPaintRect.copy(paintRect);
            }
            else {
                this._prevPaintRect = null;
            }
        };
        Displayable.prototype.getPrevPaintRect = function () {
            return this._prevPaintRect;
        };
        Displayable.prototype.animateStyle = function (loop) {
            return this.animate('style', loop);
        };
        Displayable.prototype.updateDuringAnimation = function (targetKey) {
            if (targetKey === 'style') {
                this.dirtyStyle();
            }
            else {
                this.markRedraw();
            }
        };
        Displayable.prototype.attrKV = function (key, value) {
            if (key !== 'style') {
                _super.prototype.attrKV.call(this, key, value);
            }
            else {
                if (!this.style) {
                    this.useStyle(value);
                }
                else {
                    this.setStyle(value);
                }
            }
        };
        Displayable.prototype.setStyle = function (keyOrObj, value) {
            if (typeof keyOrObj === 'string') {
                this.style[keyOrObj] = value;
            }
            else {
                extend(this.style, keyOrObj);
            }
            this.dirtyStyle();
            return this;
        };
        Displayable.prototype.dirtyStyle = function (notRedraw) {
            if (!notRedraw) {
                this.markRedraw();
            }
            this.__dirty |= STYLE_CHANGED_BIT;
            if (this._rect) {
                this._rect = null;
            }
        };
        Displayable.prototype.dirty = function () {
            this.dirtyStyle();
        };
        Displayable.prototype.styleChanged = function () {
            return !!(this.__dirty & STYLE_CHANGED_BIT);
        };
        Displayable.prototype.styleUpdated = function () {
            this.__dirty &= ~STYLE_CHANGED_BIT;
        };
        Displayable.prototype.createStyle = function (obj) {
            return createObject(DEFAULT_COMMON_STYLE, obj);
        };
        Displayable.prototype.useStyle = function (obj) {
            if (!obj[STYLE_MAGIC_KEY]) {
                obj = this.createStyle(obj);
            }
            if (this.__inHover) {
                this.__hoverStyle = obj;
            }
            else {
                this.style = obj;
            }
            this.dirtyStyle();
        };
        Displayable.prototype.isStyleObject = function (obj) {
            return obj[STYLE_MAGIC_KEY];
        };
        Displayable.prototype._innerSaveToNormal = function (toState) {
            _super.prototype._innerSaveToNormal.call(this, toState);
            var normalState = this._normalState;
            if (toState.style && !normalState.style) {
                normalState.style = this._mergeStyle(this.createStyle(), this.style);
            }
            this._savePrimaryToNormal(toState, normalState, PRIMARY_STATES_KEYS$1);
        };
        Displayable.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) {
            _super.prototype._applyStateObj.call(this, stateName, state, normalState, keepCurrentStates, transition, animationCfg);
            var needsRestoreToNormal = !(state && keepCurrentStates);
            var targetStyle;
            if (state && state.style) {
                if (transition) {
                    if (keepCurrentStates) {
                        targetStyle = state.style;
                    }
                    else {
                        targetStyle = this._mergeStyle(this.createStyle(), normalState.style);
                        this._mergeStyle(targetStyle, state.style);
                    }
                }
                else {
                    targetStyle = this._mergeStyle(this.createStyle(), keepCurrentStates ? this.style : normalState.style);
                    this._mergeStyle(targetStyle, state.style);
                }
            }
            else if (needsRestoreToNormal) {
                targetStyle = normalState.style;
            }
            if (targetStyle) {
                if (transition) {
                    var sourceStyle = this.style;
                    this.style = this.createStyle(needsRestoreToNormal ? {} : sourceStyle);
                    if (needsRestoreToNormal) {
                        var changedKeys = keys(sourceStyle);
                        for (var i = 0; i < changedKeys.length; i++) {
                            var key = changedKeys[i];
                            if (key in targetStyle) {
                                targetStyle[key] = targetStyle[key];
                                this.style[key] = sourceStyle[key];
                            }
                        }
                    }
                    var targetKeys = keys(targetStyle);
                    for (var i = 0; i < targetKeys.length; i++) {
                        var key = targetKeys[i];
                        this.style[key] = this.style[key];
                    }
                    this._transitionState(stateName, {
                        style: targetStyle
                    }, animationCfg, this.getAnimationStyleProps());
                }
                else {
                    this.useStyle(targetStyle);
                }
            }
            var statesKeys = this.__inHover ? PRIMARY_STATES_KEYS_IN_HOVER_LAYER : PRIMARY_STATES_KEYS$1;
            for (var i = 0; i < statesKeys.length; i++) {
                var key = statesKeys[i];
                if (state && state[key] != null) {
                    this[key] = state[key];
                }
                else if (needsRestoreToNormal) {
                    if (normalState[key] != null) {
                        this[key] = normalState[key];
                    }
                }
            }
        };
        Displayable.prototype._mergeStates = function (states) {
            var mergedState = _super.prototype._mergeStates.call(this, states);
            var mergedStyle;
            for (var i = 0; i < states.length; i++) {
                var state = states[i];
                if (state.style) {
                    mergedStyle = mergedStyle || {};
                    this._mergeStyle(mergedStyle, state.style);
                }
            }
            if (mergedStyle) {
                mergedState.style = mergedStyle;
            }
            return mergedState;
        };
        Displayable.prototype._mergeStyle = function (targetStyle, sourceStyle) {
            extend(targetStyle, sourceStyle);
            return targetStyle;
        };
        Displayable.prototype.getAnimationStyleProps = function () {
            return DEFAULT_COMMON_ANIMATION_PROPS;
        };
        Displayable.initDefaultProps = (function () {
            var dispProto = Displayable.prototype;
            dispProto.type = 'displayable';
            dispProto.invisible = false;
            dispProto.z = 0;
            dispProto.z2 = 0;
            dispProto.zlevel = 0;
            dispProto.culling = false;
            dispProto.cursor = 'pointer';
            dispProto.rectHover = false;
            dispProto.incremental = false;
            dispProto._rect = null;
            dispProto.dirtyRectTolerance = 0;
            dispProto.__dirty = REDRAW_BIT | STYLE_CHANGED_BIT;
        })();
        return Displayable;
    }(Element));
    var tmpRect$1 = new BoundingRect(0, 0, 0, 0);
    var viewRect = new BoundingRect(0, 0, 0, 0);
    function isDisplayableCulled(el, width, height) {
        tmpRect$1.copy(el.getBoundingRect());
        if (el.transform) {
            tmpRect$1.applyTransform(el.transform);
        }
        viewRect.width = width;
        viewRect.height = height;
        return !tmpRect$1.intersect(viewRect);
    }

    var mathMin$1 = Math.min;
    var mathMax$1 = Math.max;
    var mathSin = Math.sin;
    var mathCos = Math.cos;
    var PI2 = Math.PI * 2;
    var start = create();
    var end = create();
    var extremity = create();
    function fromLine(x0, y0, x1, y1, min, max) {
        min[0] = mathMin$1(x0, x1);
        min[1] = mathMin$1(y0, y1);
        max[0] = mathMax$1(x0, x1);
        max[1] = mathMax$1(y0, y1);
    }
    var xDim = [];
    var yDim = [];
    function fromCubic(x0, y0, x1, y1, x2, y2, x3, y3, min, max) {
        var cubicExtrema$1 = cubicExtrema;
        var cubicAt$1 = cubicAt;
        var n = cubicExtrema$1(x0, x1, x2, x3, xDim);
        min[0] = Infinity;
        min[1] = Infinity;
        max[0] = -Infinity;
        max[1] = -Infinity;
        for (var i = 0; i < n; i++) {
            var x = cubicAt$1(x0, x1, x2, x3, xDim[i]);
            min[0] = mathMin$1(x, min[0]);
            max[0] = mathMax$1(x, max[0]);
        }
        n = cubicExtrema$1(y0, y1, y2, y3, yDim);
        for (var i = 0; i < n; i++) {
            var y = cubicAt$1(y0, y1, y2, y3, yDim[i]);
            min[1] = mathMin$1(y, min[1]);
            max[1] = mathMax$1(y, max[1]);
        }
        min[0] = mathMin$1(x0, min[0]);
        max[0] = mathMax$1(x0, max[0]);
        min[0] = mathMin$1(x3, min[0]);
        max[0] = mathMax$1(x3, max[0]);
        min[1] = mathMin$1(y0, min[1]);
        max[1] = mathMax$1(y0, max[1]);
        min[1] = mathMin$1(y3, min[1]);
        max[1] = mathMax$1(y3, max[1]);
    }
    function fromQuadratic(x0, y0, x1, y1, x2, y2, min, max) {
        var quadraticExtremum$1 = quadraticExtremum;
        var quadraticAt$1 = quadraticAt;
        var tx = mathMax$1(mathMin$1(quadraticExtremum$1(x0, x1, x2), 1), 0);
        var ty = mathMax$1(mathMin$1(quadraticExtremum$1(y0, y1, y2), 1), 0);
        var x = quadraticAt$1(x0, x1, x2, tx);
        var y = quadraticAt$1(y0, y1, y2, ty);
        min[0] = mathMin$1(x0, x2, x);
        min[1] = mathMin$1(y0, y2, y);
        max[0] = mathMax$1(x0, x2, x);
        max[1] = mathMax$1(y0, y2, y);
    }
    function fromArc(x, y, rx, ry, startAngle, endAngle, anticlockwise, min$1, max$1) {
        var vec2Min = min;
        var vec2Max = max;
        var diff = Math.abs(startAngle - endAngle);
        if (diff % PI2 < 1e-4 && diff > 1e-4) {
            min$1[0] = x - rx;
            min$1[1] = y - ry;
            max$1[0] = x + rx;
            max$1[1] = y + ry;
            return;
        }
        start[0] = mathCos(startAngle) * rx + x;
        start[1] = mathSin(startAngle) * ry + y;
        end[0] = mathCos(endAngle) * rx + x;
        end[1] = mathSin(endAngle) * ry + y;
        vec2Min(min$1, start, end);
        vec2Max(max$1, start, end);
        startAngle = startAngle % (PI2);
        if (startAngle < 0) {
            startAngle = startAngle + PI2;
        }
        endAngle = endAngle % (PI2);
        if (endAngle < 0) {
            endAngle = endAngle + PI2;
        }
        if (startAngle > endAngle && !anticlockwise) {
            endAngle += PI2;
        }
        else if (startAngle < endAngle && anticlockwise) {
            startAngle += PI2;
        }
        if (anticlockwise) {
            var tmp = endAngle;
            endAngle = startAngle;
            startAngle = tmp;
        }
        for (var angle = 0; angle < endAngle; angle += Math.PI / 2) {
            if (angle > startAngle) {
                extremity[0] = mathCos(angle) * rx + x;
                extremity[1] = mathSin(angle) * ry + y;
                vec2Min(min$1, extremity, min$1);
                vec2Max(max$1, extremity, max$1);
            }
        }
    }

    var CMD = {
        M: 1,
        L: 2,
        C: 3,
        Q: 4,
        A: 5,
        Z: 6,
        R: 7
    };
    var tmpOutX = [];
    var tmpOutY = [];
    var min$1 = [];
    var max$1 = [];
    var min2 = [];
    var max2 = [];
    var mathMin$2 = Math.min;
    var mathMax$2 = Math.max;
    var mathCos$1 = Math.cos;
    var mathSin$1 = Math.sin;
    var mathAbs = Math.abs;
    var PI = Math.PI;
    var PI2$1 = PI * 2;
    var hasTypedArray = typeof Float32Array !== 'undefined';
    var tmpAngles = [];
    function modPI2(radian) {
        var n = Math.round(radian / PI * 1e8) / 1e8;
        return (n % 2) * PI;
    }
    function normalizeArcAngles(angles, anticlockwise) {
        var newStartAngle = modPI2(angles[0]);
        if (newStartAngle < 0) {
            newStartAngle += PI2$1;
        }
        var delta = newStartAngle - angles[0];
        var newEndAngle = angles[1];
        newEndAngle += delta;
        if (!anticlockwise && newEndAngle - newStartAngle >= PI2$1) {
            newEndAngle = newStartAngle + PI2$1;
        }
        else if (anticlockwise && newStartAngle - newEndAngle >= PI2$1) {
            newEndAngle = newStartAngle - PI2$1;
        }
        else if (!anticlockwise && newStartAngle > newEndAngle) {
            newEndAngle = newStartAngle + (PI2$1 - modPI2(newStartAngle - newEndAngle));
        }
        else if (anticlockwise && newStartAngle < newEndAngle) {
            newEndAngle = newStartAngle - (PI2$1 - modPI2(newEndAngle - newStartAngle));
        }
        angles[0] = newStartAngle;
        angles[1] = newEndAngle;
    }
    var PathProxy = (function () {
        function PathProxy(notSaveData) {
            this.dpr = 1;
            this._xi = 0;
            this._yi = 0;
            this._x0 = 0;
            this._y0 = 0;
            this._len = 0;
            if (notSaveData) {
                this._saveData = false;
            }
            if (this._saveData) {
                this.data = [];
            }
        }
        PathProxy.prototype.increaseVersion = function () {
            this._version++;
        };
        PathProxy.prototype.getVersion = function () {
            return this._version;
        };
        PathProxy.prototype.setScale = function (sx, sy, segmentIgnoreThreshold) {
            segmentIgnoreThreshold = segmentIgnoreThreshold || 0;
            if (segmentIgnoreThreshold > 0) {
                this._ux = mathAbs(segmentIgnoreThreshold / devicePixelRatio / sx) || 0;
                this._uy = mathAbs(segmentIgnoreThreshold / devicePixelRatio / sy) || 0;
            }
        };
        PathProxy.prototype.setDPR = function (dpr) {
            this.dpr = dpr;
        };
        PathProxy.prototype.setContext = function (ctx) {
            this._ctx = ctx;
        };
        PathProxy.prototype.getContext = function () {
            return this._ctx;
        };
        PathProxy.prototype.beginPath = function () {
            this._ctx && this._ctx.beginPath();
            this.reset();
            return this;
        };
        PathProxy.prototype.reset = function () {
            if (this._saveData) {
                this._len = 0;
            }
            if (this._pathSegLen) {
                this._pathSegLen = null;
                this._pathLen = 0;
            }
            this._version++;
        };
        PathProxy.prototype.moveTo = function (x, y) {
            this._drawPendingPt();
            this.addData(CMD.M, x, y);
            this._ctx && this._ctx.moveTo(x, y);
            this._x0 = x;
            this._y0 = y;
            this._xi = x;
            this._yi = y;
            return this;
        };
        PathProxy.prototype.lineTo = function (x, y) {
            var dx = mathAbs(x - this._xi);
            var dy = mathAbs(y - this._yi);
            var exceedUnit = dx > this._ux || dy > this._uy;
            this.addData(CMD.L, x, y);
            if (this._ctx && exceedUnit) {
                this._ctx.lineTo(x, y);
            }
            if (exceedUnit) {
                this._xi = x;
                this._yi = y;
                this._pendingPtDist = 0;
            }
            else {
                var d2 = dx * dx + dy * dy;
                if (d2 > this._pendingPtDist) {
                    this._pendingPtX = x;
                    this._pendingPtY = y;
                    this._pendingPtDist = d2;
                }
            }
            return this;
        };
        PathProxy.prototype.bezierCurveTo = function (x1, y1, x2, y2, x3, y3) {
            this._drawPendingPt();
            this.addData(CMD.C, x1, y1, x2, y2, x3, y3);
            if (this._ctx) {
                this._ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
            }
            this._xi = x3;
            this._yi = y3;
            return this;
        };
        PathProxy.prototype.quadraticCurveTo = function (x1, y1, x2, y2) {
            this._drawPendingPt();
            this.addData(CMD.Q, x1, y1, x2, y2);
            if (this._ctx) {
                this._ctx.quadraticCurveTo(x1, y1, x2, y2);
            }
            this._xi = x2;
            this._yi = y2;
            return this;
        };
        PathProxy.prototype.arc = function (cx, cy, r, startAngle, endAngle, anticlockwise) {
            this._drawPendingPt();
            tmpAngles[0] = startAngle;
            tmpAngles[1] = endAngle;
            normalizeArcAngles(tmpAngles, anticlockwise);
            startAngle = tmpAngles[0];
            endAngle = tmpAngles[1];
            var delta = endAngle - startAngle;
            this.addData(CMD.A, cx, cy, r, r, startAngle, delta, 0, anticlockwise ? 0 : 1);
            this._ctx && this._ctx.arc(cx, cy, r, startAngle, endAngle, anticlockwise);
            this._xi = mathCos$1(endAngle) * r + cx;
            this._yi = mathSin$1(endAngle) * r + cy;
            return this;
        };
        PathProxy.prototype.arcTo = function (x1, y1, x2, y2, radius) {
            this._drawPendingPt();
            if (this._ctx) {
                this._ctx.arcTo(x1, y1, x2, y2, radius);
            }
            return this;
        };
        PathProxy.prototype.rect = function (x, y, w, h) {
            this._drawPendingPt();
            this._ctx && this._ctx.rect(x, y, w, h);
            this.addData(CMD.R, x, y, w, h);
            return this;
        };
        PathProxy.prototype.closePath = function () {
            this._drawPendingPt();
            this.addData(CMD.Z);
            var ctx = this._ctx;
            var x0 = this._x0;
            var y0 = this._y0;
            if (ctx) {
                ctx.closePath();
            }
            this._xi = x0;
            this._yi = y0;
            return this;
        };
        PathProxy.prototype.fill = function (ctx) {
            ctx && ctx.fill();
            this.toStatic();
        };
        PathProxy.prototype.stroke = function (ctx) {
            ctx && ctx.stroke();
            this.toStatic();
        };
        PathProxy.prototype.len = function () {
            return this._len;
        };
        PathProxy.prototype.setData = function (data) {
            var len = data.length;
            if (!(this.data && this.data.length === len) && hasTypedArray) {
                this.data = new Float32Array(len);
            }
            for (var i = 0; i < len; i++) {
                this.data[i] = data[i];
            }
            this._len = len;
        };
        PathProxy.prototype.appendPath = function (path) {
            if (!(path instanceof Array)) {
                path = [path];
            }
            var len = path.length;
            var appendSize = 0;
            var offset = this._len;
            for (var i = 0; i < len; i++) {
                appendSize += path[i].len();
            }
            if (hasTypedArray && (this.data instanceof Float32Array)) {
                this.data = new Float32Array(offset + appendSize);
            }
            for (var i = 0; i < len; i++) {
                var appendPathData = path[i].data;
                for (var k = 0; k < appendPathData.length; k++) {
                    this.data[offset++] = appendPathData[k];
                }
            }
            this._len = offset;
        };
        PathProxy.prototype.addData = function (cmd, a, b, c, d, e, f, g, h) {
            if (!this._saveData) {
                return;
            }
            var data = this.data;
            if (this._len + arguments.length > data.length) {
                this._expandData();
                data = this.data;
            }
            for (var i = 0; i < arguments.length; i++) {
                data[this._len++] = arguments[i];
            }
        };
        PathProxy.prototype._drawPendingPt = function () {
            if (this._pendingPtDist > 0) {
                this._ctx && this._ctx.lineTo(this._pendingPtX, this._pendingPtY);
                this._pendingPtDist = 0;
            }
        };
        PathProxy.prototype._expandData = function () {
            if (!(this.data instanceof Array)) {
                var newData = [];
                for (var i = 0; i < this._len; i++) {
                    newData[i] = this.data[i];
                }
                this.data = newData;
            }
        };
        PathProxy.prototype.toStatic = function () {
            if (!this._saveData) {
                return;
            }
            this._drawPendingPt();
            var data = this.data;
            if (data instanceof Array) {
                data.length = this._len;
                if (hasTypedArray && this._len > 11) {
                    this.data = new Float32Array(data);
                }
            }
        };
        PathProxy.prototype.getBoundingRect = function () {
            min$1[0] = min$1[1] = min2[0] = min2[1] = Number.MAX_VALUE;
            max$1[0] = max$1[1] = max2[0] = max2[1] = -Number.MAX_VALUE;
            var data = this.data;
            var xi = 0;
            var yi = 0;
            var x0 = 0;
            var y0 = 0;
            var i;
            for (i = 0; i < this._len;) {
                var cmd = data[i++];
                var isFirst = i === 1;
                if (isFirst) {
                    xi = data[i];
                    yi = data[i + 1];
                    x0 = xi;
                    y0 = yi;
                }
                switch (cmd) {
                    case CMD.M:
                        xi = x0 = data[i++];
                        yi = y0 = data[i++];
                        min2[0] = x0;
                        min2[1] = y0;
                        max2[0] = x0;
                        max2[1] = y0;
                        break;
                    case CMD.L:
                        fromLine(xi, yi, data[i], data[i + 1], min2, max2);
                        xi = data[i++];
                        yi = data[i++];
                        break;
                    case CMD.C:
                        fromCubic(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], min2, max2);
                        xi = data[i++];
                        yi = data[i++];
                        break;
                    case CMD.Q:
                        fromQuadratic(xi, yi, data[i++], data[i++], data[i], data[i + 1], min2, max2);
                        xi = data[i++];
                        yi = data[i++];
                        break;
                    case CMD.A:
                        var cx = data[i++];
                        var cy = data[i++];
                        var rx = data[i++];
                        var ry = data[i++];
                        var startAngle = data[i++];
                        var endAngle = data[i++] + startAngle;
                        i += 1;
                        var anticlockwise = !data[i++];
                        if (isFirst) {
                            x0 = mathCos$1(startAngle) * rx + cx;
                            y0 = mathSin$1(startAngle) * ry + cy;
                        }
                        fromArc(cx, cy, rx, ry, startAngle, endAngle, anticlockwise, min2, max2);
                        xi = mathCos$1(endAngle) * rx + cx;
                        yi = mathSin$1(endAngle) * ry + cy;
                        break;
                    case CMD.R:
                        x0 = xi = data[i++];
                        y0 = yi = data[i++];
                        var width = data[i++];
                        var height = data[i++];
                        fromLine(x0, y0, x0 + width, y0 + height, min2, max2);
                        break;
                    case CMD.Z:
                        xi = x0;
                        yi = y0;
                        break;
                }
                min(min$1, min$1, min2);
                max(max$1, max$1, max2);
            }
            if (i === 0) {
                min$1[0] = min$1[1] = max$1[0] = max$1[1] = 0;
            }
            return new BoundingRect(min$1[0], min$1[1], max$1[0] - min$1[0], max$1[1] - min$1[1]);
        };
        PathProxy.prototype._calculateLength = function () {
            var data = this.data;
            var len = this._len;
            var ux = this._ux;
            var uy = this._uy;
            var xi = 0;
            var yi = 0;
            var x0 = 0;
            var y0 = 0;
            if (!this._pathSegLen) {
                this._pathSegLen = [];
            }
            var pathSegLen = this._pathSegLen;
            var pathTotalLen = 0;
            var segCount = 0;
            for (var i = 0; i < len;) {
                var cmd = data[i++];
                var isFirst = i === 1;
                if (isFirst) {
                    xi = data[i];
                    yi = data[i + 1];
                    x0 = xi;
                    y0 = yi;
                }
                var l = -1;
                switch (cmd) {
                    case CMD.M:
                        xi = x0 = data[i++];
                        yi = y0 = data[i++];
                        break;
                    case CMD.L: {
                        var x2 = data[i++];
                        var y2 = data[i++];
                        var dx = x2 - xi;
                        var dy = y2 - yi;
                        if (mathAbs(dx) > ux || mathAbs(dy) > uy || i === len - 1) {
                            l = Math.sqrt(dx * dx + dy * dy);
                            xi = x2;
                            yi = y2;
                        }
                        break;
                    }
                    case CMD.C: {
                        var x1 = data[i++];
                        var y1 = data[i++];
                        var x2 = data[i++];
                        var y2 = data[i++];
                        var x3 = data[i++];
                        var y3 = data[i++];
                        l = cubicLength(xi, yi, x1, y1, x2, y2, x3, y3, 10);
                        xi = x3;
                        yi = y3;
                        break;
                    }
                    case CMD.Q: {
                        var x1 = data[i++];
                        var y1 = data[i++];
                        var x2 = data[i++];
                        var y2 = data[i++];
                        l = quadraticLength(xi, yi, x1, y1, x2, y2, 10);
                        xi = x2;
                        yi = y2;
                        break;
                    }
                    case CMD.A:
                        var cx = data[i++];
                        var cy = data[i++];
                        var rx = data[i++];
                        var ry = data[i++];
                        var startAngle = data[i++];
                        var delta = data[i++];
                        var endAngle = delta + startAngle;
                        i += 1;
                        var anticlockwise = !data[i++];
                        if (isFirst) {
                            x0 = mathCos$1(startAngle) * rx + cx;
                            y0 = mathSin$1(startAngle) * ry + cy;
                        }
                        l = mathMax$2(rx, ry) * mathMin$2(PI2$1, Math.abs(delta));
                        xi = mathCos$1(endAngle) * rx + cx;
                        yi = mathSin$1(endAngle) * ry + cy;
                        break;
                    case CMD.R: {
                        x0 = xi = data[i++];
                        y0 = yi = data[i++];
                        var width = data[i++];
                        var height = data[i++];
                        l = width * 2 + height * 2;
                        break;
                    }
                    case CMD.Z: {
                        var dx = x0 - xi;
                        var dy = y0 - yi;
                        l = Math.sqrt(dx * dx + dy * dy);
                        xi = x0;
                        yi = y0;
                        break;
                    }
                }
                if (l >= 0) {
                    pathSegLen[segCount++] = l;
                    pathTotalLen += l;
                }
            }
            this._pathLen = pathTotalLen;
            return pathTotalLen;
        };
        PathProxy.prototype.rebuildPath = function (ctx, percent) {
            var d = this.data;
            var ux = this._ux;
            var uy = this._uy;
            var len = this._len;
            var x0;
            var y0;
            var xi;
            var yi;
            var x;
            var y;
            var drawPart = percent < 1;
            var pathSegLen;
            var pathTotalLen;
            var accumLength = 0;
            var segCount = 0;
            var displayedLength;
            var pendingPtDist = 0;
            var pendingPtX;
            var pendingPtY;
            if (drawPart) {
                if (!this._pathSegLen) {
                    this._calculateLength();
                }
                pathSegLen = this._pathSegLen;
                pathTotalLen = this._pathLen;
                displayedLength = percent * pathTotalLen;
                if (!displayedLength) {
                    return;
                }
            }
            lo: for (var i = 0; i < len;) {
                var cmd = d[i++];
                var isFirst = i === 1;
                if (isFirst) {
                    xi = d[i];
                    yi = d[i + 1];
                    x0 = xi;
                    y0 = yi;
                }
                if (cmd !== CMD.L && pendingPtDist > 0) {
                    ctx.lineTo(pendingPtX, pendingPtY);
                    pendingPtDist = 0;
                }
                switch (cmd) {
                    case CMD.M:
                        x0 = xi = d[i++];
                        y0 = yi = d[i++];
                        ctx.moveTo(xi, yi);
                        break;
                    case CMD.L: {
                        x = d[i++];
                        y = d[i++];
                        var dx = mathAbs(x - xi);
                        var dy = mathAbs(y - yi);
                        if (dx > ux || dy > uy) {
                            if (drawPart) {
                                var l = pathSegLen[segCount++];
                                if (accumLength + l > displayedLength) {
                                    var t = (displayedLength - accumLength) / l;
                                    ctx.lineTo(xi * (1 - t) + x * t, yi * (1 - t) + y * t);
                                    break lo;
                                }
                                accumLength += l;
                            }
                            ctx.lineTo(x, y);
                            xi = x;
                            yi = y;
                            pendingPtDist = 0;
                        }
                        else {
                            var d2 = dx * dx + dy * dy;
                            if (d2 > pendingPtDist) {
                                pendingPtX = x;
                                pendingPtY = y;
                                pendingPtDist = d2;
                            }
                        }
                        break;
                    }
                    case CMD.C: {
                        var x1 = d[i++];
                        var y1 = d[i++];
                        var x2 = d[i++];
                        var y2 = d[i++];
                        var x3 = d[i++];
                        var y3 = d[i++];
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                var t = (displayedLength - accumLength) / l;
                                cubicSubdivide(xi, x1, x2, x3, t, tmpOutX);
                                cubicSubdivide(yi, y1, y2, y3, t, tmpOutY);
                                ctx.bezierCurveTo(tmpOutX[1], tmpOutY[1], tmpOutX[2], tmpOutY[2], tmpOutX[3], tmpOutY[3]);
                                break lo;
                            }
                            accumLength += l;
                        }
                        ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
                        xi = x3;
                        yi = y3;
                        break;
                    }
                    case CMD.Q: {
                        var x1 = d[i++];
                        var y1 = d[i++];
                        var x2 = d[i++];
                        var y2 = d[i++];
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                var t = (displayedLength - accumLength) / l;
                                quadraticSubdivide(xi, x1, x2, t, tmpOutX);
                                quadraticSubdivide(yi, y1, y2, t, tmpOutY);
                                ctx.quadraticCurveTo(tmpOutX[1], tmpOutY[1], tmpOutX[2], tmpOutY[2]);
                                break lo;
                            }
                            accumLength += l;
                        }
                        ctx.quadraticCurveTo(x1, y1, x2, y2);
                        xi = x2;
                        yi = y2;
                        break;
                    }
                    case CMD.A:
                        var cx = d[i++];
                        var cy = d[i++];
                        var rx = d[i++];
                        var ry = d[i++];
                        var startAngle = d[i++];
                        var delta = d[i++];
                        var psi = d[i++];
                        var anticlockwise = !d[i++];
                        var r = (rx > ry) ? rx : ry;
                        var isEllipse = mathAbs(rx - ry) > 1e-3;
                        var endAngle = startAngle + delta;
                        var breakBuild = false;
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                endAngle = startAngle + delta * (displayedLength - accumLength) / l;
                                breakBuild = true;
                            }
                            accumLength += l;
                        }
                        if (isEllipse && ctx.ellipse) {
                            ctx.ellipse(cx, cy, rx, ry, psi, startAngle, endAngle, anticlockwise);
                        }
                        else {
                            ctx.arc(cx, cy, r, startAngle, endAngle, anticlockwise);
                        }
                        if (breakBuild) {
                            break lo;
                        }
                        if (isFirst) {
                            x0 = mathCos$1(startAngle) * rx + cx;
                            y0 = mathSin$1(startAngle) * ry + cy;
                        }
                        xi = mathCos$1(endAngle) * rx + cx;
                        yi = mathSin$1(endAngle) * ry + cy;
                        break;
                    case CMD.R:
                        x0 = xi = d[i];
                        y0 = yi = d[i + 1];
                        x = d[i++];
                        y = d[i++];
                        var width = d[i++];
                        var height = d[i++];
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                var d_1 = displayedLength - accumLength;
                                ctx.moveTo(x, y);
                                ctx.lineTo(x + mathMin$2(d_1, width), y);
                                d_1 -= width;
                                if (d_1 > 0) {
                                    ctx.lineTo(x + width, y + mathMin$2(d_1, height));
                                }
                                d_1 -= height;
                                if (d_1 > 0) {
                                    ctx.lineTo(x + mathMax$2(width - d_1, 0), y + height);
                                }
                                d_1 -= width;
                                if (d_1 > 0) {
                                    ctx.lineTo(x, y + mathMax$2(height - d_1, 0));
                                }
                                break lo;
                            }
                            accumLength += l;
                        }
                        ctx.rect(x, y, width, height);
                        break;
                    case CMD.Z:
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                var t = (displayedLength - accumLength) / l;
                                ctx.lineTo(xi * (1 - t) + x0 * t, yi * (1 - t) + y0 * t);
                                break lo;
                            }
                            accumLength += l;
                        }
                        ctx.closePath();
                        xi = x0;
                        yi = y0;
                }
            }
        };
        PathProxy.prototype.clone = function () {
            var newProxy = new PathProxy();
            var data = this.data;
            newProxy.data = data.slice ? data.slice()
                : Array.prototype.slice.call(data);
            newProxy._len = this._len;
            return newProxy;
        };
        PathProxy.CMD = CMD;
        PathProxy.initDefaultProps = (function () {
            var proto = PathProxy.prototype;
            proto._saveData = true;
            proto._ux = 0;
            proto._uy = 0;
            proto._pendingPtDist = 0;
            proto._version = 0;
        })();
        return PathProxy;
    }());

    function containStroke(x0, y0, x1, y1, lineWidth, x, y) {
        if (lineWidth === 0) {
            return false;
        }
        var _l = lineWidth;
        var _a = 0;
        var _b = x0;
        if ((y > y0 + _l && y > y1 + _l)
            || (y < y0 - _l && y < y1 - _l)
            || (x > x0 + _l && x > x1 + _l)
            || (x < x0 - _l && x < x1 - _l)) {
            return false;
        }
        if (x0 !== x1) {
            _a = (y0 - y1) / (x0 - x1);
            _b = (x0 * y1 - x1 * y0) / (x0 - x1);
        }
        else {
            return Math.abs(x - x0) <= _l / 2;
        }
        var tmp = _a * x - y + _b;
        var _s = tmp * tmp / (_a * _a + 1);
        return _s <= _l / 2 * _l / 2;
    }

    function containStroke$1(x0, y0, x1, y1, x2, y2, x3, y3, lineWidth, x, y) {
        if (lineWidth === 0) {
            return false;
        }
        var _l = lineWidth;
        if ((y > y0 + _l && y > y1 + _l && y > y2 + _l && y > y3 + _l)
            || (y < y0 - _l && y < y1 - _l && y < y2 - _l && y < y3 - _l)
            || (x > x0 + _l && x > x1 + _l && x > x2 + _l && x > x3 + _l)
            || (x < x0 - _l && x < x1 - _l && x < x2 - _l && x < x3 - _l)) {
            return false;
        }
        var d = cubicProjectPoint(x0, y0, x1, y1, x2, y2, x3, y3, x, y, null);
        return d <= _l / 2;
    }

    function containStroke$2(x0, y0, x1, y1, x2, y2, lineWidth, x, y) {
        if (lineWidth === 0) {
            return false;
        }
        var _l = lineWidth;
        if ((y > y0 + _l && y > y1 + _l && y > y2 + _l)
            || (y < y0 - _l && y < y1 - _l && y < y2 - _l)
            || (x > x0 + _l && x > x1 + _l && x > x2 + _l)
            || (x < x0 - _l && x < x1 - _l && x < x2 - _l)) {
            return false;
        }
        var d = quadraticProjectPoint(x0, y0, x1, y1, x2, y2, x, y, null);
        return d <= _l / 2;
    }

    var PI2$2 = Math.PI * 2;
    function normalizeRadian(angle) {
        angle %= PI2$2;
        if (angle < 0) {
            angle += PI2$2;
        }
        return angle;
    }

    var PI2$3 = Math.PI * 2;
    function containStroke$3(cx, cy, r, startAngle, endAngle, anticlockwise, lineWidth, x, y) {
        if (lineWidth === 0) {
            return false;
        }
        var _l = lineWidth;
        x -= cx;
        y -= cy;
        var d = Math.sqrt(x * x + y * y);
        if ((d - _l > r) || (d + _l < r)) {
            return false;
        }
        if (Math.abs(startAngle - endAngle) % PI2$3 < 1e-4) {
            return true;
        }
        if (anticlockwise) {
            var tmp = startAngle;
            startAngle = normalizeRadian(endAngle);
            endAngle = normalizeRadian(tmp);
        }
        else {
            startAngle = normalizeRadian(startAngle);
            endAngle = normalizeRadian(endAngle);
        }
        if (startAngle > endAngle) {
            endAngle += PI2$3;
        }
        var angle = Math.atan2(y, x);
        if (angle < 0) {
            angle += PI2$3;
        }
        return (angle >= startAngle && angle <= endAngle)
            || (angle + PI2$3 >= startAngle && angle + PI2$3 <= endAngle);
    }

    function windingLine(x0, y0, x1, y1, x, y) {
        if ((y > y0 && y > y1) || (y < y0 && y < y1)) {
            return 0;
        }
        if (y1 === y0) {
            return 0;
        }
        var t = (y - y0) / (y1 - y0);
        var dir = y1 < y0 ? 1 : -1;
        if (t === 1 || t === 0) {
            dir = y1 < y0 ? 0.5 : -0.5;
        }
        var x_ = t * (x1 - x0) + x0;
        return x_ === x ? Infinity : x_ > x ? dir : 0;
    }

    var CMD$1 = PathProxy.CMD;
    var PI2$4 = Math.PI * 2;
    var EPSILON$3 = 1e-4;
    function isAroundEqual(a, b) {
        return Math.abs(a - b) < EPSILON$3;
    }
    var roots = [-1, -1, -1];
    var extrema = [-1, -1];
    function swapExtrema() {
        var tmp = extrema[0];
        extrema[0] = extrema[1];
        extrema[1] = tmp;
    }
    function windingCubic(x0, y0, x1, y1, x2, y2, x3, y3, x, y) {
        if ((y > y0 && y > y1 && y > y2 && y > y3)
            || (y < y0 && y < y1 && y < y2 && y < y3)) {
            return 0;
        }
        var nRoots = cubicRootAt(y0, y1, y2, y3, y, roots);
        if (nRoots === 0) {
            return 0;
        }
        else {
            var w = 0;
            var nExtrema = -1;
            var y0_ = void 0;
            var y1_ = void 0;
            for (var i = 0; i < nRoots; i++) {
                var t = roots[i];
                var unit = (t === 0 || t === 1) ? 0.5 : 1;
                var x_ = cubicAt(x0, x1, x2, x3, t);
                if (x_ < x) {
                    continue;
                }
                if (nExtrema < 0) {
                    nExtrema = cubicExtrema(y0, y1, y2, y3, extrema);
                    if (extrema[1] < extrema[0] && nExtrema > 1) {
                        swapExtrema();
                    }
                    y0_ = cubicAt(y0, y1, y2, y3, extrema[0]);
                    if (nExtrema > 1) {
                        y1_ = cubicAt(y0, y1, y2, y3, extrema[1]);
                    }
                }
                if (nExtrema === 2) {
                    if (t < extrema[0]) {
                        w += y0_ < y0 ? unit : -unit;
                    }
                    else if (t < extrema[1]) {
                        w += y1_ < y0_ ? unit : -unit;
                    }
                    else {
                        w += y3 < y1_ ? unit : -unit;
                    }
                }
                else {
                    if (t < extrema[0]) {
                        w += y0_ < y0 ? unit : -unit;
                    }
                    else {
                        w += y3 < y0_ ? unit : -unit;
                    }
                }
            }
            return w;
        }
    }
    function windingQuadratic(x0, y0, x1, y1, x2, y2, x, y) {
        if ((y > y0 && y > y1 && y > y2)
            || (y < y0 && y < y1 && y < y2)) {
            return 0;
        }
        var nRoots = quadraticRootAt(y0, y1, y2, y, roots);
        if (nRoots === 0) {
            return 0;
        }
        else {
            var t = quadraticExtremum(y0, y1, y2);
            if (t >= 0 && t <= 1) {
                var w = 0;
                var y_ = quadraticAt(y0, y1, y2, t);
                for (var i = 0; i < nRoots; i++) {
                    var unit = (roots[i] === 0 || roots[i] === 1) ? 0.5 : 1;
                    var x_ = quadraticAt(x0, x1, x2, roots[i]);
                    if (x_ < x) {
                        continue;
                    }
                    if (roots[i] < t) {
                        w += y_ < y0 ? unit : -unit;
                    }
                    else {
                        w += y2 < y_ ? unit : -unit;
                    }
                }
                return w;
            }
            else {
                var unit = (roots[0] === 0 || roots[0] === 1) ? 0.5 : 1;
                var x_ = quadraticAt(x0, x1, x2, roots[0]);
                if (x_ < x) {
                    return 0;
                }
                return y2 < y0 ? unit : -unit;
            }
        }
    }
    function windingArc(cx, cy, r, startAngle, endAngle, anticlockwise, x, y) {
        y -= cy;
        if (y > r || y < -r) {
            return 0;
        }
        var tmp = Math.sqrt(r * r - y * y);
        roots[0] = -tmp;
        roots[1] = tmp;
        var dTheta = Math.abs(startAngle - endAngle);
        if (dTheta < 1e-4) {
            return 0;
        }
        if (dTheta >= PI2$4 - 1e-4) {
            startAngle = 0;
            endAngle = PI2$4;
            var dir = anticlockwise ? 1 : -1;
            if (x >= roots[0] + cx && x <= roots[1] + cx) {
                return dir;
            }
            else {
                return 0;
            }
        }
        if (startAngle > endAngle) {
            var tmp_1 = startAngle;
            startAngle = endAngle;
            endAngle = tmp_1;
        }
        if (startAngle < 0) {
            startAngle += PI2$4;
            endAngle += PI2$4;
        }
        var w = 0;
        for (var i = 0; i < 2; i++) {
            var x_ = roots[i];
            if (x_ + cx > x) {
                var angle = Math.atan2(y, x_);
                var dir = anticlockwise ? 1 : -1;
                if (angle < 0) {
                    angle = PI2$4 + angle;
                }
                if ((angle >= startAngle && angle <= endAngle)
                    || (angle + PI2$4 >= startAngle && angle + PI2$4 <= endAngle)) {
                    if (angle > Math.PI / 2 && angle < Math.PI * 1.5) {
                        dir = -dir;
                    }
                    w += dir;
                }
            }
        }
        return w;
    }
    function containPath(path, lineWidth, isStroke, x, y) {
        var data = path.data;
        var len = path.len();
        var w = 0;
        var xi = 0;
        var yi = 0;
        var x0 = 0;
        var y0 = 0;
        var x1;
        var y1;
        for (var i = 0; i < len;) {
            var cmd = data[i++];
            var isFirst = i === 1;
            if (cmd === CMD$1.M && i > 1) {
                if (!isStroke) {
                    w += windingLine(xi, yi, x0, y0, x, y);
                }
            }
            if (isFirst) {
                xi = data[i];
                yi = data[i + 1];
                x0 = xi;
                y0 = yi;
            }
            switch (cmd) {
                case CMD$1.M:
                    x0 = data[i++];
                    y0 = data[i++];
                    xi = x0;
                    yi = y0;
                    break;
                case CMD$1.L:
                    if (isStroke) {
                        if (containStroke(xi, yi, data[i], data[i + 1], lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingLine(xi, yi, data[i], data[i + 1], x, y) || 0;
                    }
                    xi = data[i++];
                    yi = data[i++];
                    break;
                case CMD$1.C:
                    if (isStroke) {
                        if (containStroke$1(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingCubic(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], x, y) || 0;
                    }
                    xi = data[i++];
                    yi = data[i++];
                    break;
                case CMD$1.Q:
                    if (isStroke) {
                        if (containStroke$2(xi, yi, data[i++], data[i++], data[i], data[i + 1], lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingQuadratic(xi, yi, data[i++], data[i++], data[i], data[i + 1], x, y) || 0;
                    }
                    xi = data[i++];
                    yi = data[i++];
                    break;
                case CMD$1.A:
                    var cx = data[i++];
                    var cy = data[i++];
                    var rx = data[i++];
                    var ry = data[i++];
                    var theta = data[i++];
                    var dTheta = data[i++];
                    i += 1;
                    var anticlockwise = !!(1 - data[i++]);
                    x1 = Math.cos(theta) * rx + cx;
                    y1 = Math.sin(theta) * ry + cy;
                    if (!isFirst) {
                        w += windingLine(xi, yi, x1, y1, x, y);
                    }
                    else {
                        x0 = x1;
                        y0 = y1;
                    }
                    var _x = (x - cx) * ry / rx + cx;
                    if (isStroke) {
                        if (containStroke$3(cx, cy, ry, theta, theta + dTheta, anticlockwise, lineWidth, _x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingArc(cx, cy, ry, theta, theta + dTheta, anticlockwise, _x, y);
                    }
                    xi = Math.cos(theta + dTheta) * rx + cx;
                    yi = Math.sin(theta + dTheta) * ry + cy;
                    break;
                case CMD$1.R:
                    x0 = xi = data[i++];
                    y0 = yi = data[i++];
                    var width = data[i++];
                    var height = data[i++];
                    x1 = x0 + width;
                    y1 = y0 + height;
                    if (isStroke) {
                        if (containStroke(x0, y0, x1, y0, lineWidth, x, y)
                            || containStroke(x1, y0, x1, y1, lineWidth, x, y)
                            || containStroke(x1, y1, x0, y1, lineWidth, x, y)
                            || containStroke(x0, y1, x0, y0, lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingLine(x1, y0, x1, y1, x, y);
                        w += windingLine(x0, y1, x0, y0, x, y);
                    }
                    break;
                case CMD$1.Z:
                    if (isStroke) {
                        if (containStroke(xi, yi, x0, y0, lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingLine(xi, yi, x0, y0, x, y);
                    }
                    xi = x0;
                    yi = y0;
                    break;
            }
        }
        if (!isStroke && !isAroundEqual(yi, y0)) {
            w += windingLine(xi, yi, x0, y0, x, y) || 0;
        }
        return w !== 0;
    }
    function contain(pathProxy, x, y) {
        return containPath(pathProxy, 0, false, x, y);
    }
    function containStroke$4(pathProxy, lineWidth, x, y) {
        return containPath(pathProxy, lineWidth, true, x, y);
    }

    var DEFAULT_PATH_STYLE = defaults({
        fill: '#000',
        stroke: null,
        strokePercent: 1,
        fillOpacity: 1,
        strokeOpacity: 1,
        lineDashOffset: 0,
        lineWidth: 1,
        lineCap: 'butt',
        miterLimit: 10,
        strokeNoScale: false,
        strokeFirst: false
    }, DEFAULT_COMMON_STYLE);
    var DEFAULT_PATH_ANIMATION_PROPS = {
        style: defaults({
            fill: true,
            stroke: true,
            strokePercent: true,
            fillOpacity: true,
            strokeOpacity: true,
            lineDashOffset: true,
            lineWidth: true,
            miterLimit: true
        }, DEFAULT_COMMON_ANIMATION_PROPS.style)
    };
    var pathCopyParams = TRANSFORMABLE_PROPS.concat(['invisible',
        'culling', 'z', 'z2', 'zlevel', 'parent'
    ]);
    var Path = (function (_super) {
        __extends(Path, _super);
        function Path(opts) {
            return _super.call(this, opts) || this;
        }
        Path.prototype.update = function () {
            var _this = this;
            _super.prototype.update.call(this);
            var style = this.style;
            if (style.decal) {
                var decalEl = this._decalEl = this._decalEl || new Path();
                if (decalEl.buildPath === Path.prototype.buildPath) {
                    decalEl.buildPath = function (ctx) {
                        _this.buildPath(ctx, _this.shape);
                    };
                }
                decalEl.silent = true;
                var decalElStyle = decalEl.style;
                for (var key in style) {
                    if (decalElStyle[key] !== style[key]) {
                        decalElStyle[key] = style[key];
                    }
                }
                decalElStyle.fill = style.fill ? style.decal : null;
                decalElStyle.decal = null;
                decalElStyle.shadowColor = null;
                style.strokeFirst && (decalElStyle.stroke = null);
                for (var i = 0; i < pathCopyParams.length; ++i) {
                    decalEl[pathCopyParams[i]] = this[pathCopyParams[i]];
                }
                decalEl.__dirty |= REDRAW_BIT;
            }
            else if (this._decalEl) {
                this._decalEl = null;
            }
        };
        Path.prototype.getDecalElement = function () {
            return this._decalEl;
        };
        Path.prototype._init = function (props) {
            var keysArr = keys(props);
            this.shape = this.getDefaultShape();
            var defaultStyle = this.getDefaultStyle();
            if (defaultStyle) {
                this.useStyle(defaultStyle);
            }
            for (var i = 0; i < keysArr.length; i++) {
                var key = keysArr[i];
                var value = props[key];
                if (key === 'style') {
                    if (!this.style) {
                        this.useStyle(value);
                    }
                    else {
                        extend(this.style, value);
                    }
                }
                else if (key === 'shape') {
                    extend(this.shape, value);
                }
                else {
                    _super.prototype.attrKV.call(this, key, value);
                }
            }
            if (!this.style) {
                this.useStyle({});
            }
        };
        Path.prototype.getDefaultStyle = function () {
            return null;
        };
        Path.prototype.getDefaultShape = function () {
            return {};
        };
        Path.prototype.canBeInsideText = function () {
            return this.hasFill();
        };
        Path.prototype.getInsideTextFill = function () {
            var pathFill = this.style.fill;
            if (pathFill !== 'none') {
                if (isString(pathFill)) {
                    var fillLum = lum(pathFill, 0);
                    if (fillLum > 0.5) {
                        return DARK_LABEL_COLOR;
                    }
                    else if (fillLum > 0.2) {
                        return LIGHTER_LABEL_COLOR;
                    }
                    return LIGHT_LABEL_COLOR;
                }
                else if (pathFill) {
                    return LIGHT_LABEL_COLOR;
                }
            }
            return DARK_LABEL_COLOR;
        };
        Path.prototype.getInsideTextStroke = function (textFill) {
            var pathFill = this.style.fill;
            if (isString(pathFill)) {
                var zr = this.__zr;
                var isDarkMode = !!(zr && zr.isDarkMode());
                var isDarkLabel = lum(textFill, 0) < DARK_MODE_THRESHOLD;
                if (isDarkMode === isDarkLabel) {
                    return pathFill;
                }
            }
        };
        Path.prototype.buildPath = function (ctx, shapeCfg, inBatch) { };
        Path.prototype.pathUpdated = function () {
            this.__dirty &= ~SHAPE_CHANGED_BIT;
        };
        Path.prototype.getUpdatedPathProxy = function (inBatch) {
            !this.path && this.createPathProxy();
            this.path.beginPath();
            this.buildPath(this.path, this.shape, inBatch);
            return this.path;
        };
        Path.prototype.createPathProxy = function () {
            this.path = new PathProxy(false);
        };
        Path.prototype.hasStroke = function () {
            var style = this.style;
            var stroke = style.stroke;
            return !(stroke == null || stroke === 'none' || !(style.lineWidth > 0));
        };
        Path.prototype.hasFill = function () {
            var style = this.style;
            var fill = style.fill;
            return fill != null && fill !== 'none';
        };
        Path.prototype.getBoundingRect = function () {
            var rect = this._rect;
            var style = this.style;
            var needsUpdateRect = !rect;
            if (needsUpdateRect) {
                var firstInvoke = false;
                if (!this.path) {
                    firstInvoke = true;
                    this.createPathProxy();
                }
                var path = this.path;
                if (firstInvoke || (this.__dirty & SHAPE_CHANGED_BIT)) {
                    path.beginPath();
                    this.buildPath(path, this.shape, false);
                    this.pathUpdated();
                }
                rect = path.getBoundingRect();
            }
            this._rect = rect;
            if (this.hasStroke() && this.path && this.path.len() > 0) {
                var rectStroke = this._rectStroke || (this._rectStroke = rect.clone());
                if (this.__dirty || needsUpdateRect) {
                    rectStroke.copy(rect);
                    var lineScale = style.strokeNoScale ? this.getLineScale() : 1;
                    var w = style.lineWidth;
                    if (!this.hasFill()) {
                        var strokeContainThreshold = this.strokeContainThreshold;
                        w = Math.max(w, strokeContainThreshold == null ? 4 : strokeContainThreshold);
                    }
                    if (lineScale > 1e-10) {
                        rectStroke.width += w / lineScale;
                        rectStroke.height += w / lineScale;
                        rectStroke.x -= w / lineScale / 2;
                        rectStroke.y -= w / lineScale / 2;
                    }
                }
                return rectStroke;
            }
            return rect;
        };
        Path.prototype.contain = function (x, y) {
            var localPos = this.transformCoordToLocal(x, y);
            var rect = this.getBoundingRect();
            var style = this.style;
            x = localPos[0];
            y = localPos[1];
            if (rect.contain(x, y)) {
                var pathProxy = this.path;
                if (this.hasStroke()) {
                    var lineWidth = style.lineWidth;
                    var lineScale = style.strokeNoScale ? this.getLineScale() : 1;
                    if (lineScale > 1e-10) {
                        if (!this.hasFill()) {
                            lineWidth = Math.max(lineWidth, this.strokeContainThreshold);
                        }
                        if (containStroke$4(pathProxy, lineWidth / lineScale, x, y)) {
                            return true;
                        }
                    }
                }
                if (this.hasFill()) {
                    return contain(pathProxy, x, y);
                }
            }
            return false;
        };
        Path.prototype.dirtyShape = function () {
            this.__dirty |= SHAPE_CHANGED_BIT;
            if (this._rect) {
                this._rect = null;
            }
            if (this._decalEl) {
                this._decalEl.dirtyShape();
            }
            this.markRedraw();
        };
        Path.prototype.dirty = function () {
            this.dirtyStyle();
            this.dirtyShape();
        };
        Path.prototype.animateShape = function (loop) {
            return this.animate('shape', loop);
        };
        Path.prototype.updateDuringAnimation = function (targetKey) {
            if (targetKey === 'style') {
                this.dirtyStyle();
            }
            else if (targetKey === 'shape') {
                this.dirtyShape();
            }
            else {
                this.markRedraw();
            }
        };
        Path.prototype.attrKV = function (key, value) {
            if (key === 'shape') {
                this.setShape(value);
            }
            else {
                _super.prototype.attrKV.call(this, key, value);
            }
        };
        Path.prototype.setShape = function (keyOrObj, value) {
            var shape = this.shape;
            if (!shape) {
                shape = this.shape = {};
            }
            if (typeof keyOrObj === 'string') {
                shape[keyOrObj] = value;
            }
            else {
                extend(shape, keyOrObj);
            }
            this.dirtyShape();
            return this;
        };
        Path.prototype.shapeChanged = function () {
            return !!(this.__dirty & SHAPE_CHANGED_BIT);
        };
        Path.prototype.createStyle = function (obj) {
            return createObject(DEFAULT_PATH_STYLE, obj);
        };
        Path.prototype._innerSaveToNormal = function (toState) {
            _super.prototype._innerSaveToNormal.call(this, toState);
            var normalState = this._normalState;
            if (toState.shape && !normalState.shape) {
                normalState.shape = extend({}, this.shape);
            }
        };
        Path.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) {
            _super.prototype._applyStateObj.call(this, stateName, state, normalState, keepCurrentStates, transition, animationCfg);
            var needsRestoreToNormal = !(state && keepCurrentStates);
            var targetShape;
            if (state && state.shape) {
                if (transition) {
                    if (keepCurrentStates) {
                        targetShape = state.shape;
                    }
                    else {
                        targetShape = extend({}, normalState.shape);
                        extend(targetShape, state.shape);
                    }
                }
                else {
                    targetShape = extend({}, keepCurrentStates ? this.shape : normalState.shape);
                    extend(targetShape, state.shape);
                }
            }
            else if (needsRestoreToNormal) {
                targetShape = normalState.shape;
            }
            if (targetShape) {
                if (transition) {
                    this.shape = extend({}, this.shape);
                    var targetShapePrimaryProps = {};
                    var shapeKeys = keys(targetShape);
                    for (var i = 0; i < shapeKeys.length; i++) {
                        var key = shapeKeys[i];
                        if (typeof targetShape[key] === 'object') {
                            this.shape[key] = targetShape[key];
                        }
                        else {
                            targetShapePrimaryProps[key] = targetShape[key];
                        }
                    }
                    this._transitionState(stateName, {
                        shape: targetShapePrimaryProps
                    }, animationCfg);
                }
                else {
                    this.shape = targetShape;
                    this.dirtyShape();
                }
            }
        };
        Path.prototype._mergeStates = function (states) {
            var mergedState = _super.prototype._mergeStates.call(this, states);
            var mergedShape;
            for (var i = 0; i < states.length; i++) {
                var state = states[i];
                if (state.shape) {
                    mergedShape = mergedShape || {};
                    this._mergeStyle(mergedShape, state.shape);
                }
            }
            if (mergedShape) {
                mergedState.shape = mergedShape;
            }
            return mergedState;
        };
        Path.prototype.getAnimationStyleProps = function () {
            return DEFAULT_PATH_ANIMATION_PROPS;
        };
        Path.prototype.isZeroArea = function () {
            return false;
        };
        Path.extend = function (defaultProps) {
            var Sub = (function (_super) {
                __extends(Sub, _super);
                function Sub(opts) {
                    var _this = _super.call(this, opts) || this;
                    defaultProps.init && defaultProps.init.call(_this, opts);
                    return _this;
                }
                Sub.prototype.getDefaultStyle = function () {
                    return clone(defaultProps.style);
                };
                Sub.prototype.getDefaultShape = function () {
                    return clone(defaultProps.shape);
                };
                return Sub;
            }(Path));
            for (var key in defaultProps) {
                if (typeof defaultProps[key] === 'function') {
                    Sub.prototype[key] = defaultProps[key];
                }
            }
            return Sub;
        };
        Path.initDefaultProps = (function () {
            var pathProto = Path.prototype;
            pathProto.type = 'path';
            pathProto.strokeContainThreshold = 5;
            pathProto.segmentIgnoreThreshold = 0;
            pathProto.subPixelOptimize = false;
            pathProto.autoBatch = false;
            pathProto.__dirty = REDRAW_BIT | STYLE_CHANGED_BIT | SHAPE_CHANGED_BIT;
        })();
        return Path;
    }(Displayable));

    var DEFAULT_TSPAN_STYLE = defaults({
        strokeFirst: true,
        font: DEFAULT_FONT,
        x: 0,
        y: 0,
        textAlign: 'left',
        textBaseline: 'top',
        miterLimit: 2
    }, DEFAULT_PATH_STYLE);
    var TSpan = (function (_super) {
        __extends(TSpan, _super);
        function TSpan() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        TSpan.prototype.hasStroke = function () {
            var style = this.style;
            var stroke = style.stroke;
            return stroke != null && stroke !== 'none' && style.lineWidth > 0;
        };
        TSpan.prototype.hasFill = function () {
            var style = this.style;
            var fill = style.fill;
            return fill != null && fill !== 'none';
        };
        TSpan.prototype.createStyle = function (obj) {
            return createObject(DEFAULT_TSPAN_STYLE, obj);
        };
        TSpan.prototype.setBoundingRect = function (rect) {
            this._rect = rect;
        };
        TSpan.prototype.getBoundingRect = function () {
            var style = this.style;
            if (!this._rect) {
                var text = style.text;
                text != null ? (text += '') : (text = '');
                var rect = getBoundingRect(text, style.font, style.textAlign, style.textBaseline);
                rect.x += style.x || 0;
                rect.y += style.y || 0;
                if (this.hasStroke()) {
                    var w = style.lineWidth;
                    rect.x -= w / 2;
                    rect.y -= w / 2;
                    rect.width += w;
                    rect.height += w;
                }
                this._rect = rect;
            }
            return this._rect;
        };
        TSpan.initDefaultProps = (function () {
            var tspanProto = TSpan.prototype;
            tspanProto.dirtyRectTolerance = 10;
        })();
        return TSpan;
    }(Displayable));
    TSpan.prototype.type = 'tspan';

    var DEFAULT_IMAGE_STYLE = defaults({
        x: 0,
        y: 0
    }, DEFAULT_COMMON_STYLE);
    var DEFAULT_IMAGE_ANIMATION_PROPS = {
        style: defaults({
            x: true,
            y: true,
            width: true,
            height: true,
            sx: true,
            sy: true,
            sWidth: true,
            sHeight: true
        }, DEFAULT_COMMON_ANIMATION_PROPS.style)
    };
    function isImageLike(source) {
        return !!(source
            && typeof source !== 'string'
            && source.width && source.height);
    }
    var ZRImage = (function (_super) {
        __extends(ZRImage, _super);
        function ZRImage() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        ZRImage.prototype.createStyle = function (obj) {
            return createObject(DEFAULT_IMAGE_STYLE, obj);
        };
        ZRImage.prototype._getSize = function (dim) {
            var style = this.style;
            var size = style[dim];
            if (size != null) {
                return size;
            }
            var imageSource = isImageLike(style.image)
                ? style.image : this.__image;
            if (!imageSource) {
                return 0;
            }
            var otherDim = dim === 'width' ? 'height' : 'width';
            var otherDimSize = style[otherDim];
            if (otherDimSize == null) {
                return imageSource[dim];
            }
            else {
                return imageSource[dim] / imageSource[otherDim] * otherDimSize;
            }
        };
        ZRImage.prototype.getWidth = function () {
            return this._getSize('width');
        };
        ZRImage.prototype.getHeight = function () {
            return this._getSize('height');
        };
        ZRImage.prototype.getAnimationStyleProps = function () {
            return DEFAULT_IMAGE_ANIMATION_PROPS;
        };
        ZRImage.prototype.getBoundingRect = function () {
            var style = this.style;
            if (!this._rect) {
                this._rect = new BoundingRect(style.x || 0, style.y || 0, this.getWidth(), this.getHeight());
            }
            return this._rect;
        };
        return ZRImage;
    }(Displayable));
    ZRImage.prototype.type = 'image';

    function buildPath(ctx, shape) {
        var x = shape.x;
        var y = shape.y;
        var width = shape.width;
        var height = shape.height;
        var r = shape.r;
        var r1;
        var r2;
        var r3;
        var r4;
        if (width < 0) {
            x = x + width;
            width = -width;
        }
        if (height < 0) {
            y = y + height;
            height = -height;
        }
        if (typeof r === 'number') {
            r1 = r2 = r3 = r4 = r;
        }
        else if (r instanceof Array) {
            if (r.length === 1) {
                r1 = r2 = r3 = r4 = r[0];
            }
            else if (r.length === 2) {
                r1 = r3 = r[0];
                r2 = r4 = r[1];
            }
            else if (r.length === 3) {
                r1 = r[0];
                r2 = r4 = r[1];
                r3 = r[2];
            }
            else {
                r1 = r[0];
                r2 = r[1];
                r3 = r[2];
                r4 = r[3];
            }
        }
        else {
            r1 = r2 = r3 = r4 = 0;
        }
        var total;
        if (r1 + r2 > width) {
            total = r1 + r2;
            r1 *= width / total;
            r2 *= width / total;
        }
        if (r3 + r4 > width) {
            total = r3 + r4;
            r3 *= width / total;
            r4 *= width / total;
        }
        if (r2 + r3 > height) {
            total = r2 + r3;
            r2 *= height / total;
            r3 *= height / total;
        }
        if (r1 + r4 > height) {
            total = r1 + r4;
            r1 *= height / total;
            r4 *= height / total;
        }
        ctx.moveTo(x + r1, y);
        ctx.lineTo(x + width - r2, y);
        r2 !== 0 && ctx.arc(x + width - r2, y + r2, r2, -Math.PI / 2, 0);
        ctx.lineTo(x + width, y + height - r3);
        r3 !== 0 && ctx.arc(x + width - r3, y + height - r3, r3, 0, Math.PI / 2);
        ctx.lineTo(x + r4, y + height);
        r4 !== 0 && ctx.arc(x + r4, y + height - r4, r4, Math.PI / 2, Math.PI);
        ctx.lineTo(x, y + r1);
        r1 !== 0 && ctx.arc(x + r1, y + r1, r1, Math.PI, Math.PI * 1.5);
    }

    var round$1 = Math.round;
    function subPixelOptimizeLine(outputShape, inputShape, style) {
        if (!inputShape) {
            return;
        }
        var x1 = inputShape.x1;
        var x2 = inputShape.x2;
        var y1 = inputShape.y1;
        var y2 = inputShape.y2;
        outputShape.x1 = x1;
        outputShape.x2 = x2;
        outputShape.y1 = y1;
        outputShape.y2 = y2;
        var lineWidth = style && style.lineWidth;
        if (!lineWidth) {
            return outputShape;
        }
        if (round$1(x1 * 2) === round$1(x2 * 2)) {
            outputShape.x1 = outputShape.x2 = subPixelOptimize(x1, lineWidth, true);
        }
        if (round$1(y1 * 2) === round$1(y2 * 2)) {
            outputShape.y1 = outputShape.y2 = subPixelOptimize(y1, lineWidth, true);
        }
        return outputShape;
    }
    function subPixelOptimizeRect(outputShape, inputShape, style) {
        if (!inputShape) {
            return;
        }
        var originX = inputShape.x;
        var originY = inputShape.y;
        var originWidth = inputShape.width;
        var originHeight = inputShape.height;
        outputShape.x = originX;
        outputShape.y = originY;
        outputShape.width = originWidth;
        outputShape.height = originHeight;
        var lineWidth = style && style.lineWidth;
        if (!lineWidth) {
            return outputShape;
        }
        outputShape.x = subPixelOptimize(originX, lineWidth, true);
        outputShape.y = subPixelOptimize(originY, lineWidth, true);
        outputShape.width = Math.max(subPixelOptimize(originX + originWidth, lineWidth, false) - outputShape.x, originWidth === 0 ? 0 : 1);
        outputShape.height = Math.max(subPixelOptimize(originY + originHeight, lineWidth, false) - outputShape.y, originHeight === 0 ? 0 : 1);
        return outputShape;
    }
    function subPixelOptimize(position, lineWidth, positiveOrNegative) {
        if (!lineWidth) {
            return position;
        }
        var doubledPosition = round$1(position * 2);
        return (doubledPosition + round$1(lineWidth)) % 2 === 0
            ? doubledPosition / 2
            : (doubledPosition + (positiveOrNegative ? 1 : -1)) / 2;
    }

    var RectShape = (function () {
        function RectShape() {
            this.x = 0;
            this.y = 0;
            this.width = 0;
            this.height = 0;
        }
        return RectShape;
    }());
    var subPixelOptimizeOutputShape = {};
    var Rect = (function (_super) {
        __extends(Rect, _super);
        function Rect(opts) {
            return _super.call(this, opts) || this;
        }
        Rect.prototype.getDefaultShape = function () {
            return new RectShape();
        };
        Rect.prototype.buildPath = function (ctx, shape) {
            var x;
            var y;
            var width;
            var height;
            if (this.subPixelOptimize) {
                var optimizedShape = subPixelOptimizeRect(subPixelOptimizeOutputShape, shape, this.style);
                x = optimizedShape.x;
                y = optimizedShape.y;
                width = optimizedShape.width;
                height = optimizedShape.height;
                optimizedShape.r = shape.r;
                shape = optimizedShape;
            }
            else {
                x = shape.x;
                y = shape.y;
                width = shape.width;
                height = shape.height;
            }
            if (!shape.r) {
                ctx.rect(x, y, width, height);
            }
            else {
                buildPath(ctx, shape);
            }
        };
        Rect.prototype.isZeroArea = function () {
            return !this.shape.width || !this.shape.height;
        };
        return Rect;
    }(Path));
    Rect.prototype.type = 'rect';

    var DEFAULT_RICH_TEXT_COLOR = {
        fill: '#000'
    };
    var DEFAULT_STROKE_LINE_WIDTH = 2;
    var DEFAULT_TEXT_ANIMATION_PROPS = {
        style: defaults({
            fill: true,
            stroke: true,
            fillOpacity: true,
            strokeOpacity: true,
            lineWidth: true,
            fontSize: true,
            lineHeight: true,
            width: true,
            height: true,
            textShadowColor: true,
            textShadowBlur: true,
            textShadowOffsetX: true,
            textShadowOffsetY: true,
            backgroundColor: true,
            padding: true,
            borderColor: true,
            borderWidth: true,
            borderRadius: true
        }, DEFAULT_COMMON_ANIMATION_PROPS.style)
    };
    var ZRText = (function (_super) {
        __extends(ZRText, _super);
        function ZRText(opts) {
            var _this = _super.call(this) || this;
            _this.type = 'text';
            _this._children = [];
            _this._defaultStyle = DEFAULT_RICH_TEXT_COLOR;
            _this.attr(opts);
            return _this;
        }
        ZRText.prototype.childrenRef = function () {
            return this._children;
        };
        ZRText.prototype.update = function () {
            _super.prototype.update.call(this);
            if (this.styleChanged()) {
                this._updateSubTexts();
            }
            for (var i = 0; i < this._children.length; i++) {
                var child = this._children[i];
                child.zlevel = this.zlevel;
                child.z = this.z;
                child.z2 = this.z2;
                child.culling = this.culling;
                child.cursor = this.cursor;
                child.invisible = this.invisible;
            }
        };
        ZRText.prototype.updateTransform = function () {
            var innerTransformable = this.innerTransformable;
            if (innerTransformable) {
                innerTransformable.updateTransform();
                if (innerTransformable.transform) {
                    this.transform = innerTransformable.transform;
                }
            }
            else {
                _super.prototype.updateTransform.call(this);
            }
        };
        ZRText.prototype.getLocalTransform = function (m) {
            var innerTransformable = this.innerTransformable;
            return innerTransformable
                ? innerTransformable.getLocalTransform(m)
                : _super.prototype.getLocalTransform.call(this, m);
        };
        ZRText.prototype.getComputedTransform = function () {
            if (this.__hostTarget) {
                this.__hostTarget.getComputedTransform();
                this.__hostTarget.updateInnerText(true);
            }
            return _super.prototype.getComputedTransform.call(this);
        };
        ZRText.prototype._updateSubTexts = function () {
            this._childCursor = 0;
            normalizeTextStyle(this.style);
            this.style.rich
                ? this._updateRichTexts()
                : this._updatePlainTexts();
            this._children.length = this._childCursor;
            this.styleUpdated();
        };
        ZRText.prototype.addSelfToZr = function (zr) {
            _super.prototype.addSelfToZr.call(this, zr);
            for (var i = 0; i < this._children.length; i++) {
                this._children[i].__zr = zr;
            }
        };
        ZRText.prototype.removeSelfFromZr = function (zr) {
            _super.prototype.removeSelfFromZr.call(this, zr);
            for (var i = 0; i < this._children.length; i++) {
                this._children[i].__zr = null;
            }
        };
        ZRText.prototype.getBoundingRect = function () {
            if (this.styleChanged()) {
                this._updateSubTexts();
            }
            if (!this._rect) {
                var tmpRect = new BoundingRect(0, 0, 0, 0);
                var children = this._children;
                var tmpMat = [];
                var rect = null;
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    var childRect = child.getBoundingRect();
                    var transform = child.getLocalTransform(tmpMat);
                    if (transform) {
                        tmpRect.copy(childRect);
                        tmpRect.applyTransform(transform);
                        rect = rect || tmpRect.clone();
                        rect.union(tmpRect);
                    }
                    else {
                        rect = rect || childRect.clone();
                        rect.union(childRect);
                    }
                }
                this._rect = rect || tmpRect;
            }
            return this._rect;
        };
        ZRText.prototype.setDefaultTextStyle = function (defaultTextStyle) {
            this._defaultStyle = defaultTextStyle || DEFAULT_RICH_TEXT_COLOR;
        };
        ZRText.prototype.setTextContent = function (textContent) {
            if ("development" !== 'production') {
                throw new Error('Can\'t attach text on another text');
            }
        };
        ZRText.prototype._mergeStyle = function (targetStyle, sourceStyle) {
            if (!sourceStyle) {
                return targetStyle;
            }
            var sourceRich = sourceStyle.rich;
            var targetRich = targetStyle.rich || (sourceRich && {});
            extend(targetStyle, sourceStyle);
            if (sourceRich && targetRich) {
                this._mergeRich(targetRich, sourceRich);
                targetStyle.rich = targetRich;
            }
            else if (targetRich) {
                targetStyle.rich = targetRich;
            }
            return targetStyle;
        };
        ZRText.prototype._mergeRich = function (targetRich, sourceRich) {
            var richNames = keys(sourceRich);
            for (var i = 0; i < richNames.length; i++) {
                var richName = richNames[i];
                targetRich[richName] = targetRich[richName] || {};
                extend(targetRich[richName], sourceRich[richName]);
            }
        };
        ZRText.prototype.getAnimationStyleProps = function () {
            return DEFAULT_TEXT_ANIMATION_PROPS;
        };
        ZRText.prototype._getOrCreateChild = function (Ctor) {
            var child = this._children[this._childCursor];
            if (!child || !(child instanceof Ctor)) {
                child = new Ctor();
            }
            this._children[this._childCursor++] = child;
            child.__zr = this.__zr;
            child.parent = this;
            return child;
        };
        ZRText.prototype._updatePlainTexts = function () {
            var style = this.style;
            var textFont = style.font || DEFAULT_FONT;
            var textPadding = style.padding;
            var text = getStyleText(style);
            var contentBlock = parsePlainText(text, style);
            var needDrawBg = needDrawBackground(style);
            var bgColorDrawn = !!(style.backgroundColor);
            var outerHeight = contentBlock.outerHeight;
            var outerWidth = contentBlock.outerWidth;
            var contentWidth = contentBlock.contentWidth;
            var textLines = contentBlock.lines;
            var lineHeight = contentBlock.lineHeight;
            var defaultStyle = this._defaultStyle;
            var baseX = style.x || 0;
            var baseY = style.y || 0;
            var textAlign = style.align || defaultStyle.align || 'left';
            var verticalAlign = style.verticalAlign || defaultStyle.verticalAlign || 'top';
            var textX = baseX;
            var textY = adjustTextY$1(baseY, contentBlock.contentHeight, verticalAlign);
            if (needDrawBg || textPadding) {
                var boxX = adjustTextX(baseX, outerWidth, textAlign);
                var boxY = adjustTextY$1(baseY, outerHeight, verticalAlign);
                needDrawBg && this._renderBackground(style, style, boxX, boxY, outerWidth, outerHeight);
            }
            textY += lineHeight / 2;
            if (textPadding) {
                textX = getTextXForPadding(baseX, textAlign, textPadding);
                if (verticalAlign === 'top') {
                    textY += textPadding[0];
                }
                else if (verticalAlign === 'bottom') {
                    textY -= textPadding[2];
                }
            }
            var defaultLineWidth = 0;
            var useDefaultFill = false;
            var textFill = getFill('fill' in style
                ? style.fill
                : (useDefaultFill = true, defaultStyle.fill));
            var textStroke = getStroke('stroke' in style
                ? style.stroke
                : (!bgColorDrawn
                    && (!defaultStyle.autoStroke || useDefaultFill))
                    ? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, defaultStyle.stroke)
                    : null);
            var hasShadow = style.textShadowBlur > 0;
            var fixedBoundingRect = style.width != null
                && (style.overflow === 'truncate' || style.overflow === 'break' || style.overflow === 'breakAll');
            var calculatedLineHeight = contentBlock.calculatedLineHeight;
            for (var i = 0; i < textLines.length; i++) {
                var el = this._getOrCreateChild(TSpan);
                var subElStyle = el.createStyle();
                el.useStyle(subElStyle);
                subElStyle.text = textLines[i];
                subElStyle.x = textX;
                subElStyle.y = textY;
                if (textAlign) {
                    subElStyle.textAlign = textAlign;
                }
                subElStyle.textBaseline = 'middle';
                subElStyle.opacity = style.opacity;
                subElStyle.strokeFirst = true;
                if (hasShadow) {
                    subElStyle.shadowBlur = style.textShadowBlur || 0;
                    subElStyle.shadowColor = style.textShadowColor || 'transparent';
                    subElStyle.shadowOffsetX = style.textShadowOffsetX || 0;
                    subElStyle.shadowOffsetY = style.textShadowOffsetY || 0;
                }
                subElStyle.stroke = textStroke;
                subElStyle.fill = textFill;
                if (textStroke) {
                    subElStyle.lineWidth = style.lineWidth || defaultLineWidth;
                    subElStyle.lineDash = style.lineDash;
                    subElStyle.lineDashOffset = style.lineDashOffset || 0;
                }
                subElStyle.font = textFont;
                setSeparateFont(subElStyle, style);
                textY += lineHeight;
                if (fixedBoundingRect) {
                    el.setBoundingRect(new BoundingRect(adjustTextX(subElStyle.x, style.width, subElStyle.textAlign), adjustTextY$1(subElStyle.y, calculatedLineHeight, subElStyle.textBaseline), contentWidth, calculatedLineHeight));
                }
            }
        };
        ZRText.prototype._updateRichTexts = function () {
            var style = this.style;
            var text = getStyleText(style);
            var contentBlock = parseRichText(text, style);
            var contentWidth = contentBlock.width;
            var outerWidth = contentBlock.outerWidth;
            var outerHeight = contentBlock.outerHeight;
            var textPadding = style.padding;
            var baseX = style.x || 0;
            var baseY = style.y || 0;
            var defaultStyle = this._defaultStyle;
            var textAlign = style.align || defaultStyle.align;
            var verticalAlign = style.verticalAlign || defaultStyle.verticalAlign;
            var boxX = adjustTextX(baseX, outerWidth, textAlign);
            var boxY = adjustTextY$1(baseY, outerHeight, verticalAlign);
            var xLeft = boxX;
            var lineTop = boxY;
            if (textPadding) {
                xLeft += textPadding[3];
                lineTop += textPadding[0];
            }
            var xRight = xLeft + contentWidth;
            if (needDrawBackground(style)) {
                this._renderBackground(style, style, boxX, boxY, outerWidth, outerHeight);
            }
            var bgColorDrawn = !!(style.backgroundColor);
            for (var i = 0; i < contentBlock.lines.length; i++) {
                var line = contentBlock.lines[i];
                var tokens = line.tokens;
                var tokenCount = tokens.length;
                var lineHeight = line.lineHeight;
                var remainedWidth = line.width;
                var leftIndex = 0;
                var lineXLeft = xLeft;
                var lineXRight = xRight;
                var rightIndex = tokenCount - 1;
                var token = void 0;
                while (leftIndex < tokenCount
                    && (token = tokens[leftIndex], !token.align || token.align === 'left')) {
                    this._placeToken(token, style, lineHeight, lineTop, lineXLeft, 'left', bgColorDrawn);
                    remainedWidth -= token.width;
                    lineXLeft += token.width;
                    leftIndex++;
                }
                while (rightIndex >= 0
                    && (token = tokens[rightIndex], token.align === 'right')) {
                    this._placeToken(token, style, lineHeight, lineTop, lineXRight, 'right', bgColorDrawn);
                    remainedWidth -= token.width;
                    lineXRight -= token.width;
                    rightIndex--;
                }
                lineXLeft += (contentWidth - (lineXLeft - xLeft) - (xRight - lineXRight) - remainedWidth) / 2;
                while (leftIndex <= rightIndex) {
                    token = tokens[leftIndex];
                    this._placeToken(token, style, lineHeight, lineTop, lineXLeft + token.width / 2, 'center', bgColorDrawn);
                    lineXLeft += token.width;
                    leftIndex++;
                }
                lineTop += lineHeight;
            }
        };
        ZRText.prototype._placeToken = function (token, style, lineHeight, lineTop, x, textAlign, parentBgColorDrawn) {
            var tokenStyle = style.rich[token.styleName] || {};
            tokenStyle.text = token.text;
            var verticalAlign = token.verticalAlign;
            var y = lineTop + lineHeight / 2;
            if (verticalAlign === 'top') {
                y = lineTop + token.height / 2;
            }
            else if (verticalAlign === 'bottom') {
                y = lineTop + lineHeight - token.height / 2;
            }
            var needDrawBg = !token.isLineHolder && needDrawBackground(tokenStyle);
            needDrawBg && this._renderBackground(tokenStyle, style, textAlign === 'right'
                ? x - token.width
                : textAlign === 'center'
                    ? x - token.width / 2
                    : x, y - token.height / 2, token.width, token.height);
            var bgColorDrawn = !!tokenStyle.backgroundColor;
            var textPadding = token.textPadding;
            if (textPadding) {
                x = getTextXForPadding(x, textAlign, textPadding);
                y -= token.height / 2 - textPadding[0] - token.innerHeight / 2;
            }
            var el = this._getOrCreateChild(TSpan);
            var subElStyle = el.createStyle();
            el.useStyle(subElStyle);
            var defaultStyle = this._defaultStyle;
            var useDefaultFill = false;
            var defaultLineWidth = 0;
            var textFill = getFill('fill' in tokenStyle ? tokenStyle.fill
                : 'fill' in style ? style.fill
                    : (useDefaultFill = true, defaultStyle.fill));
            var textStroke = getStroke('stroke' in tokenStyle ? tokenStyle.stroke
                : 'stroke' in style ? style.stroke
                    : (!bgColorDrawn
                        && !parentBgColorDrawn
                        && (!defaultStyle.autoStroke || useDefaultFill)) ? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, defaultStyle.stroke)
                        : null);
            var hasShadow = tokenStyle.textShadowBlur > 0
                || style.textShadowBlur > 0;
            subElStyle.text = token.text;
            subElStyle.x = x;
            subElStyle.y = y;
            if (hasShadow) {
                subElStyle.shadowBlur = tokenStyle.textShadowBlur || style.textShadowBlur || 0;
                subElStyle.shadowColor = tokenStyle.textShadowColor || style.textShadowColor || 'transparent';
                subElStyle.shadowOffsetX = tokenStyle.textShadowOffsetX || style.textShadowOffsetX || 0;
                subElStyle.shadowOffsetY = tokenStyle.textShadowOffsetY || style.textShadowOffsetY || 0;
            }
            subElStyle.textAlign = textAlign;
            subElStyle.textBaseline = 'middle';
            subElStyle.font = token.font || DEFAULT_FONT;
            subElStyle.opacity = retrieve3(tokenStyle.opacity, style.opacity, 1);
            setSeparateFont(subElStyle, tokenStyle);
            if (textStroke) {
                subElStyle.lineWidth = retrieve3(tokenStyle.lineWidth, style.lineWidth, defaultLineWidth);
                subElStyle.lineDash = retrieve2(tokenStyle.lineDash, style.lineDash);
                subElStyle.lineDashOffset = style.lineDashOffset || 0;
                subElStyle.stroke = textStroke;
            }
            if (textFill) {
                subElStyle.fill = textFill;
            }
            var textWidth = token.contentWidth;
            var textHeight = token.contentHeight;
            el.setBoundingRect(new BoundingRect(adjustTextX(subElStyle.x, textWidth, subElStyle.textAlign), adjustTextY$1(subElStyle.y, textHeight, subElStyle.textBaseline), textWidth, textHeight));
        };
        ZRText.prototype._renderBackground = function (style, topStyle, x, y, width, height) {
            var textBackgroundColor = style.backgroundColor;
            var textBorderWidth = style.borderWidth;
            var textBorderColor = style.borderColor;
            var isImageBg = textBackgroundColor && textBackgroundColor.image;
            var isPlainOrGradientBg = textBackgroundColor && !isImageBg;
            var textBorderRadius = style.borderRadius;
            var self = this;
            var rectEl;
            var imgEl;
            if (isPlainOrGradientBg || style.lineHeight || (textBorderWidth && textBorderColor)) {
                rectEl = this._getOrCreateChild(Rect);
                rectEl.useStyle(rectEl.createStyle());
                rectEl.style.fill = null;
                var rectShape = rectEl.shape;
                rectShape.x = x;
                rectShape.y = y;
                rectShape.width = width;
                rectShape.height = height;
                rectShape.r = textBorderRadius;
                rectEl.dirtyShape();
            }
            if (isPlainOrGradientBg) {
                var rectStyle = rectEl.style;
                rectStyle.fill = textBackgroundColor || null;
                rectStyle.fillOpacity = retrieve2(style.fillOpacity, 1);
            }
            else if (isImageBg) {
                imgEl = this._getOrCreateChild(ZRImage);
                imgEl.onload = function () {
                    self.dirtyStyle();
                };
                var imgStyle = imgEl.style;
                imgStyle.image = textBackgroundColor.image;
                imgStyle.x = x;
                imgStyle.y = y;
                imgStyle.width = width;
                imgStyle.height = height;
            }
            if (textBorderWidth && textBorderColor) {
                var rectStyle = rectEl.style;
                rectStyle.lineWidth = textBorderWidth;
                rectStyle.stroke = textBorderColor;
                rectStyle.strokeOpacity = retrieve2(style.strokeOpacity, 1);
                rectStyle.lineDash = style.borderDash;
                rectStyle.lineDashOffset = style.borderDashOffset || 0;
                rectEl.strokeContainThreshold = 0;
                if (rectEl.hasFill() && rectEl.hasStroke()) {
                    rectStyle.strokeFirst = true;
                    rectStyle.lineWidth *= 2;
                }
            }
            var commonStyle = (rectEl || imgEl).style;
            commonStyle.shadowBlur = style.shadowBlur || 0;
            commonStyle.shadowColor = style.shadowColor || 'transparent';
            commonStyle.shadowOffsetX = style.shadowOffsetX || 0;
            commonStyle.shadowOffsetY = style.shadowOffsetY || 0;
            commonStyle.opacity = retrieve3(style.opacity, topStyle.opacity, 1);
        };
        ZRText.makeFont = function (style) {
            var font = '';
            if (hasSeparateFont(style)) {
                font = [
                    style.fontStyle,
                    style.fontWeight,
                    parseFontSize(style.fontSize),
                    style.fontFamily || 'sans-serif'
                ].join(' ');
            }
            return font && trim(font) || style.textFont || style.font;
        };
        return ZRText;
    }(Displayable));
    var VALID_TEXT_ALIGN = { left: true, right: 1, center: 1 };
    var VALID_TEXT_VERTICAL_ALIGN = { top: 1, bottom: 1, middle: 1 };
    var FONT_PARTS = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily'];
    function parseFontSize(fontSize) {
        if (typeof fontSize === 'string'
            && (fontSize.indexOf('px') !== -1
                || fontSize.indexOf('rem') !== -1
                || fontSize.indexOf('em') !== -1)) {
            return fontSize;
        }
        else if (!isNaN(+fontSize)) {
            return fontSize + 'px';
        }
        else {
            return DEFAULT_FONT_SIZE + 'px';
        }
    }
    function setSeparateFont(targetStyle, sourceStyle) {
        for (var i = 0; i < FONT_PARTS.length; i++) {
            var fontProp = FONT_PARTS[i];
            var val = sourceStyle[fontProp];
            if (val != null) {
                targetStyle[fontProp] = val;
            }
        }
    }
    function hasSeparateFont(style) {
        return style.fontSize != null || style.fontFamily || style.fontWeight;
    }
    function normalizeTextStyle(style) {
        normalizeStyle(style);
        each(style.rich, normalizeStyle);
        return style;
    }
    function normalizeStyle(style) {
        if (style) {
            style.font = ZRText.makeFont(style);
            var textAlign = style.align;
            textAlign === 'middle' && (textAlign = 'center');
            style.align = (textAlign == null || VALID_TEXT_ALIGN[textAlign]) ? textAlign : 'left';
            var verticalAlign = style.verticalAlign;
            verticalAlign === 'center' && (verticalAlign = 'middle');
            style.verticalAlign = (verticalAlign == null || VALID_TEXT_VERTICAL_ALIGN[verticalAlign]) ? verticalAlign : 'top';
            var textPadding = style.padding;
            if (textPadding) {
                style.padding = normalizeCssArray(style.padding);
            }
        }
    }
    function getStroke(stroke, lineWidth) {
        return (stroke == null || lineWidth <= 0 || stroke === 'transparent' || stroke === 'none')
            ? null
            : (stroke.image || stroke.colorStops)
                ? '#000'
                : stroke;
    }
    function getFill(fill) {
        return (fill == null || fill === 'none')
            ? null
            : (fill.image || fill.colorStops)
                ? '#000'
                : fill;
    }
    function getTextXForPadding(x, textAlign, textPadding) {
        return textAlign === 'right'
            ? (x - textPadding[1])
            : textAlign === 'center'
                ? (x + textPadding[3] / 2 - textPadding[1] / 2)
                : (x + textPadding[3]);
    }
    function getStyleText(style) {
        var text = style.text;
        text != null && (text += '');
        return text;
    }
    function needDrawBackground(style) {
        return !!(style.backgroundColor
            || style.lineHeight
            || (style.borderWidth && style.borderColor));
    }

    var getECData = makeInner();
    var setCommonECData = function (seriesIndex, dataType, dataIdx, el) {
      if (el) {
        var ecData = getECData(el); // Add data index and series index for indexing the data by element
        // Useful in tooltip

        ecData.dataIndex = dataIdx;
        ecData.dataType = dataType;
        ecData.seriesIndex = seriesIndex; // TODO: not store dataIndex on children.

        if (el.type === 'group') {
          el.traverse(function (child) {
            var childECData = getECData(child);
            childECData.seriesIndex = seriesIndex;
            childECData.dataIndex = dataIdx;
            childECData.dataType = dataType;
          });
        }
      }
    };

    var _highlightNextDigit = 1;
    var _highlightKeyMap = {};
    var getSavedStates = makeInner();
    var getComponentStates = makeInner();
    var HOVER_STATE_NORMAL = 0;
    var HOVER_STATE_BLUR = 1;
    var HOVER_STATE_EMPHASIS = 2;
    var SPECIAL_STATES = ['emphasis', 'blur', 'select'];
    var DISPLAY_STATES = ['normal', 'emphasis', 'blur', 'select'];
    var Z2_EMPHASIS_LIFT = 10;
    var Z2_SELECT_LIFT = 9;
    var HIGHLIGHT_ACTION_TYPE = 'highlight';
    var DOWNPLAY_ACTION_TYPE = 'downplay';
    var SELECT_ACTION_TYPE = 'select';
    var UNSELECT_ACTION_TYPE = 'unselect';
    var TOGGLE_SELECT_ACTION_TYPE = 'toggleSelect';

    function hasFillOrStroke(fillOrStroke) {
      return fillOrStroke != null && fillOrStroke !== 'none';
    } // Most lifted color are duplicated.


    var liftedColorCache = new LRU(100);

    function liftColor(color$1) {
      if (isString(color$1)) {
        var liftedColor = liftedColorCache.get(color$1);

        if (!liftedColor) {
          liftedColor = lift(color$1, -0.1);
          liftedColorCache.put(color$1, liftedColor);
        }

        return liftedColor;
      } else if (isGradientObject(color$1)) {
        var ret = extend({}, color$1);
        ret.colorStops = map(color$1.colorStops, function (stop) {
          return {
            offset: stop.offset,
            color: lift(stop.color, -0.1)
          };
        });
        return ret;
      } // Change nothing.


      return color$1;
    }

    function doChangeHoverState(el, stateName, hoverStateEnum) {
      if (el.onHoverStateChange && (el.hoverState || 0) !== hoverStateEnum) {
        el.onHoverStateChange(stateName);
      }

      el.hoverState = hoverStateEnum;
    }

    function singleEnterEmphasis(el) {
      // Only mark the flag.
      // States will be applied in the echarts.ts in next frame.
      doChangeHoverState(el, 'emphasis', HOVER_STATE_EMPHASIS);
    }

    function singleLeaveEmphasis(el) {
      // Only mark the flag.
      // States will be applied in the echarts.ts in next frame.
      if (el.hoverState === HOVER_STATE_EMPHASIS) {
        doChangeHoverState(el, 'normal', HOVER_STATE_NORMAL);
      }
    }

    function singleEnterBlur(el) {
      doChangeHoverState(el, 'blur', HOVER_STATE_BLUR);
    }

    function singleLeaveBlur(el) {
      if (el.hoverState === HOVER_STATE_BLUR) {
        doChangeHoverState(el, 'normal', HOVER_STATE_NORMAL);
      }
    }

    function singleEnterSelect(el) {
      el.selected = true;
    }

    function singleLeaveSelect(el) {
      el.selected = false;
    }

    function updateElementState(el, updater, commonParam) {
      updater(el, commonParam);
    }

    function traverseUpdateState(el, updater, commonParam) {
      updateElementState(el, updater, commonParam);
      el.isGroup && el.traverse(function (child) {
        updateElementState(child, updater, commonParam);
      });
    }

    function setStatesFlag(el, stateName) {
      switch (stateName) {
        case 'emphasis':
          el.hoverState = HOVER_STATE_EMPHASIS;
          break;

        case 'normal':
          el.hoverState = HOVER_STATE_NORMAL;
          break;

        case 'blur':
          el.hoverState = HOVER_STATE_BLUR;
          break;

        case 'select':
          el.selected = true;
      }
    }

    function getFromStateStyle(el, props, toStateName, defaultValue) {
      var style = el.style;
      var fromState = {};

      for (var i = 0; i < props.length; i++) {
        var propName = props[i];
        var val = style[propName];
        fromState[propName] = val == null ? defaultValue && defaultValue[propName] : val;
      }

      for (var i = 0; i < el.animators.length; i++) {
        var animator = el.animators[i];

        if (animator.__fromStateTransition // Don't consider the animation to emphasis state.
        && animator.__fromStateTransition.indexOf(toStateName) < 0 && animator.targetName === 'style') {
          animator.saveTo(fromState, props);
        }
      }

      return fromState;
    }

    function createEmphasisDefaultState(el, stateName, targetStates, state) {
      var hasSelect = targetStates && indexOf(targetStates, 'select') >= 0;
      var cloned = false;

      if (el instanceof Path) {
        var store = getSavedStates(el);
        var fromFill = hasSelect ? store.selectFill || store.normalFill : store.normalFill;
        var fromStroke = hasSelect ? store.selectStroke || store.normalStroke : store.normalStroke;

        if (hasFillOrStroke(fromFill) || hasFillOrStroke(fromStroke)) {
          state = state || {};
          var emphasisStyle = state.style || {}; // inherit case

          if (emphasisStyle.fill === 'inherit') {
            cloned = true;
            state = extend({}, state);
            emphasisStyle = extend({}, emphasisStyle);
            emphasisStyle.fill = fromFill;
          } // Apply default color lift
          else if (!hasFillOrStroke(emphasisStyle.fill) && hasFillOrStroke(fromFill)) {
              cloned = true; // Not modify the original value.

              state = extend({}, state);
              emphasisStyle = extend({}, emphasisStyle); // Already being applied 'emphasis'. DON'T lift color multiple times.

              emphasisStyle.fill = liftColor(fromFill);
            } // Not highlight stroke if fill has been highlighted.
            else if (!hasFillOrStroke(emphasisStyle.stroke) && hasFillOrStroke(fromStroke)) {
                if (!cloned) {
                  state = extend({}, state);
                  emphasisStyle = extend({}, emphasisStyle);
                }

                emphasisStyle.stroke = liftColor(fromStroke);
              }

          state.style = emphasisStyle;
        }
      }

      if (state) {
        // TODO Share with textContent?
        if (state.z2 == null) {
          if (!cloned) {
            state = extend({}, state);
          }

          var z2EmphasisLift = el.z2EmphasisLift;
          state.z2 = el.z2 + (z2EmphasisLift != null ? z2EmphasisLift : Z2_EMPHASIS_LIFT);
        }
      }

      return state;
    }

    function createSelectDefaultState(el, stateName, state) {
      // const hasSelect = indexOf(el.currentStates, stateName) >= 0;
      if (state) {
        // TODO Share with textContent?
        if (state.z2 == null) {
          state = extend({}, state);
          var z2SelectLift = el.z2SelectLift;
          state.z2 = el.z2 + (z2SelectLift != null ? z2SelectLift : Z2_SELECT_LIFT);
        }
      }

      return state;
    }

    function createBlurDefaultState(el, stateName, state) {
      var hasBlur = indexOf(el.currentStates, stateName) >= 0;
      var currentOpacity = el.style.opacity;
      var fromState = !hasBlur ? getFromStateStyle(el, ['opacity'], stateName, {
        opacity: 1
      }) : null;
      state = state || {};
      var blurStyle = state.style || {};

      if (blurStyle.opacity == null) {
        // clone state
        state = extend({}, state);
        blurStyle = extend({
          // Already being applied 'emphasis'. DON'T mul opacity multiple times.
          opacity: hasBlur ? currentOpacity : fromState.opacity * 0.1
        }, blurStyle);
        state.style = blurStyle;
      }

      return state;
    }

    function elementStateProxy(stateName, targetStates) {
      var state = this.states[stateName];

      if (this.style) {
        if (stateName === 'emphasis') {
          return createEmphasisDefaultState(this, stateName, targetStates, state);
        } else if (stateName === 'blur') {
          return createBlurDefaultState(this, stateName, state);
        } else if (stateName === 'select') {
          return createSelectDefaultState(this, stateName, state);
        }
      }

      return state;
    }
    /**
     * Set hover style (namely "emphasis style") of element.
     * @param el Should not be `zrender/graphic/Group`.
     * @param focus 'self' | 'selfInSeries' | 'series'
     */


    function setDefaultStateProxy(el) {
      el.stateProxy = elementStateProxy;
      var textContent = el.getTextContent();
      var textGuide = el.getTextGuideLine();

      if (textContent) {
        textContent.stateProxy = elementStateProxy;
      }

      if (textGuide) {
        textGuide.stateProxy = elementStateProxy;
      }
    }
    function enterEmphasisWhenMouseOver(el, e) {
      !shouldSilent(el, e) // "emphasis" event highlight has higher priority than mouse highlight.
      && !el.__highByOuter && traverseUpdateState(el, singleEnterEmphasis);
    }
    function leaveEmphasisWhenMouseOut(el, e) {
      !shouldSilent(el, e) // "emphasis" event highlight has higher priority than mouse highlight.
      && !el.__highByOuter && traverseUpdateState(el, singleLeaveEmphasis);
    }
    function enterEmphasis(el, highlightDigit) {
      el.__highByOuter |= 1 << (highlightDigit || 0);
      traverseUpdateState(el, singleEnterEmphasis);
    }
    function leaveEmphasis(el, highlightDigit) {
      !(el.__highByOuter &= ~(1 << (highlightDigit || 0))) && traverseUpdateState(el, singleLeaveEmphasis);
    }
    function enterBlur(el) {
      traverseUpdateState(el, singleEnterBlur);
    }
    function leaveBlur(el) {
      traverseUpdateState(el, singleLeaveBlur);
    }
    function enterSelect(el) {
      traverseUpdateState(el, singleEnterSelect);
    }
    function leaveSelect(el) {
      traverseUpdateState(el, singleLeaveSelect);
    }

    function shouldSilent(el, e) {
      return el.__highDownSilentOnTouch && e.zrByTouch;
    }

    function allLeaveBlur(api) {
      var model = api.getModel();
      var leaveBlurredSeries = [];
      var allComponentViews = [];
      model.eachComponent(function (componentType, componentModel) {
        var componentStates = getComponentStates(componentModel);
        var isSeries = componentType === 'series';
        var view = isSeries ? api.getViewOfSeriesModel(componentModel) : api.getViewOfComponentModel(componentModel);
        !isSeries && allComponentViews.push(view);

        if (componentStates.isBlured) {
          // Leave blur anyway
          view.group.traverse(function (child) {
            singleLeaveBlur(child);
          });
          isSeries && leaveBlurredSeries.push(componentModel);
        }

        componentStates.isBlured = false;
      });
      each(allComponentViews, function (view) {
        if (view && view.toggleBlurSeries) {
          view.toggleBlurSeries(leaveBlurredSeries, false, model);
        }
      });
    }
    function blurSeries(targetSeriesIndex, focus, blurScope, api) {
      var ecModel = api.getModel();
      blurScope = blurScope || 'coordinateSystem';

      function leaveBlurOfIndices(data, dataIndices) {
        for (var i = 0; i < dataIndices.length; i++) {
          var itemEl = data.getItemGraphicEl(dataIndices[i]);
          itemEl && leaveBlur(itemEl);
        }
      }

      if (targetSeriesIndex == null) {
        return;
      }

      if (!focus || focus === 'none') {
        return;
      }

      var targetSeriesModel = ecModel.getSeriesByIndex(targetSeriesIndex);
      var targetCoordSys = targetSeriesModel.coordinateSystem;

      if (targetCoordSys && targetCoordSys.master) {
        targetCoordSys = targetCoordSys.master;
      }

      var blurredSeries = [];
      ecModel.eachSeries(function (seriesModel) {
        var sameSeries = targetSeriesModel === seriesModel;
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys && coordSys.master) {
          coordSys = coordSys.master;
        }

        var sameCoordSys = coordSys && targetCoordSys ? coordSys === targetCoordSys : sameSeries; // If there is no coordinate system. use sameSeries instead.

        if (!( // Not blur other series if blurScope series
        blurScope === 'series' && !sameSeries // Not blur other coordinate system if blurScope is coordinateSystem
        || blurScope === 'coordinateSystem' && !sameCoordSys // Not blur self series if focus is series.
        || focus === 'series' && sameSeries // TODO blurScope: coordinate system
        )) {
          var view = api.getViewOfSeriesModel(seriesModel);
          view.group.traverse(function (child) {
            singleEnterBlur(child);
          });

          if (isArrayLike(focus)) {
            leaveBlurOfIndices(seriesModel.getData(), focus);
          } else if (isObject(focus)) {
            var dataTypes = keys(focus);

            for (var d = 0; d < dataTypes.length; d++) {
              leaveBlurOfIndices(seriesModel.getData(dataTypes[d]), focus[dataTypes[d]]);
            }
          }

          blurredSeries.push(seriesModel);
          getComponentStates(seriesModel).isBlured = true;
        }
      });
      ecModel.eachComponent(function (componentType, componentModel) {
        if (componentType === 'series') {
          return;
        }

        var view = api.getViewOfComponentModel(componentModel);

        if (view && view.toggleBlurSeries) {
          view.toggleBlurSeries(blurredSeries, true, ecModel);
        }
      });
    }
    function blurComponent(componentMainType, componentIndex, api) {
      if (componentMainType == null || componentIndex == null) {
        return;
      }

      var componentModel = api.getModel().getComponent(componentMainType, componentIndex);

      if (!componentModel) {
        return;
      }

      getComponentStates(componentModel).isBlured = true;
      var view = api.getViewOfComponentModel(componentModel);

      if (!view || !view.focusBlurEnabled) {
        return;
      }

      view.group.traverse(function (child) {
        singleEnterBlur(child);
      });
    }
    function blurSeriesFromHighlightPayload(seriesModel, payload, api) {
      var seriesIndex = seriesModel.seriesIndex;
      var data = seriesModel.getData(payload.dataType);

      if (!data) {
        if ("development" !== 'production') {
          error("Unknown dataType " + payload.dataType);
        }

        return;
      }

      var dataIndex = queryDataIndex(data, payload); // Pick the first one if there is multiple/none exists.

      dataIndex = (isArray(dataIndex) ? dataIndex[0] : dataIndex) || 0;
      var el = data.getItemGraphicEl(dataIndex);

      if (!el) {
        var count = data.count();
        var current = 0; // If data on dataIndex is NaN.

        while (!el && current < count) {
          el = data.getItemGraphicEl(current++);
        }
      }

      if (el) {
        var ecData = getECData(el);
        blurSeries(seriesIndex, ecData.focus, ecData.blurScope, api);
      } else {
        // If there is no element put on the data. Try getting it from raw option
        // TODO Should put it on seriesModel?
        var focus_1 = seriesModel.get(['emphasis', 'focus']);
        var blurScope = seriesModel.get(['emphasis', 'blurScope']);

        if (focus_1 != null) {
          blurSeries(seriesIndex, focus_1, blurScope, api);
        }
      }
    }
    function findComponentHighDownDispatchers(componentMainType, componentIndex, name, api) {
      var ret = {
        focusSelf: false,
        dispatchers: null
      };

      if (componentMainType == null || componentMainType === 'series' || componentIndex == null || name == null) {
        return ret;
      }

      var componentModel = api.getModel().getComponent(componentMainType, componentIndex);

      if (!componentModel) {
        return ret;
      }

      var view = api.getViewOfComponentModel(componentModel);

      if (!view || !view.findHighDownDispatchers) {
        return ret;
      }

      var dispatchers = view.findHighDownDispatchers(name); // At presnet, the component (like Geo) only blur inside itself.
      // So we do not use `blurScope` in component.

      var focusSelf;

      for (var i = 0; i < dispatchers.length; i++) {
        if ("development" !== 'production' && !isHighDownDispatcher(dispatchers[i])) {
          error('param should be highDownDispatcher');
        }

        if (getECData(dispatchers[i]).focus === 'self') {
          focusSelf = true;
          break;
        }
      }

      return {
        focusSelf: focusSelf,
        dispatchers: dispatchers
      };
    }
    function handleGlobalMouseOverForHighDown(dispatcher, e, api) {
      if ("development" !== 'production' && !isHighDownDispatcher(dispatcher)) {
        error('param should be highDownDispatcher');
      }

      var ecData = getECData(dispatcher);

      var _a = findComponentHighDownDispatchers(ecData.componentMainType, ecData.componentIndex, ecData.componentHighDownName, api),
          dispatchers = _a.dispatchers,
          focusSelf = _a.focusSelf; // If `findHighDownDispatchers` is supported on the component,
      // highlight/downplay elements with the same name.


      if (dispatchers) {
        if (focusSelf) {
          blurComponent(ecData.componentMainType, ecData.componentIndex, api);
        }

        each(dispatchers, function (dispatcher) {
          return enterEmphasisWhenMouseOver(dispatcher, e);
        });
      } else {
        // Try blur all in the related series. Then emphasis the hoverred.
        // TODO. progressive mode.
        blurSeries(ecData.seriesIndex, ecData.focus, ecData.blurScope, api);

        if (ecData.focus === 'self') {
          blurComponent(ecData.componentMainType, ecData.componentIndex, api);
        } // Other than series, component that not support `findHighDownDispatcher` will
        // also use it. But in this case, highlight/downplay are only supported in
        // mouse hover but not in dispatchAction.


        enterEmphasisWhenMouseOver(dispatcher, e);
      }
    }
    function handleGlobalMouseOutForHighDown(dispatcher, e, api) {
      if ("development" !== 'production' && !isHighDownDispatcher(dispatcher)) {
        error('param should be highDownDispatcher');
      }

      allLeaveBlur(api);
      var ecData = getECData(dispatcher);
      var dispatchers = findComponentHighDownDispatchers(ecData.componentMainType, ecData.componentIndex, ecData.componentHighDownName, api).dispatchers;

      if (dispatchers) {
        each(dispatchers, function (dispatcher) {
          return leaveEmphasisWhenMouseOut(dispatcher, e);
        });
      } else {
        leaveEmphasisWhenMouseOut(dispatcher, e);
      }
    }
    function toggleSelectionFromPayload(seriesModel, payload, api) {
      if (!isSelectChangePayload(payload)) {
        return;
      }

      var dataType = payload.dataType;
      var data = seriesModel.getData(dataType);
      var dataIndex = queryDataIndex(data, payload);

      if (!isArray(dataIndex)) {
        dataIndex = [dataIndex];
      }

      seriesModel[payload.type === TOGGLE_SELECT_ACTION_TYPE ? 'toggleSelect' : payload.type === SELECT_ACTION_TYPE ? 'select' : 'unselect'](dataIndex, dataType);
    }
    function updateSeriesElementSelection(seriesModel) {
      var allData = seriesModel.getAllData();
      each(allData, function (_a) {
        var data = _a.data,
            type = _a.type;
        data.eachItemGraphicEl(function (el, idx) {
          seriesModel.isSelected(idx, type) ? enterSelect(el) : leaveSelect(el);
        });
      });
    }
    function getAllSelectedIndices(ecModel) {
      var ret = [];
      ecModel.eachSeries(function (seriesModel) {
        var allData = seriesModel.getAllData();
        each(allData, function (_a) {
          var data = _a.data,
              type = _a.type;
          var dataIndices = seriesModel.getSelectedDataIndices();

          if (dataIndices.length > 0) {
            var item = {
              dataIndex: dataIndices,
              seriesIndex: seriesModel.seriesIndex
            };

            if (type != null) {
              item.dataType = type;
            }

            ret.push(item);
          }
        });
      });
      return ret;
    }
    /**
     * Enable the function that mouseover will trigger the emphasis state.
     *
     * NOTE:
     * This function should be used on the element with dataIndex, seriesIndex.
     *
     */

    function enableHoverEmphasis(el, focus, blurScope) {
      setAsHighDownDispatcher(el, true);
      traverseUpdateState(el, setDefaultStateProxy);
      enableHoverFocus(el, focus, blurScope);
    }
    function disableHoverEmphasis(el) {
      setAsHighDownDispatcher(el, false);
    }
    function toggleHoverEmphasis(el, focus, blurScope, isDisabled) {
      isDisabled ? disableHoverEmphasis(el) : enableHoverEmphasis(el, focus, blurScope);
    }
    function enableHoverFocus(el, focus, blurScope) {
      var ecData = getECData(el);

      if (focus != null) {
        // TODO dataIndex may be set after this function. This check is not useful.
        // if (ecData.dataIndex == null) {
        //     if (__DEV__) {
        //         console.warn('focus can only been set on element with dataIndex');
        //     }
        // }
        // else {
        ecData.focus = focus;
        ecData.blurScope = blurScope; // }
      } else if (ecData.focus) {
        ecData.focus = null;
      }
    }
    var OTHER_STATES = ['emphasis', 'blur', 'select'];
    var defaultStyleGetterMap = {
      itemStyle: 'getItemStyle',
      lineStyle: 'getLineStyle',
      areaStyle: 'getAreaStyle'
    };
    /**
     * Set emphasis/blur/selected states of element.
     */

    function setStatesStylesFromModel(el, itemModel, styleType, // default itemStyle
    getter) {
      styleType = styleType || 'itemStyle';

      for (var i = 0; i < OTHER_STATES.length; i++) {
        var stateName = OTHER_STATES[i];
        var model = itemModel.getModel([stateName, styleType]);
        var state = el.ensureState(stateName); // Let it throw error if getterType is not found.

        state.style = getter ? getter(model) : model[defaultStyleGetterMap[styleType]]();
      }
    }
    /**
     *
     * Set element as highlight / downplay dispatcher.
     * It will be checked when element received mouseover event or from highlight action.
     * It's in change of all highlight/downplay behavior of it's children.
     *
     * @param el
     * @param el.highDownSilentOnTouch
     *        In touch device, mouseover event will be trigger on touchstart event
     *        (see module:zrender/dom/HandlerProxy). By this mechanism, we can
     *        conveniently use hoverStyle when tap on touch screen without additional
     *        code for compatibility.
     *        But if the chart/component has select feature, which usually also use
     *        hoverStyle, there might be conflict between 'select-highlight' and
     *        'hover-highlight' especially when roam is enabled (see geo for example).
     *        In this case, `highDownSilentOnTouch` should be used to disable
     *        hover-highlight on touch device.
     * @param asDispatcher If `false`, do not set as "highDownDispatcher".
     */

    function setAsHighDownDispatcher(el, asDispatcher) {
      var disable = asDispatcher === false;
      var extendedEl = el; // Make `highDownSilentOnTouch` and `onStateChange` only work after
      // `setAsHighDownDispatcher` called. Avoid it is modified by user unexpectedly.

      if (el.highDownSilentOnTouch) {
        extendedEl.__highDownSilentOnTouch = el.highDownSilentOnTouch;
      } // Simple optimize, since this method might be
      // called for each elements of a group in some cases.


      if (!disable || extendedEl.__highDownDispatcher) {
        // Emphasis, normal can be triggered manually by API or other components like hover link.
        // el[method]('emphasis', onElementEmphasisEvent)[method]('normal', onElementNormalEvent);
        // Also keep previous record.
        extendedEl.__highByOuter = extendedEl.__highByOuter || 0;
        extendedEl.__highDownDispatcher = !disable;
      }
    }
    function isHighDownDispatcher(el) {
      return !!(el && el.__highDownDispatcher);
    }
    /**
     * Support highlight/downplay record on each elements.
     * For the case: hover highlight/downplay (legend, visualMap, ...) and
     * user triggered highlight/downplay should not conflict.
     * Only all of the highlightDigit cleared, return to normal.
     * @param {string} highlightKey
     * @return {number} highlightDigit
     */

    function getHighlightDigit(highlightKey) {
      var highlightDigit = _highlightKeyMap[highlightKey];

      if (highlightDigit == null && _highlightNextDigit <= 32) {
        highlightDigit = _highlightKeyMap[highlightKey] = _highlightNextDigit++;
      }

      return highlightDigit;
    }
    function isSelectChangePayload(payload) {
      var payloadType = payload.type;
      return payloadType === SELECT_ACTION_TYPE || payloadType === UNSELECT_ACTION_TYPE || payloadType === TOGGLE_SELECT_ACTION_TYPE;
    }
    function isHighDownPayload(payload) {
      var payloadType = payload.type;
      return payloadType === HIGHLIGHT_ACTION_TYPE || payloadType === DOWNPLAY_ACTION_TYPE;
    }
    function savePathStates(el) {
      var store = getSavedStates(el);
      store.normalFill = el.style.fill;
      store.normalStroke = el.style.stroke;
      var selectState = el.states.select || {};
      store.selectFill = selectState.style && selectState.style.fill || null;
      store.selectStroke = selectState.style && selectState.style.stroke || null;
    }

    var CMD$2 = PathProxy.CMD;
    var points = [[], [], []];
    var mathSqrt$1 = Math.sqrt;
    var mathAtan2 = Math.atan2;
    function transformPath(path, m) {
        if (!m) {
            return;
        }
        var data = path.data;
        var len = path.len();
        var cmd;
        var nPoint;
        var i;
        var j;
        var k;
        var p;
        var M = CMD$2.M;
        var C = CMD$2.C;
        var L = CMD$2.L;
        var R = CMD$2.R;
        var A = CMD$2.A;
        var Q = CMD$2.Q;
        for (i = 0, j = 0; i < len;) {
            cmd = data[i++];
            j = i;
            nPoint = 0;
            switch (cmd) {
                case M:
                    nPoint = 1;
                    break;
                case L:
                    nPoint = 1;
                    break;
                case C:
                    nPoint = 3;
                    break;
                case Q:
                    nPoint = 2;
                    break;
                case A:
                    var x = m[4];
                    var y = m[5];
                    var sx = mathSqrt$1(m[0] * m[0] + m[1] * m[1]);
                    var sy = mathSqrt$1(m[2] * m[2] + m[3] * m[3]);
                    var angle = mathAtan2(-m[1] / sy, m[0] / sx);
                    data[i] *= sx;
                    data[i++] += x;
                    data[i] *= sy;
                    data[i++] += y;
                    data[i++] *= sx;
                    data[i++] *= sy;
                    data[i++] += angle;
                    data[i++] += angle;
                    i += 2;
                    j = i;
                    break;
                case R:
                    p[0] = data[i++];
                    p[1] = data[i++];
                    applyTransform(p, p, m);
                    data[j++] = p[0];
                    data[j++] = p[1];
                    p[0] += data[i++];
                    p[1] += data[i++];
                    applyTransform(p, p, m);
                    data[j++] = p[0];
                    data[j++] = p[1];
            }
            for (k = 0; k < nPoint; k++) {
                var p_1 = points[k];
                p_1[0] = data[i++];
                p_1[1] = data[i++];
                applyTransform(p_1, p_1, m);
                data[j++] = p_1[0];
                data[j++] = p_1[1];
            }
        }
        path.increaseVersion();
    }

    var mathSqrt$2 = Math.sqrt;
    var mathSin$2 = Math.sin;
    var mathCos$2 = Math.cos;
    var PI$1 = Math.PI;
    function vMag(v) {
        return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
    }
    function vRatio(u, v) {
        return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v));
    }
    function vAngle(u, v) {
        return (u[0] * v[1] < u[1] * v[0] ? -1 : 1)
            * Math.acos(vRatio(u, v));
    }
    function processArc(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg, cmd, path) {
        var psi = psiDeg * (PI$1 / 180.0);
        var xp = mathCos$2(psi) * (x1 - x2) / 2.0
            + mathSin$2(psi) * (y1 - y2) / 2.0;
        var yp = -1 * mathSin$2(psi) * (x1 - x2) / 2.0
            + mathCos$2(psi) * (y1 - y2) / 2.0;
        var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry);
        if (lambda > 1) {
            rx *= mathSqrt$2(lambda);
            ry *= mathSqrt$2(lambda);
        }
        var f = (fa === fs ? -1 : 1)
            * mathSqrt$2((((rx * rx) * (ry * ry))
                - ((rx * rx) * (yp * yp))
                - ((ry * ry) * (xp * xp))) / ((rx * rx) * (yp * yp)
                + (ry * ry) * (xp * xp))) || 0;
        var cxp = f * rx * yp / ry;
        var cyp = f * -ry * xp / rx;
        var cx = (x1 + x2) / 2.0
            + mathCos$2(psi) * cxp
            - mathSin$2(psi) * cyp;
        var cy = (y1 + y2) / 2.0
            + mathSin$2(psi) * cxp
            + mathCos$2(psi) * cyp;
        var theta = vAngle([1, 0], [(xp - cxp) / rx, (yp - cyp) / ry]);
        var u = [(xp - cxp) / rx, (yp - cyp) / ry];
        var v = [(-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry];
        var dTheta = vAngle(u, v);
        if (vRatio(u, v) <= -1) {
            dTheta = PI$1;
        }
        if (vRatio(u, v) >= 1) {
            dTheta = 0;
        }
        if (dTheta < 0) {
            var n = Math.round(dTheta / PI$1 * 1e6) / 1e6;
            dTheta = PI$1 * 2 + (n % 2) * PI$1;
        }
        path.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs);
    }
    var commandReg = /([mlvhzcqtsa])([^mlvhzcqtsa]*)/ig;
    var numberReg = /-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;
    function createPathProxyFromString(data) {
        var path = new PathProxy();
        if (!data) {
            return path;
        }
        var cpx = 0;
        var cpy = 0;
        var subpathX = cpx;
        var subpathY = cpy;
        var prevCmd;
        var CMD = PathProxy.CMD;
        var cmdList = data.match(commandReg);
        if (!cmdList) {
            return path;
        }
        for (var l = 0; l < cmdList.length; l++) {
            var cmdText = cmdList[l];
            var cmdStr = cmdText.charAt(0);
            var cmd = void 0;
            var p = cmdText.match(numberReg) || [];
            var pLen = p.length;
            for (var i = 0; i < pLen; i++) {
                p[i] = parseFloat(p[i]);
            }
            var off = 0;
            while (off < pLen) {
                var ctlPtx = void 0;
                var ctlPty = void 0;
                var rx = void 0;
                var ry = void 0;
                var psi = void 0;
                var fa = void 0;
                var fs = void 0;
                var x1 = cpx;
                var y1 = cpy;
                var len = void 0;
                var pathData = void 0;
                switch (cmdStr) {
                    case 'l':
                        cpx += p[off++];
                        cpy += p[off++];
                        cmd = CMD.L;
                        path.addData(cmd, cpx, cpy);
                        break;
                    case 'L':
                        cpx = p[off++];
                        cpy = p[off++];
                        cmd = CMD.L;
                        path.addData(cmd, cpx, cpy);
                        break;
                    case 'm':
                        cpx += p[off++];
                        cpy += p[off++];
                        cmd = CMD.M;
                        path.addData(cmd, cpx, cpy);
                        subpathX = cpx;
                        subpathY = cpy;
                        cmdStr = 'l';
                        break;
                    case 'M':
                        cpx = p[off++];
                        cpy = p[off++];
                        cmd = CMD.M;
                        path.addData(cmd, cpx, cpy);
                        subpathX = cpx;
                        subpathY = cpy;
                        cmdStr = 'L';
                        break;
                    case 'h':
                        cpx += p[off++];
                        cmd = CMD.L;
                        path.addData(cmd, cpx, cpy);
                        break;
                    case 'H':
                        cpx = p[off++];
                        cmd = CMD.L;
                        path.addData(cmd, cpx, cpy);
                        break;
                    case 'v':
                        cpy += p[off++];
                        cmd = CMD.L;
                        path.addData(cmd, cpx, cpy);
                        break;
                    case 'V':
                        cpy = p[off++];
                        cmd = CMD.L;
                        path.addData(cmd, cpx, cpy);
                        break;
                    case 'C':
                        cmd = CMD.C;
                        path.addData(cmd, p[off++], p[off++], p[off++], p[off++], p[off++], p[off++]);
                        cpx = p[off - 2];
                        cpy = p[off - 1];
                        break;
                    case 'c':
                        cmd = CMD.C;
                        path.addData(cmd, p[off++] + cpx, p[off++] + cpy, p[off++] + cpx, p[off++] + cpy, p[off++] + cpx, p[off++] + cpy);
                        cpx += p[off - 2];
                        cpy += p[off - 1];
                        break;
                    case 'S':
                        ctlPtx = cpx;
                        ctlPty = cpy;
                        len = path.len();
                        pathData = path.data;
                        if (prevCmd === CMD.C) {
                            ctlPtx += cpx - pathData[len - 4];
                            ctlPty += cpy - pathData[len - 3];
                        }
                        cmd = CMD.C;
                        x1 = p[off++];
                        y1 = p[off++];
                        cpx = p[off++];
                        cpy = p[off++];
                        path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy);
                        break;
                    case 's':
                        ctlPtx = cpx;
                        ctlPty = cpy;
                        len = path.len();
                        pathData = path.data;
                        if (prevCmd === CMD.C) {
                            ctlPtx += cpx - pathData[len - 4];
                            ctlPty += cpy - pathData[len - 3];
                        }
                        cmd = CMD.C;
                        x1 = cpx + p[off++];
                        y1 = cpy + p[off++];
                        cpx += p[off++];
                        cpy += p[off++];
                        path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy);
                        break;
                    case 'Q':
                        x1 = p[off++];
                        y1 = p[off++];
                        cpx = p[off++];
                        cpy = p[off++];
                        cmd = CMD.Q;
                        path.addData(cmd, x1, y1, cpx, cpy);
                        break;
                    case 'q':
                        x1 = p[off++] + cpx;
                        y1 = p[off++] + cpy;
                        cpx += p[off++];
                        cpy += p[off++];
                        cmd = CMD.Q;
                        path.addData(cmd, x1, y1, cpx, cpy);
                        break;
                    case 'T':
                        ctlPtx = cpx;
                        ctlPty = cpy;
                        len = path.len();
                        pathData = path.data;
                        if (prevCmd === CMD.Q) {
                            ctlPtx += cpx - pathData[len - 4];
                            ctlPty += cpy - pathData[len - 3];
                        }
                        cpx = p[off++];
                        cpy = p[off++];
                        cmd = CMD.Q;
                        path.addData(cmd, ctlPtx, ctlPty, cpx, cpy);
                        break;
                    case 't':
                        ctlPtx = cpx;
                        ctlPty = cpy;
                        len = path.len();
                        pathData = path.data;
                        if (prevCmd === CMD.Q) {
                            ctlPtx += cpx - pathData[len - 4];
                            ctlPty += cpy - pathData[len - 3];
                        }
                        cpx += p[off++];
                        cpy += p[off++];
                        cmd = CMD.Q;
                        path.addData(cmd, ctlPtx, ctlPty, cpx, cpy);
                        break;
                    case 'A':
                        rx = p[off++];
                        ry = p[off++];
                        psi = p[off++];
                        fa = p[off++];
                        fs = p[off++];
                        x1 = cpx, y1 = cpy;
                        cpx = p[off++];
                        cpy = p[off++];
                        cmd = CMD.A;
                        processArc(x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path);
                        break;
                    case 'a':
                        rx = p[off++];
                        ry = p[off++];
                        psi = p[off++];
                        fa = p[off++];
                        fs = p[off++];
                        x1 = cpx, y1 = cpy;
                        cpx += p[off++];
                        cpy += p[off++];
                        cmd = CMD.A;
                        processArc(x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path);
                        break;
                }
            }
            if (cmdStr === 'z' || cmdStr === 'Z') {
                cmd = CMD.Z;
                path.addData(cmd);
                cpx = subpathX;
                cpy = subpathY;
            }
            prevCmd = cmd;
        }
        path.toStatic();
        return path;
    }
    var SVGPath = (function (_super) {
        __extends(SVGPath, _super);
        function SVGPath() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        SVGPath.prototype.applyTransform = function (m) { };
        return SVGPath;
    }(Path));
    function isPathProxy(path) {
        return path.setData != null;
    }
    function createPathOptions(str, opts) {
        var pathProxy = createPathProxyFromString(str);
        var innerOpts = extend({}, opts);
        innerOpts.buildPath = function (path) {
            if (isPathProxy(path)) {
                path.setData(pathProxy.data);
                var ctx = path.getContext();
                if (ctx) {
                    path.rebuildPath(ctx, 1);
                }
            }
            else {
                var ctx = path;
                pathProxy.rebuildPath(ctx, 1);
            }
        };
        innerOpts.applyTransform = function (m) {
            transformPath(pathProxy, m);
            this.dirtyShape();
        };
        return innerOpts;
    }
    function createFromString(str, opts) {
        return new SVGPath(createPathOptions(str, opts));
    }
    function extendFromString(str, defaultOpts) {
        var innerOpts = createPathOptions(str, defaultOpts);
        var Sub = (function (_super) {
            __extends(Sub, _super);
            function Sub(opts) {
                var _this = _super.call(this, opts) || this;
                _this.applyTransform = innerOpts.applyTransform;
                _this.buildPath = innerOpts.buildPath;
                return _this;
            }
            return Sub;
        }(SVGPath));
        return Sub;
    }
    function mergePath(pathEls, opts) {
        var pathList = [];
        var len = pathEls.length;
        for (var i = 0; i < len; i++) {
            var pathEl = pathEls[i];
            pathList.push(pathEl.getUpdatedPathProxy(true));
        }
        var pathBundle = new Path(opts);
        pathBundle.createPathProxy();
        pathBundle.buildPath = function (path) {
            if (isPathProxy(path)) {
                path.appendPath(pathList);
                var ctx = path.getContext();
                if (ctx) {
                    path.rebuildPath(ctx, 1);
                }
            }
        };
        return pathBundle;
    }

    var CircleShape = (function () {
        function CircleShape() {
            this.cx = 0;
            this.cy = 0;
            this.r = 0;
        }
        return CircleShape;
    }());
    var Circle = (function (_super) {
        __extends(Circle, _super);
        function Circle(opts) {
            return _super.call(this, opts) || this;
        }
        Circle.prototype.getDefaultShape = function () {
            return new CircleShape();
        };
        Circle.prototype.buildPath = function (ctx, shape) {
            ctx.moveTo(shape.cx + shape.r, shape.cy);
            ctx.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2);
        };
        return Circle;
    }(Path));
    Circle.prototype.type = 'circle';

    var EllipseShape = (function () {
        function EllipseShape() {
            this.cx = 0;
            this.cy = 0;
            this.rx = 0;
            this.ry = 0;
        }
        return EllipseShape;
    }());
    var Ellipse = (function (_super) {
        __extends(Ellipse, _super);
        function Ellipse(opts) {
            return _super.call(this, opts) || this;
        }
        Ellipse.prototype.getDefaultShape = function () {
            return new EllipseShape();
        };
        Ellipse.prototype.buildPath = function (ctx, shape) {
            var k = 0.5522848;
            var x = shape.cx;
            var y = shape.cy;
            var a = shape.rx;
            var b = shape.ry;
            var ox = a * k;
            var oy = b * k;
            ctx.moveTo(x - a, y);
            ctx.bezierCurveTo(x - a, y - oy, x - ox, y - b, x, y - b);
            ctx.bezierCurveTo(x + ox, y - b, x + a, y - oy, x + a, y);
            ctx.bezierCurveTo(x + a, y + oy, x + ox, y + b, x, y + b);
            ctx.bezierCurveTo(x - ox, y + b, x - a, y + oy, x - a, y);
            ctx.closePath();
        };
        return Ellipse;
    }(Path));
    Ellipse.prototype.type = 'ellipse';

    var PI$2 = Math.PI;
    var PI2$5 = PI$2 * 2;
    var mathSin$3 = Math.sin;
    var mathCos$3 = Math.cos;
    var mathACos = Math.acos;
    var mathATan2 = Math.atan2;
    var mathAbs$1 = Math.abs;
    var mathSqrt$3 = Math.sqrt;
    var mathMax$3 = Math.max;
    var mathMin$3 = Math.min;
    var e = 1e-4;
    function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
        var dx10 = x1 - x0;
        var dy10 = y1 - y0;
        var dx32 = x3 - x2;
        var dy32 = y3 - y2;
        var t = dy32 * dx10 - dx32 * dy10;
        if (t * t < e) {
            return;
        }
        t = (dx32 * (y0 - y2) - dy32 * (x0 - x2)) / t;
        return [x0 + t * dx10, y0 + t * dy10];
    }
    function computeCornerTangents(x0, y0, x1, y1, radius, cr, clockwise) {
        var x01 = x0 - x1;
        var y01 = y0 - y1;
        var lo = (clockwise ? cr : -cr) / mathSqrt$3(x01 * x01 + y01 * y01);
        var ox = lo * y01;
        var oy = -lo * x01;
        var x11 = x0 + ox;
        var y11 = y0 + oy;
        var x10 = x1 + ox;
        var y10 = y1 + oy;
        var x00 = (x11 + x10) / 2;
        var y00 = (y11 + y10) / 2;
        var dx = x10 - x11;
        var dy = y10 - y11;
        var d2 = dx * dx + dy * dy;
        var r = radius - cr;
        var s = x11 * y10 - x10 * y11;
        var d = (dy < 0 ? -1 : 1) * mathSqrt$3(mathMax$3(0, r * r * d2 - s * s));
        var cx0 = (s * dy - dx * d) / d2;
        var cy0 = (-s * dx - dy * d) / d2;
        var cx1 = (s * dy + dx * d) / d2;
        var cy1 = (-s * dx + dy * d) / d2;
        var dx0 = cx0 - x00;
        var dy0 = cy0 - y00;
        var dx1 = cx1 - x00;
        var dy1 = cy1 - y00;
        if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) {
            cx0 = cx1;
            cy0 = cy1;
        }
        return {
            cx: cx0,
            cy: cy0,
            x0: -ox,
            y0: -oy,
            x1: cx0 * (radius / r - 1),
            y1: cy0 * (radius / r - 1)
        };
    }
    function normalizeCornerRadius(cr) {
        var arr;
        if (isArray(cr)) {
            var len = cr.length;
            if (!len) {
                return cr;
            }
            if (len === 1) {
                arr = [cr[0], cr[0], 0, 0];
            }
            else if (len === 2) {
                arr = [cr[0], cr[0], cr[1], cr[1]];
            }
            else if (len === 3) {
                arr = cr.concat(cr[2]);
            }
            else {
                arr = cr;
            }
        }
        else {
            arr = [cr, cr, cr, cr];
        }
        return arr;
    }
    function buildPath$1(ctx, shape) {
        var _a;
        var radius = mathMax$3(shape.r, 0);
        var innerRadius = mathMax$3(shape.r0 || 0, 0);
        var hasRadius = radius > 0;
        var hasInnerRadius = innerRadius > 0;
        if (!hasRadius && !hasInnerRadius) {
            return;
        }
        if (!hasRadius) {
            radius = innerRadius;
            innerRadius = 0;
        }
        if (innerRadius > radius) {
            var tmp = radius;
            radius = innerRadius;
            innerRadius = tmp;
        }
        var startAngle = shape.startAngle, endAngle = shape.endAngle;
        if (isNaN(startAngle) || isNaN(endAngle)) {
            return;
        }
        var cx = shape.cx, cy = shape.cy;
        var clockwise = !!shape.clockwise;
        var arc = mathAbs$1(endAngle - startAngle);
        var mod = arc > PI2$5 && arc % PI2$5;
        mod > e && (arc = mod);
        if (!(radius > e)) {
            ctx.moveTo(cx, cy);
        }
        else if (arc > PI2$5 - e) {
            ctx.moveTo(cx + radius * mathCos$3(startAngle), cy + radius * mathSin$3(startAngle));
            ctx.arc(cx, cy, radius, startAngle, endAngle, !clockwise);
            if (innerRadius > e) {
                ctx.moveTo(cx + innerRadius * mathCos$3(endAngle), cy + innerRadius * mathSin$3(endAngle));
                ctx.arc(cx, cy, innerRadius, endAngle, startAngle, clockwise);
            }
        }
        else {
            var icrStart = void 0;
            var icrEnd = void 0;
            var ocrStart = void 0;
            var ocrEnd = void 0;
            var ocrs = void 0;
            var ocre = void 0;
            var icrs = void 0;
            var icre = void 0;
            var ocrMax = void 0;
            var icrMax = void 0;
            var limitedOcrMax = void 0;
            var limitedIcrMax = void 0;
            var xre = void 0;
            var yre = void 0;
            var xirs = void 0;
            var yirs = void 0;
            var xrs = radius * mathCos$3(startAngle);
            var yrs = radius * mathSin$3(startAngle);
            var xire = innerRadius * mathCos$3(endAngle);
            var yire = innerRadius * mathSin$3(endAngle);
            var hasArc = arc > e;
            if (hasArc) {
                var cornerRadius = shape.cornerRadius;
                if (cornerRadius) {
                    _a = normalizeCornerRadius(cornerRadius), icrStart = _a[0], icrEnd = _a[1], ocrStart = _a[2], ocrEnd = _a[3];
                }
                var halfRd = mathAbs$1(radius - innerRadius) / 2;
                ocrs = mathMin$3(halfRd, ocrStart);
                ocre = mathMin$3(halfRd, ocrEnd);
                icrs = mathMin$3(halfRd, icrStart);
                icre = mathMin$3(halfRd, icrEnd);
                limitedOcrMax = ocrMax = mathMax$3(ocrs, ocre);
                limitedIcrMax = icrMax = mathMax$3(icrs, icre);
                if (ocrMax > e || icrMax > e) {
                    xre = radius * mathCos$3(endAngle);
                    yre = radius * mathSin$3(endAngle);
                    xirs = innerRadius * mathCos$3(startAngle);
                    yirs = innerRadius * mathSin$3(startAngle);
                    if (arc < PI$2) {
                        var it_1 = intersect(xrs, yrs, xirs, yirs, xre, yre, xire, yire);
                        if (it_1) {
                            var x0 = xrs - it_1[0];
                            var y0 = yrs - it_1[1];
                            var x1 = xre - it_1[0];
                            var y1 = yre - it_1[1];
                            var a = 1 / mathSin$3(mathACos((x0 * x1 + y0 * y1) / (mathSqrt$3(x0 * x0 + y0 * y0) * mathSqrt$3(x1 * x1 + y1 * y1))) / 2);
                            var b = mathSqrt$3(it_1[0] * it_1[0] + it_1[1] * it_1[1]);
                            limitedOcrMax = mathMin$3(ocrMax, (radius - b) / (a + 1));
                            limitedIcrMax = mathMin$3(icrMax, (innerRadius - b) / (a - 1));
                        }
                    }
                }
            }
            if (!hasArc) {
                ctx.moveTo(cx + xrs, cy + yrs);
            }
            else if (limitedOcrMax > e) {
                var crStart = mathMin$3(ocrStart, limitedOcrMax);
                var crEnd = mathMin$3(ocrEnd, limitedOcrMax);
                var ct0 = computeCornerTangents(xirs, yirs, xrs, yrs, radius, crStart, clockwise);
                var ct1 = computeCornerTangents(xre, yre, xire, yire, radius, crEnd, clockwise);
                ctx.moveTo(cx + ct0.cx + ct0.x0, cy + ct0.cy + ct0.y0);
                if (limitedOcrMax < ocrMax && crStart === crEnd) {
                    ctx.arc(cx + ct0.cx, cy + ct0.cy, limitedOcrMax, mathATan2(ct0.y0, ct0.x0), mathATan2(ct1.y0, ct1.x0), !clockwise);
                }
                else {
                    crStart > 0 && ctx.arc(cx + ct0.cx, cy + ct0.cy, crStart, mathATan2(ct0.y0, ct0.x0), mathATan2(ct0.y1, ct0.x1), !clockwise);
                    ctx.arc(cx, cy, radius, mathATan2(ct0.cy + ct0.y1, ct0.cx + ct0.x1), mathATan2(ct1.cy + ct1.y1, ct1.cx + ct1.x1), !clockwise);
                    crEnd > 0 && ctx.arc(cx + ct1.cx, cy + ct1.cy, crEnd, mathATan2(ct1.y1, ct1.x1), mathATan2(ct1.y0, ct1.x0), !clockwise);
                }
            }
            else {
                ctx.moveTo(cx + xrs, cy + yrs);
                ctx.arc(cx, cy, radius, startAngle, endAngle, !clockwise);
            }
            if (!(innerRadius > e) || !hasArc) {
                ctx.lineTo(cx + xire, cy + yire);
            }
            else if (limitedIcrMax > e) {
                var crStart = mathMin$3(icrStart, limitedIcrMax);
                var crEnd = mathMin$3(icrEnd, limitedIcrMax);
                var ct0 = computeCornerTangents(xire, yire, xre, yre, innerRadius, -crEnd, clockwise);
                var ct1 = computeCornerTangents(xrs, yrs, xirs, yirs, innerRadius, -crStart, clockwise);
                ctx.lineTo(cx + ct0.cx + ct0.x0, cy + ct0.cy + ct0.y0);
                if (limitedIcrMax < icrMax && crStart === crEnd) {
                    ctx.arc(cx + ct0.cx, cy + ct0.cy, limitedIcrMax, mathATan2(ct0.y0, ct0.x0), mathATan2(ct1.y0, ct1.x0), !clockwise);
                }
                else {
                    crEnd > 0 && ctx.arc(cx + ct0.cx, cy + ct0.cy, crEnd, mathATan2(ct0.y0, ct0.x0), mathATan2(ct0.y1, ct0.x1), !clockwise);
                    ctx.arc(cx, cy, innerRadius, mathATan2(ct0.cy + ct0.y1, ct0.cx + ct0.x1), mathATan2(ct1.cy + ct1.y1, ct1.cx + ct1.x1), clockwise);
                    crStart > 0 && ctx.arc(cx + ct1.cx, cy + ct1.cy, crStart, mathATan2(ct1.y1, ct1.x1), mathATan2(ct1.y0, ct1.x0), !clockwise);
                }
            }
            else {
                ctx.lineTo(cx + xire, cy + yire);
                ctx.arc(cx, cy, innerRadius, endAngle, startAngle, clockwise);
            }
        }
        ctx.closePath();
    }

    var SectorShape = (function () {
        function SectorShape() {
            this.cx = 0;
            this.cy = 0;
            this.r0 = 0;
            this.r = 0;
            this.startAngle = 0;
            this.endAngle = Math.PI * 2;
            this.clockwise = true;
            this.cornerRadius = 0;
        }
        return SectorShape;
    }());
    var Sector = (function (_super) {
        __extends(Sector, _super);
        function Sector(opts) {
            return _super.call(this, opts) || this;
        }
        Sector.prototype.getDefaultShape = function () {
            return new SectorShape();
        };
        Sector.prototype.buildPath = function (ctx, shape) {
            buildPath$1(ctx, shape);
        };
        Sector.prototype.isZeroArea = function () {
            return this.shape.startAngle === this.shape.endAngle
                || this.shape.r === this.shape.r0;
        };
        return Sector;
    }(Path));
    Sector.prototype.type = 'sector';

    var RingShape = (function () {
        function RingShape() {
            this.cx = 0;
            this.cy = 0;
            this.r = 0;
            this.r0 = 0;
        }
        return RingShape;
    }());
    var Ring = (function (_super) {
        __extends(Ring, _super);
        function Ring(opts) {
            return _super.call(this, opts) || this;
        }
        Ring.prototype.getDefaultShape = function () {
            return new RingShape();
        };
        Ring.prototype.buildPath = function (ctx, shape) {
            var x = shape.cx;
            var y = shape.cy;
            var PI2 = Math.PI * 2;
            ctx.moveTo(x + shape.r, y);
            ctx.arc(x, y, shape.r, 0, PI2, false);
            ctx.moveTo(x + shape.r0, y);
            ctx.arc(x, y, shape.r0, 0, PI2, true);
        };
        return Ring;
    }(Path));
    Ring.prototype.type = 'ring';

    function smoothBezier(points, smooth, isLoop, constraint) {
        var cps = [];
        var v = [];
        var v1 = [];
        var v2 = [];
        var prevPoint;
        var nextPoint;
        var min$1;
        var max$1;
        if (constraint) {
            min$1 = [Infinity, Infinity];
            max$1 = [-Infinity, -Infinity];
            for (var i = 0, len = points.length; i < len; i++) {
                min(min$1, min$1, points[i]);
                max(max$1, max$1, points[i]);
            }
            min(min$1, min$1, constraint[0]);
            max(max$1, max$1, constraint[1]);
        }
        for (var i = 0, len = points.length; i < len; i++) {
            var point = points[i];
            if (isLoop) {
                prevPoint = points[i ? i - 1 : len - 1];
                nextPoint = points[(i + 1) % len];
            }
            else {
                if (i === 0 || i === len - 1) {
                    cps.push(clone$1(points[i]));
                    continue;
                }
                else {
                    prevPoint = points[i - 1];
                    nextPoint = points[i + 1];
                }
            }
            sub(v, nextPoint, prevPoint);
            scale(v, v, smooth);
            var d0 = distance(point, prevPoint);
            var d1 = distance(point, nextPoint);
            var sum = d0 + d1;
            if (sum !== 0) {
                d0 /= sum;
                d1 /= sum;
            }
            scale(v1, v, -d0);
            scale(v2, v, d1);
            var cp0 = add([], point, v1);
            var cp1 = add([], point, v2);
            if (constraint) {
                max(cp0, cp0, min$1);
                min(cp0, cp0, max$1);
                max(cp1, cp1, min$1);
                min(cp1, cp1, max$1);
            }
            cps.push(cp0);
            cps.push(cp1);
        }
        if (isLoop) {
            cps.push(cps.shift());
        }
        return cps;
    }

    function buildPath$2(ctx, shape, closePath) {
        var smooth = shape.smooth;
        var points = shape.points;
        if (points && points.length >= 2) {
            if (smooth) {
                var controlPoints = smoothBezier(points, smooth, closePath, shape.smoothConstraint);
                ctx.moveTo(points[0][0], points[0][1]);
                var len = points.length;
                for (var i = 0; i < (closePath ? len : len - 1); i++) {
                    var cp1 = controlPoints[i * 2];
                    var cp2 = controlPoints[i * 2 + 1];
                    var p = points[(i + 1) % len];
                    ctx.bezierCurveTo(cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]);
                }
            }
            else {
                ctx.moveTo(points[0][0], points[0][1]);
                for (var i = 1, l = points.length; i < l; i++) {
                    ctx.lineTo(points[i][0], points[i][1]);
                }
            }
            closePath && ctx.closePath();
        }
    }

    var PolygonShape = (function () {
        function PolygonShape() {
            this.points = null;
            this.smooth = 0;
            this.smoothConstraint = null;
        }
        return PolygonShape;
    }());
    var Polygon = (function (_super) {
        __extends(Polygon, _super);
        function Polygon(opts) {
            return _super.call(this, opts) || this;
        }
        Polygon.prototype.getDefaultShape = function () {
            return new PolygonShape();
        };
        Polygon.prototype.buildPath = function (ctx, shape) {
            buildPath$2(ctx, shape, true);
        };
        return Polygon;
    }(Path));
    Polygon.prototype.type = 'polygon';

    var PolylineShape = (function () {
        function PolylineShape() {
            this.points = null;
            this.percent = 1;
            this.smooth = 0;
            this.smoothConstraint = null;
        }
        return PolylineShape;
    }());
    var Polyline = (function (_super) {
        __extends(Polyline, _super);
        function Polyline(opts) {
            return _super.call(this, opts) || this;
        }
        Polyline.prototype.getDefaultStyle = function () {
            return {
                stroke: '#000',
                fill: null
            };
        };
        Polyline.prototype.getDefaultShape = function () {
            return new PolylineShape();
        };
        Polyline.prototype.buildPath = function (ctx, shape) {
            buildPath$2(ctx, shape, false);
        };
        return Polyline;
    }(Path));
    Polyline.prototype.type = 'polyline';

    var subPixelOptimizeOutputShape$1 = {};
    var LineShape = (function () {
        function LineShape() {
            this.x1 = 0;
            this.y1 = 0;
            this.x2 = 0;
            this.y2 = 0;
            this.percent = 1;
        }
        return LineShape;
    }());
    var Line = (function (_super) {
        __extends(Line, _super);
        function Line(opts) {
            return _super.call(this, opts) || this;
        }
        Line.prototype.getDefaultStyle = function () {
            return {
                stroke: '#000',
                fill: null
            };
        };
        Line.prototype.getDefaultShape = function () {
            return new LineShape();
        };
        Line.prototype.buildPath = function (ctx, shape) {
            var x1;
            var y1;
            var x2;
            var y2;
            if (this.subPixelOptimize) {
                var optimizedShape = subPixelOptimizeLine(subPixelOptimizeOutputShape$1, shape, this.style);
                x1 = optimizedShape.x1;
                y1 = optimizedShape.y1;
                x2 = optimizedShape.x2;
                y2 = optimizedShape.y2;
            }
            else {
                x1 = shape.x1;
                y1 = shape.y1;
                x2 = shape.x2;
                y2 = shape.y2;
            }
            var percent = shape.percent;
            if (percent === 0) {
                return;
            }
            ctx.moveTo(x1, y1);
            if (percent < 1) {
                x2 = x1 * (1 - percent) + x2 * percent;
                y2 = y1 * (1 - percent) + y2 * percent;
            }
            ctx.lineTo(x2, y2);
        };
        Line.prototype.pointAt = function (p) {
            var shape = this.shape;
            return [
                shape.x1 * (1 - p) + shape.x2 * p,
                shape.y1 * (1 - p) + shape.y2 * p
            ];
        };
        return Line;
    }(Path));
    Line.prototype.type = 'line';

    var out = [];
    var BezierCurveShape = (function () {
        function BezierCurveShape() {
            this.x1 = 0;
            this.y1 = 0;
            this.x2 = 0;
            this.y2 = 0;
            this.cpx1 = 0;
            this.cpy1 = 0;
            this.percent = 1;
        }
        return BezierCurveShape;
    }());
    function someVectorAt(shape, t, isTangent) {
        var cpx2 = shape.cpx2;
        var cpy2 = shape.cpy2;
        if (cpx2 != null || cpy2 != null) {
            return [
                (isTangent ? cubicDerivativeAt : cubicAt)(shape.x1, shape.cpx1, shape.cpx2, shape.x2, t),
                (isTangent ? cubicDerivativeAt : cubicAt)(shape.y1, shape.cpy1, shape.cpy2, shape.y2, t)
            ];
        }
        else {
            return [
                (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.x1, shape.cpx1, shape.x2, t),
                (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.y1, shape.cpy1, shape.y2, t)
            ];
        }
    }
    var BezierCurve = (function (_super) {
        __extends(BezierCurve, _super);
        function BezierCurve(opts) {
            return _super.call(this, opts) || this;
        }
        BezierCurve.prototype.getDefaultStyle = function () {
            return {
                stroke: '#000',
                fill: null
            };
        };
        BezierCurve.prototype.getDefaultShape = function () {
            return new BezierCurveShape();
        };
        BezierCurve.prototype.buildPath = function (ctx, shape) {
            var x1 = shape.x1;
            var y1 = shape.y1;
            var x2 = shape.x2;
            var y2 = shape.y2;
            var cpx1 = shape.cpx1;
            var cpy1 = shape.cpy1;
            var cpx2 = shape.cpx2;
            var cpy2 = shape.cpy2;
            var percent = shape.percent;
            if (percent === 0) {
                return;
            }
            ctx.moveTo(x1, y1);
            if (cpx2 == null || cpy2 == null) {
                if (percent < 1) {
                    quadraticSubdivide(x1, cpx1, x2, percent, out);
                    cpx1 = out[1];
                    x2 = out[2];
                    quadraticSubdivide(y1, cpy1, y2, percent, out);
                    cpy1 = out[1];
                    y2 = out[2];
                }
                ctx.quadraticCurveTo(cpx1, cpy1, x2, y2);
            }
            else {
                if (percent < 1) {
                    cubicSubdivide(x1, cpx1, cpx2, x2, percent, out);
                    cpx1 = out[1];
                    cpx2 = out[2];
                    x2 = out[3];
                    cubicSubdivide(y1, cpy1, cpy2, y2, percent, out);
                    cpy1 = out[1];
                    cpy2 = out[2];
                    y2 = out[3];
                }
                ctx.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x2, y2);
            }
        };
        BezierCurve.prototype.pointAt = function (t) {
            return someVectorAt(this.shape, t, false);
        };
        BezierCurve.prototype.tangentAt = function (t) {
            var p = someVectorAt(this.shape, t, true);
            return normalize(p, p);
        };
        return BezierCurve;
    }(Path));
    BezierCurve.prototype.type = 'bezier-curve';

    var ArcShape = (function () {
        function ArcShape() {
            this.cx = 0;
            this.cy = 0;
            this.r = 0;
            this.startAngle = 0;
            this.endAngle = Math.PI * 2;
            this.clockwise = true;
        }
        return ArcShape;
    }());
    var Arc = (function (_super) {
        __extends(Arc, _super);
        function Arc(opts) {
            return _super.call(this, opts) || this;
        }
        Arc.prototype.getDefaultStyle = function () {
            return {
                stroke: '#000',
                fill: null
            };
        };
        Arc.prototype.getDefaultShape = function () {
            return new ArcShape();
        };
        Arc.prototype.buildPath = function (ctx, shape) {
            var x = shape.cx;
            var y = shape.cy;
            var r = Math.max(shape.r, 0);
            var startAngle = shape.startAngle;
            var endAngle = shape.endAngle;
            var clockwise = shape.clockwise;
            var unitX = Math.cos(startAngle);
            var unitY = Math.sin(startAngle);
            ctx.moveTo(unitX * r + x, unitY * r + y);
            ctx.arc(x, y, r, startAngle, endAngle, !clockwise);
        };
        return Arc;
    }(Path));
    Arc.prototype.type = 'arc';

    var CompoundPath = (function (_super) {
        __extends(CompoundPath, _super);
        function CompoundPath() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.type = 'compound';
            return _this;
        }
        CompoundPath.prototype._updatePathDirty = function () {
            var paths = this.shape.paths;
            var dirtyPath = this.shapeChanged();
            for (var i = 0; i < paths.length; i++) {
                dirtyPath = dirtyPath || paths[i].shapeChanged();
            }
            if (dirtyPath) {
                this.dirtyShape();
            }
        };
        CompoundPath.prototype.beforeBrush = function () {
            this._updatePathDirty();
            var paths = this.shape.paths || [];
            var scale = this.getGlobalScale();
            for (var i = 0; i < paths.length; i++) {
                if (!paths[i].path) {
                    paths[i].createPathProxy();
                }
                paths[i].path.setScale(scale[0], scale[1], paths[i].segmentIgnoreThreshold);
            }
        };
        CompoundPath.prototype.buildPath = function (ctx, shape) {
            var paths = shape.paths || [];
            for (var i = 0; i < paths.length; i++) {
                paths[i].buildPath(ctx, paths[i].shape, true);
            }
        };
        CompoundPath.prototype.afterBrush = function () {
            var paths = this.shape.paths || [];
            for (var i = 0; i < paths.length; i++) {
                paths[i].pathUpdated();
            }
        };
        CompoundPath.prototype.getBoundingRect = function () {
            this._updatePathDirty.call(this);
            return Path.prototype.getBoundingRect.call(this);
        };
        return CompoundPath;
    }(Path));

    var Gradient = (function () {
        function Gradient(colorStops) {
            this.colorStops = colorStops || [];
        }
        Gradient.prototype.addColorStop = function (offset, color) {
            this.colorStops.push({
                offset: offset,
                color: color
            });
        };
        return Gradient;
    }());

    var LinearGradient = (function (_super) {
        __extends(LinearGradient, _super);
        function LinearGradient(x, y, x2, y2, colorStops, globalCoord) {
            var _this = _super.call(this, colorStops) || this;
            _this.x = x == null ? 0 : x;
            _this.y = y == null ? 0 : y;
            _this.x2 = x2 == null ? 1 : x2;
            _this.y2 = y2 == null ? 0 : y2;
            _this.type = 'linear';
            _this.global = globalCoord || false;
            return _this;
        }
        return LinearGradient;
    }(Gradient));

    var RadialGradient = (function (_super) {
        __extends(RadialGradient, _super);
        function RadialGradient(x, y, r, colorStops, globalCoord) {
            var _this = _super.call(this, colorStops) || this;
            _this.x = x == null ? 0.5 : x;
            _this.y = y == null ? 0.5 : y;
            _this.r = r == null ? 0.5 : r;
            _this.type = 'radial';
            _this.global = globalCoord || false;
            return _this;
        }
        return RadialGradient;
    }(Gradient));

    var extent = [0, 0];
    var extent2 = [0, 0];
    var minTv$1 = new Point();
    var maxTv$1 = new Point();
    var OrientedBoundingRect = (function () {
        function OrientedBoundingRect(rect, transform) {
            this._corners = [];
            this._axes = [];
            this._origin = [0, 0];
            for (var i = 0; i < 4; i++) {
                this._corners[i] = new Point();
            }
            for (var i = 0; i < 2; i++) {
                this._axes[i] = new Point();
            }
            if (rect) {
                this.fromBoundingRect(rect, transform);
            }
        }
        OrientedBoundingRect.prototype.fromBoundingRect = function (rect, transform) {
            var corners = this._corners;
            var axes = this._axes;
            var x = rect.x;
            var y = rect.y;
            var x2 = x + rect.width;
            var y2 = y + rect.height;
            corners[0].set(x, y);
            corners[1].set(x2, y);
            corners[2].set(x2, y2);
            corners[3].set(x, y2);
            if (transform) {
                for (var i = 0; i < 4; i++) {
                    corners[i].transform(transform);
                }
            }
            Point.sub(axes[0], corners[1], corners[0]);
            Point.sub(axes[1], corners[3], corners[0]);
            axes[0].normalize();
            axes[1].normalize();
            for (var i = 0; i < 2; i++) {
                this._origin[i] = axes[i].dot(corners[0]);
            }
        };
        OrientedBoundingRect.prototype.intersect = function (other, mtv) {
            var overlapped = true;
            var noMtv = !mtv;
            minTv$1.set(Infinity, Infinity);
            maxTv$1.set(0, 0);
            if (!this._intersectCheckOneSide(this, other, minTv$1, maxTv$1, noMtv, 1)) {
                overlapped = false;
                if (noMtv) {
                    return overlapped;
                }
            }
            if (!this._intersectCheckOneSide(other, this, minTv$1, maxTv$1, noMtv, -1)) {
                overlapped = false;
                if (noMtv) {
                    return overlapped;
                }
            }
            if (!noMtv) {
                Point.copy(mtv, overlapped ? minTv$1 : maxTv$1);
            }
            return overlapped;
        };
        OrientedBoundingRect.prototype._intersectCheckOneSide = function (self, other, minTv, maxTv, noMtv, inverse) {
            var overlapped = true;
            for (var i = 0; i < 2; i++) {
                var axis = this._axes[i];
                this._getProjMinMaxOnAxis(i, self._corners, extent);
                this._getProjMinMaxOnAxis(i, other._corners, extent2);
                if (extent[1] < extent2[0] || extent[0] > extent2[1]) {
                    overlapped = false;
                    if (noMtv) {
                        return overlapped;
                    }
                    var dist0 = Math.abs(extent2[0] - extent[1]);
                    var dist1 = Math.abs(extent[0] - extent2[1]);
                    if (Math.min(dist0, dist1) > maxTv.len()) {
                        if (dist0 < dist1) {
                            Point.scale(maxTv, axis, -dist0 * inverse);
                        }
                        else {
                            Point.scale(maxTv, axis, dist1 * inverse);
                        }
                    }
                }
                else if (minTv) {
                    var dist0 = Math.abs(extent2[0] - extent[1]);
                    var dist1 = Math.abs(extent[0] - extent2[1]);
                    if (Math.min(dist0, dist1) < minTv.len()) {
                        if (dist0 < dist1) {
                            Point.scale(minTv, axis, dist0 * inverse);
                        }
                        else {
                            Point.scale(minTv, axis, -dist1 * inverse);
                        }
                    }
                }
            }
            return overlapped;
        };
        OrientedBoundingRect.prototype._getProjMinMaxOnAxis = function (dim, corners, out) {
            var axis = this._axes[dim];
            var origin = this._origin;
            var proj = corners[0].dot(axis) + origin[dim];
            var min = proj;
            var max = proj;
            for (var i = 1; i < corners.length; i++) {
                var proj_1 = corners[i].dot(axis) + origin[dim];
                min = Math.min(proj_1, min);
                max = Math.max(proj_1, max);
            }
            out[0] = min;
            out[1] = max;
        };
        return OrientedBoundingRect;
    }());

    var m = [];
    var IncrementalDisplayable = (function (_super) {
        __extends(IncrementalDisplayable, _super);
        function IncrementalDisplayable() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.notClear = true;
            _this.incremental = true;
            _this._displayables = [];
            _this._temporaryDisplayables = [];
            _this._cursor = 0;
            return _this;
        }
        IncrementalDisplayable.prototype.traverse = function (cb, context) {
            cb.call(context, this);
        };
        IncrementalDisplayable.prototype.useStyle = function () {
            this.style = {};
        };
        IncrementalDisplayable.prototype.getCursor = function () {
            return this._cursor;
        };
        IncrementalDisplayable.prototype.innerAfterBrush = function () {
            this._cursor = this._displayables.length;
        };
        IncrementalDisplayable.prototype.clearDisplaybles = function () {
            this._displayables = [];
            this._temporaryDisplayables = [];
            this._cursor = 0;
            this.markRedraw();
            this.notClear = false;
        };
        IncrementalDisplayable.prototype.clearTemporalDisplayables = function () {
            this._temporaryDisplayables = [];
        };
        IncrementalDisplayable.prototype.addDisplayable = function (displayable, notPersistent) {
            if (notPersistent) {
                this._temporaryDisplayables.push(displayable);
            }
            else {
                this._displayables.push(displayable);
            }
            this.markRedraw();
        };
        IncrementalDisplayable.prototype.addDisplayables = function (displayables, notPersistent) {
            notPersistent = notPersistent || false;
            for (var i = 0; i < displayables.length; i++) {
                this.addDisplayable(displayables[i], notPersistent);
            }
        };
        IncrementalDisplayable.prototype.getDisplayables = function () {
            return this._displayables;
        };
        IncrementalDisplayable.prototype.getTemporalDisplayables = function () {
            return this._temporaryDisplayables;
        };
        IncrementalDisplayable.prototype.eachPendingDisplayable = function (cb) {
            for (var i = this._cursor; i < this._displayables.length; i++) {
                cb && cb(this._displayables[i]);
            }
            for (var i = 0; i < this._temporaryDisplayables.length; i++) {
                cb && cb(this._temporaryDisplayables[i]);
            }
        };
        IncrementalDisplayable.prototype.update = function () {
            this.updateTransform();
            for (var i = this._cursor; i < this._displayables.length; i++) {
                var displayable = this._displayables[i];
                displayable.parent = this;
                displayable.update();
                displayable.parent = null;
            }
            for (var i = 0; i < this._temporaryDisplayables.length; i++) {
                var displayable = this._temporaryDisplayables[i];
                displayable.parent = this;
                displayable.update();
                displayable.parent = null;
            }
        };
        IncrementalDisplayable.prototype.getBoundingRect = function () {
            if (!this._rect) {
                var rect = new BoundingRect(Infinity, Infinity, -Infinity, -Infinity);
                for (var i = 0; i < this._displayables.length; i++) {
                    var displayable = this._displayables[i];
                    var childRect = displayable.getBoundingRect().clone();
                    if (displayable.needLocalTransform()) {
                        childRect.applyTransform(displayable.getLocalTransform(m));
                    }
                    rect.union(childRect);
                }
                this._rect = rect;
            }
            return this._rect;
        };
        IncrementalDisplayable.prototype.contain = function (x, y) {
            var localPos = this.transformCoordToLocal(x, y);
            var rect = this.getBoundingRect();
            if (rect.contain(localPos[0], localPos[1])) {
                for (var i = 0; i < this._displayables.length; i++) {
                    var displayable = this._displayables[i];
                    if (displayable.contain(x, y)) {
                        return true;
                    }
                }
            }
            return false;
        };
        return IncrementalDisplayable;
    }(Displayable));

    var transitionStore = makeInner();
    /**
     * Return null if animation is disabled.
     */

    function getAnimationConfig(animationType, animatableModel, dataIndex, // Extra opts can override the option in animatable model.
    extraOpts, // TODO It's only for pictorial bar now.
    extraDelayParams) {
      var animationPayload; // Check if there is global animation configuration from dataZoom/resize can override the config in option.
      // If animation is enabled. Will use this animation config in payload.
      // If animation is disabled. Just ignore it.

      if (animatableModel && animatableModel.ecModel) {
        var updatePayload = animatableModel.ecModel.getUpdatePayload();
        animationPayload = updatePayload && updatePayload.animation;
      }

      var animationEnabled = animatableModel && animatableModel.isAnimationEnabled();
      var isUpdate = animationType === 'update';

      if (animationEnabled) {
        var duration = void 0;
        var easing = void 0;
        var delay = void 0;

        if (extraOpts) {
          duration = retrieve2(extraOpts.duration, 200);
          easing = retrieve2(extraOpts.easing, 'cubicOut');
          delay = 0;
        } else {
          duration = animatableModel.getShallow(isUpdate ? 'animationDurationUpdate' : 'animationDuration');
          easing = animatableModel.getShallow(isUpdate ? 'animationEasingUpdate' : 'animationEasing');
          delay = animatableModel.getShallow(isUpdate ? 'animationDelayUpdate' : 'animationDelay');
        } // animation from payload has highest priority.


        if (animationPayload) {
          animationPayload.duration != null && (duration = animationPayload.duration);
          animationPayload.easing != null && (easing = animationPayload.easing);
          animationPayload.delay != null && (delay = animationPayload.delay);
        }

        if (isFunction(delay)) {
          delay = delay(dataIndex, extraDelayParams);
        }

        if (isFunction(duration)) {
          duration = duration(dataIndex);
        }

        var config = {
          duration: duration || 0,
          delay: delay,
          easing: easing
        };
        return config;
      } else {
        return null;
      }
    }

    function animateOrSetProps(animationType, el, props, animatableModel, dataIndex, cb, during) {
      var isFrom = false;
      var removeOpt;

      if (isFunction(dataIndex)) {
        during = cb;
        cb = dataIndex;
        dataIndex = null;
      } else if (isObject(dataIndex)) {
        cb = dataIndex.cb;
        during = dataIndex.during;
        isFrom = dataIndex.isFrom;
        removeOpt = dataIndex.removeOpt;
        dataIndex = dataIndex.dataIndex;
      }

      var isRemove = animationType === 'leave';

      if (!isRemove) {
        // Must stop the remove animation.
        el.stopAnimation('leave');
      }

      var animationConfig = getAnimationConfig(animationType, animatableModel, dataIndex, isRemove ? removeOpt || {} : null, animatableModel && animatableModel.getAnimationDelayParams ? animatableModel.getAnimationDelayParams(el, dataIndex) : null);

      if (animationConfig && animationConfig.duration > 0) {
        var duration = animationConfig.duration;
        var animationDelay = animationConfig.delay;
        var animationEasing = animationConfig.easing;
        var animateConfig = {
          duration: duration,
          delay: animationDelay || 0,
          easing: animationEasing,
          done: cb,
          force: !!cb || !!during,
          // Set to final state in update/init animation.
          // So the post processing based on the path shape can be done correctly.
          setToFinal: !isRemove,
          scope: animationType,
          during: during
        };
        isFrom ? el.animateFrom(props, animateConfig) : el.animateTo(props, animateConfig);
      } else {
        el.stopAnimation(); // If `isFrom`, the props is the "from" props.

        !isFrom && el.attr(props); // Call during at least once.

        during && during(1);
        cb && cb();
      }
    }
    /**
     * Update graphic element properties with or without animation according to the
     * configuration in series.
     *
     * Caution: this method will stop previous animation.
     * So do not use this method to one element twice before
     * animation starts, unless you know what you are doing.
     * @example
     *     graphic.updateProps(el, {
     *         position: [100, 100]
     *     }, seriesModel, dataIndex, function () { console.log('Animation done!'); });
     *     // Or
     *     graphic.updateProps(el, {
     *         position: [100, 100]
     *     }, seriesModel, function () { console.log('Animation done!'); });
     */


    function updateProps(el, props, // TODO: TYPE AnimatableModel
    animatableModel, dataIndex, cb, during) {
      animateOrSetProps('update', el, props, animatableModel, dataIndex, cb, during);
    }
    /**
     * Init graphic element properties with or without animation according to the
     * configuration in series.
     *
     * Caution: this method will stop previous animation.
     * So do not use this method to one element twice before
     * animation starts, unless you know what you are doing.
     */

    function initProps(el, props, animatableModel, dataIndex, cb, during) {
      animateOrSetProps('enter', el, props, animatableModel, dataIndex, cb, during);
    }
    /**
     * If element is removed.
     * It can determine if element is having remove animation.
     */

    function isElementRemoved(el) {
      if (!el.__zr) {
        return true;
      }

      for (var i = 0; i < el.animators.length; i++) {
        var animator = el.animators[i];

        if (animator.scope === 'leave') {
          return true;
        }
      }

      return false;
    }
    /**
     * Remove graphic element
     */

    function removeElement(el, props, animatableModel, dataIndex, cb, during) {
      // Don't do remove animation twice.
      if (isElementRemoved(el)) {
        return;
      }

      animateOrSetProps('leave', el, props, animatableModel, dataIndex, cb, during);
    }

    function fadeOutDisplayable(el, animatableModel, dataIndex, done) {
      el.removeTextContent();
      el.removeTextGuideLine();
      removeElement(el, {
        style: {
          opacity: 0
        }
      }, animatableModel, dataIndex, done);
    }

    function removeElementWithFadeOut(el, animatableModel, dataIndex) {
      function doRemove() {
        el.parent && el.parent.remove(el);
      } // Hide label and labelLine first
      // TODO Also use fade out animation?


      if (!el.isGroup) {
        fadeOutDisplayable(el, animatableModel, dataIndex, doRemove);
      } else {
        el.traverse(function (disp) {
          if (!disp.isGroup) {
            // Can invoke doRemove multiple times.
            fadeOutDisplayable(disp, animatableModel, dataIndex, doRemove);
          }
        });
      }
    }
    /**
     * Save old style for style transition in universalTransition module.
     * It's used when element will be reused in each render.
     * For chart like map, heatmap, which will always create new element.
     * We don't need to save this because universalTransition can get old style from the old element
     */

    function saveOldStyle(el) {
      transitionStore(el).oldStyle = el.style;
    }

    var mathMax$4 = Math.max;
    var mathMin$4 = Math.min;
    var _customShapeMap = {};
    /**
     * Extend shape with parameters
     */

    function extendShape(opts) {
      return Path.extend(opts);
    }
    var extendPathFromString = extendFromString;
    /**
     * Extend path
     */

    function extendPath(pathData, opts) {
      return extendPathFromString(pathData, opts);
    }
    /**
     * Register a user defined shape.
     * The shape class can be fetched by `getShapeClass`
     * This method will overwrite the registered shapes, including
     * the registered built-in shapes, if using the same `name`.
     * The shape can be used in `custom series` and
     * `graphic component` by declaring `{type: name}`.
     *
     * @param name
     * @param ShapeClass Can be generated by `extendShape`.
     */

    function registerShape(name, ShapeClass) {
      _customShapeMap[name] = ShapeClass;
    }
    /**
     * Find shape class registered by `registerShape`. Usually used in
     * fetching user defined shape.
     *
     * [Caution]:
     * (1) This method **MUST NOT be used inside echarts !!!**, unless it is prepared
     * to use user registered shapes.
     * Because the built-in shape (see `getBuiltInShape`) will be registered by
     * `registerShape` by default. That enables users to get both built-in
     * shapes as well as the shapes belonging to themsleves. But users can overwrite
     * the built-in shapes by using names like 'circle', 'rect' via calling
     * `registerShape`. So the echarts inner featrues should not fetch shapes from here
     * in case that it is overwritten by users, except that some features, like
     * `custom series`, `graphic component`, do it deliberately.
     *
     * (2) In the features like `custom series`, `graphic component`, the user input
     * `{tpye: 'xxx'}` does not only specify shapes but also specify other graphic
     * elements like `'group'`, `'text'`, `'image'` or event `'path'`. Those names
     * are reserved names, that is, if some user registers a shape named `'image'`,
     * the shape will not be used. If we intending to add some more reserved names
     * in feature, that might bring break changes (disable some existing user shape
     * names). But that case probably rarely happens. So we don't make more mechanism
     * to resolve this issue here.
     *
     * @param name
     * @return The shape class. If not found, return nothing.
     */

    function getShapeClass(name) {
      if (_customShapeMap.hasOwnProperty(name)) {
        return _customShapeMap[name];
      }
    }
    /**
     * Create a path element from path data string
     * @param pathData
     * @param opts
     * @param rect
     * @param layout 'center' or 'cover' default to be cover
     */

    function makePath(pathData, opts, rect, layout) {
      var path = createFromString(pathData, opts);

      if (rect) {
        if (layout === 'center') {
          rect = centerGraphic(rect, path.getBoundingRect());
        }

        resizePath(path, rect);
      }

      return path;
    }
    /**
     * Create a image element from image url
     * @param imageUrl image url
     * @param opts options
     * @param rect constrain rect
     * @param layout 'center' or 'cover'. Default to be 'cover'
     */

    function makeImage(imageUrl, rect, layout) {
      var zrImg = new ZRImage({
        style: {
          image: imageUrl,
          x: rect.x,
          y: rect.y,
          width: rect.width,
          height: rect.height
        },
        onload: function (img) {
          if (layout === 'center') {
            var boundingRect = {
              width: img.width,
              height: img.height
            };
            zrImg.setStyle(centerGraphic(rect, boundingRect));
          }
        }
      });
      return zrImg;
    }
    /**
     * Get position of centered element in bounding box.
     *
     * @param  rect         element local bounding box
     * @param  boundingRect constraint bounding box
     * @return element position containing x, y, width, and height
     */

    function centerGraphic(rect, boundingRect) {
      // Set rect to center, keep width / height ratio.
      var aspect = boundingRect.width / boundingRect.height;
      var width = rect.height * aspect;
      var height;

      if (width <= rect.width) {
        height = rect.height;
      } else {
        width = rect.width;
        height = width / aspect;
      }

      var cx = rect.x + rect.width / 2;
      var cy = rect.y + rect.height / 2;
      return {
        x: cx - width / 2,
        y: cy - height / 2,
        width: width,
        height: height
      };
    }

    var mergePath$1 = mergePath;
    /**
     * Resize a path to fit the rect
     * @param path
     * @param rect
     */

    function resizePath(path, rect) {
      if (!path.applyTransform) {
        return;
      }

      var pathRect = path.getBoundingRect();
      var m = pathRect.calculateTransform(rect);
      path.applyTransform(m);
    }
    /**
     * Sub pixel optimize line for canvas
     */

    function subPixelOptimizeLine$1(shape, lineWidth) {
      subPixelOptimizeLine(shape, shape, {
        lineWidth: lineWidth
      });
      return shape;
    }
    /**
     * Sub pixel optimize rect for canvas
     */

    function subPixelOptimizeRect$1(param) {
      subPixelOptimizeRect(param.shape, param.shape, param.style);
      return param;
    }
    /**
     * Sub pixel optimize for canvas
     *
     * @param position Coordinate, such as x, y
     * @param lineWidth Should be nonnegative integer.
     * @param positiveOrNegative Default false (negative).
     * @return Optimized position.
     */

    var subPixelOptimize$1 = subPixelOptimize;
    /**
     * Get transform matrix of target (param target),
     * in coordinate of its ancestor (param ancestor)
     *
     * @param target
     * @param [ancestor]
     */

    function getTransform(target, ancestor) {
      var mat = identity([]);

      while (target && target !== ancestor) {
        mul$1(mat, target.getLocalTransform(), mat);
        target = target.parent;
      }

      return mat;
    }
    /**
     * Apply transform to an vertex.
     * @param target [x, y]
     * @param transform Can be:
     *      + Transform matrix: like [1, 0, 0, 1, 0, 0]
     *      + {position, rotation, scale}, the same as `zrender/Transformable`.
     * @param invert Whether use invert matrix.
     * @return [x, y]
     */

    function applyTransform$1(target, transform, invert$1) {
      if (transform && !isArrayLike(transform)) {
        transform = Transformable.getLocalTransform(transform);
      }

      if (invert$1) {
        transform = invert([], transform);
      }

      return applyTransform([], target, transform);
    }
    /**
     * @param direction 'left' 'right' 'top' 'bottom'
     * @param transform Transform matrix: like [1, 0, 0, 1, 0, 0]
     * @param invert Whether use invert matrix.
     * @return Transformed direction. 'left' 'right' 'top' 'bottom'
     */

    function transformDirection(direction, transform, invert) {
      // Pick a base, ensure that transform result will not be (0, 0).
      var hBase = transform[4] === 0 || transform[5] === 0 || transform[0] === 0 ? 1 : Math.abs(2 * transform[4] / transform[0]);
      var vBase = transform[4] === 0 || transform[5] === 0 || transform[2] === 0 ? 1 : Math.abs(2 * transform[4] / transform[2]);
      var vertex = [direction === 'left' ? -hBase : direction === 'right' ? hBase : 0, direction === 'top' ? -vBase : direction === 'bottom' ? vBase : 0];
      vertex = applyTransform$1(vertex, transform, invert);
      return Math.abs(vertex[0]) > Math.abs(vertex[1]) ? vertex[0] > 0 ? 'right' : 'left' : vertex[1] > 0 ? 'bottom' : 'top';
    }

    function isNotGroup(el) {
      return !el.isGroup;
    }

    function isPath(el) {
      return el.shape != null;
    }
    /**
     * Apply group transition animation from g1 to g2.
     * If no animatableModel, no animation.
     */


    function groupTransition(g1, g2, animatableModel) {
      if (!g1 || !g2) {
        return;
      }

      function getElMap(g) {
        var elMap = {};
        g.traverse(function (el) {
          if (isNotGroup(el) && el.anid) {
            elMap[el.anid] = el;
          }
        });
        return elMap;
      }

      function getAnimatableProps(el) {
        var obj = {
          x: el.x,
          y: el.y,
          rotation: el.rotation
        };

        if (isPath(el)) {
          obj.shape = extend({}, el.shape);
        }

        return obj;
      }

      var elMap1 = getElMap(g1);
      g2.traverse(function (el) {
        if (isNotGroup(el) && el.anid) {
          var oldEl = elMap1[el.anid];

          if (oldEl) {
            var newProp = getAnimatableProps(el);
            el.attr(getAnimatableProps(oldEl));
            updateProps(el, newProp, animatableModel, getECData(el).dataIndex);
          }
        }
      });
    }
    function clipPointsByRect(points, rect) {
      // FIXME: This way might be incorrect when graphic clipped by a corner
      // and when element has a border.
      return map(points, function (point) {
        var x = point[0];
        x = mathMax$4(x, rect.x);
        x = mathMin$4(x, rect.x + rect.width);
        var y = point[1];
        y = mathMax$4(y, rect.y);
        y = mathMin$4(y, rect.y + rect.height);
        return [x, y];
      });
    }
    /**
     * Return a new clipped rect. If rect size are negative, return undefined.
     */

    function clipRectByRect(targetRect, rect) {
      var x = mathMax$4(targetRect.x, rect.x);
      var x2 = mathMin$4(targetRect.x + targetRect.width, rect.x + rect.width);
      var y = mathMax$4(targetRect.y, rect.y);
      var y2 = mathMin$4(targetRect.y + targetRect.height, rect.y + rect.height); // If the total rect is cliped, nothing, including the border,
      // should be painted. So return undefined.

      if (x2 >= x && y2 >= y) {
        return {
          x: x,
          y: y,
          width: x2 - x,
          height: y2 - y
        };
      }
    }
    function createIcon(iconStr, // Support 'image://' or 'path://' or direct svg path.
    opt, rect) {
      var innerOpts = extend({
        rectHover: true
      }, opt);
      var style = innerOpts.style = {
        strokeNoScale: true
      };
      rect = rect || {
        x: -1,
        y: -1,
        width: 2,
        height: 2
      };

      if (iconStr) {
        return iconStr.indexOf('image://') === 0 ? (style.image = iconStr.slice(8), defaults(style, rect), new ZRImage(innerOpts)) : makePath(iconStr.replace('path://', ''), innerOpts, rect, 'center');
      }
    }
    /**
     * Return `true` if the given line (line `a`) and the given polygon
     * are intersect.
     * Note that we do not count colinear as intersect here because no
     * requirement for that. We could do that if required in future.
     */

    function linePolygonIntersect(a1x, a1y, a2x, a2y, points) {
      for (var i = 0, p2 = points[points.length - 1]; i < points.length; i++) {
        var p = points[i];

        if (lineLineIntersect(a1x, a1y, a2x, a2y, p[0], p[1], p2[0], p2[1])) {
          return true;
        }

        p2 = p;
      }
    }
    /**
     * Return `true` if the given two lines (line `a` and line `b`)
     * are intersect.
     * Note that we do not count colinear as intersect here because no
     * requirement for that. We could do that if required in future.
     */

    function lineLineIntersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y) {
      // let `vec_m` to be `vec_a2 - vec_a1` and `vec_n` to be `vec_b2 - vec_b1`.
      var mx = a2x - a1x;
      var my = a2y - a1y;
      var nx = b2x - b1x;
      var ny = b2y - b1y; // `vec_m` and `vec_n` are parallel iff
      //     existing `k` such that `vec_m = k · vec_n`, equivalent to `vec_m X vec_n = 0`.

      var nmCrossProduct = crossProduct2d(nx, ny, mx, my);

      if (nearZero(nmCrossProduct)) {
        return false;
      } // `vec_m` and `vec_n` are intersect iff
      //     existing `p` and `q` in [0, 1] such that `vec_a1 + p * vec_m = vec_b1 + q * vec_n`,
      //     such that `q = ((vec_a1 - vec_b1) X vec_m) / (vec_n X vec_m)`
      //           and `p = ((vec_a1 - vec_b1) X vec_n) / (vec_n X vec_m)`.


      var b1a1x = a1x - b1x;
      var b1a1y = a1y - b1y;
      var q = crossProduct2d(b1a1x, b1a1y, mx, my) / nmCrossProduct;

      if (q < 0 || q > 1) {
        return false;
      }

      var p = crossProduct2d(b1a1x, b1a1y, nx, ny) / nmCrossProduct;

      if (p < 0 || p > 1) {
        return false;
      }

      return true;
    }
    /**
     * Cross product of 2-dimension vector.
     */

    function crossProduct2d(x1, y1, x2, y2) {
      return x1 * y2 - x2 * y1;
    }

    function nearZero(val) {
      return val <= 1e-6 && val >= -1e-6;
    }

    function setTooltipConfig(opt) {
      var itemTooltipOption = opt.itemTooltipOption;
      var componentModel = opt.componentModel;
      var itemName = opt.itemName;
      var itemTooltipOptionObj = isString(itemTooltipOption) ? {
        formatter: itemTooltipOption
      } : itemTooltipOption;
      var mainType = componentModel.mainType;
      var componentIndex = componentModel.componentIndex;
      var formatterParams = {
        componentType: mainType,
        name: itemName,
        $vars: ['name']
      };
      formatterParams[mainType + 'Index'] = componentIndex;
      var formatterParamsExtra = opt.formatterParamsExtra;

      if (formatterParamsExtra) {
        each(keys(formatterParamsExtra), function (key) {
          if (!hasOwn(formatterParams, key)) {
            formatterParams[key] = formatterParamsExtra[key];
            formatterParams.$vars.push(key);
          }
        });
      }

      var ecData = getECData(opt.el);
      ecData.componentMainType = mainType;
      ecData.componentIndex = componentIndex;
      ecData.tooltipConfig = {
        name: itemName,
        option: defaults({
          content: itemName,
          formatterParams: formatterParams
        }, itemTooltipOptionObj)
      };
    }

    function traverseElement(el, cb) {
      var stopped; // TODO
      // Polyfill for fixing zrender group traverse don't visit it's root issue.

      if (el.isGroup) {
        stopped = cb(el);
      }

      if (!stopped) {
        el.traverse(cb);
      }
    }

    function traverseElements(els, cb) {
      if (els) {
        if (isArray(els)) {
          for (var i = 0; i < els.length; i++) {
            traverseElement(els[i], cb);
          }
        } else {
          traverseElement(els, cb);
        }
      }
    } // Register built-in shapes. These shapes might be overwritten
    // by users, although we do not recommend that.

    registerShape('circle', Circle);
    registerShape('ellipse', Ellipse);
    registerShape('sector', Sector);
    registerShape('ring', Ring);
    registerShape('polygon', Polygon);
    registerShape('polyline', Polyline);
    registerShape('rect', Rect);
    registerShape('line', Line);
    registerShape('bezierCurve', BezierCurve);
    registerShape('arc', Arc);

    var graphic = /*#__PURE__*/Object.freeze({
        __proto__: null,
        updateProps: updateProps,
        initProps: initProps,
        removeElement: removeElement,
        removeElementWithFadeOut: removeElementWithFadeOut,
        isElementRemoved: isElementRemoved,
        extendShape: extendShape,
        extendPath: extendPath,
        registerShape: registerShape,
        getShapeClass: getShapeClass,
        makePath: makePath,
        makeImage: makeImage,
        mergePath: mergePath$1,
        resizePath: resizePath,
        subPixelOptimizeLine: subPixelOptimizeLine$1,
        subPixelOptimizeRect: subPixelOptimizeRect$1,
        subPixelOptimize: subPixelOptimize$1,
        getTransform: getTransform,
        applyTransform: applyTransform$1,
        transformDirection: transformDirection,
        groupTransition: groupTransition,
        clipPointsByRect: clipPointsByRect,
        clipRectByRect: clipRectByRect,
        createIcon: createIcon,
        linePolygonIntersect: linePolygonIntersect,
        lineLineIntersect: lineLineIntersect,
        setTooltipConfig: setTooltipConfig,
        traverseElements: traverseElements,
        Group: Group,
        Image: ZRImage,
        Text: ZRText,
        Circle: Circle,
        Ellipse: Ellipse,
        Sector: Sector,
        Ring: Ring,
        Polygon: Polygon,
        Polyline: Polyline,
        Rect: Rect,
        Line: Line,
        BezierCurve: BezierCurve,
        Arc: Arc,
        IncrementalDisplayable: IncrementalDisplayable,
        CompoundPath: CompoundPath,
        LinearGradient: LinearGradient,
        RadialGradient: RadialGradient,
        BoundingRect: BoundingRect,
        OrientedBoundingRect: OrientedBoundingRect,
        Point: Point,
        Path: Path
    });

    var EMPTY_OBJ = {};
    function setLabelText(label, labelTexts) {
      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        var stateName = SPECIAL_STATES[i];
        var text = labelTexts[stateName];
        var state = label.ensureState(stateName);
        state.style = state.style || {};
        state.style.text = text;
      }

      var oldStates = label.currentStates.slice();
      label.clearStates(true);
      label.setStyle({
        text: labelTexts.normal
      });
      label.useStates(oldStates, true);
    }

    function getLabelText(opt, stateModels, interpolatedValue) {
      var labelFetcher = opt.labelFetcher;
      var labelDataIndex = opt.labelDataIndex;
      var labelDimIndex = opt.labelDimIndex;
      var normalModel = stateModels.normal;
      var baseText;

      if (labelFetcher) {
        baseText = labelFetcher.getFormattedLabel(labelDataIndex, 'normal', null, labelDimIndex, normalModel && normalModel.get('formatter'), interpolatedValue != null ? {
          interpolatedValue: interpolatedValue
        } : null);
      }

      if (baseText == null) {
        baseText = isFunction(opt.defaultText) ? opt.defaultText(labelDataIndex, opt, interpolatedValue) : opt.defaultText;
      }

      var statesText = {
        normal: baseText
      };

      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        var stateName = SPECIAL_STATES[i];
        var stateModel = stateModels[stateName];
        statesText[stateName] = retrieve2(labelFetcher ? labelFetcher.getFormattedLabel(labelDataIndex, stateName, null, labelDimIndex, stateModel && stateModel.get('formatter')) : null, baseText);
      }

      return statesText;
    }

    function setLabelStyle(targetEl, labelStatesModels, opt, stateSpecified // TODO specified position?
    ) {
      opt = opt || EMPTY_OBJ;
      var isSetOnText = targetEl instanceof ZRText;
      var needsCreateText = false;

      for (var i = 0; i < DISPLAY_STATES.length; i++) {
        var stateModel = labelStatesModels[DISPLAY_STATES[i]];

        if (stateModel && stateModel.getShallow('show')) {
          needsCreateText = true;
          break;
        }
      }

      var textContent = isSetOnText ? targetEl : targetEl.getTextContent();

      if (needsCreateText) {
        if (!isSetOnText) {
          // Reuse the previous
          if (!textContent) {
            textContent = new ZRText();
            targetEl.setTextContent(textContent);
          } // Use same state proxy


          if (targetEl.stateProxy) {
            textContent.stateProxy = targetEl.stateProxy;
          }
        }

        var labelStatesTexts = getLabelText(opt, labelStatesModels);
        var normalModel = labelStatesModels.normal;
        var showNormal = !!normalModel.getShallow('show');
        var normalStyle = createTextStyle(normalModel, stateSpecified && stateSpecified.normal, opt, false, !isSetOnText);
        normalStyle.text = labelStatesTexts.normal;

        if (!isSetOnText) {
          // Always create new
          targetEl.setTextConfig(createTextConfig(normalModel, opt, false));
        }

        for (var i = 0; i < SPECIAL_STATES.length; i++) {
          var stateName = SPECIAL_STATES[i];
          var stateModel = labelStatesModels[stateName];

          if (stateModel) {
            var stateObj = textContent.ensureState(stateName);
            var stateShow = !!retrieve2(stateModel.getShallow('show'), showNormal);

            if (stateShow !== showNormal) {
              stateObj.ignore = !stateShow;
            }

            stateObj.style = createTextStyle(stateModel, stateSpecified && stateSpecified[stateName], opt, true, !isSetOnText);
            stateObj.style.text = labelStatesTexts[stateName];

            if (!isSetOnText) {
              var targetElEmphasisState = targetEl.ensureState(stateName);
              targetElEmphasisState.textConfig = createTextConfig(stateModel, opt, true);
            }
          }
        } // PENDING: if there is many requirements that emphasis position
        // need to be different from normal position, we might consider
        // auto silent is those cases.


        textContent.silent = !!normalModel.getShallow('silent'); // Keep x and y

        if (textContent.style.x != null) {
          normalStyle.x = textContent.style.x;
        }

        if (textContent.style.y != null) {
          normalStyle.y = textContent.style.y;
        }

        textContent.ignore = !showNormal; // Always create new style.

        textContent.useStyle(normalStyle);
        textContent.dirty();

        if (opt.enableTextSetter) {
          labelInner(textContent).setLabelText = function (interpolatedValue) {
            var labelStatesTexts = getLabelText(opt, labelStatesModels, interpolatedValue);
            setLabelText(textContent, labelStatesTexts);
          };
        }
      } else if (textContent) {
        // Not display rich text.
        textContent.ignore = true;
      }

      targetEl.dirty();
    }
    function getLabelStatesModels(itemModel, labelName) {
      labelName = labelName || 'label';
      var statesModels = {
        normal: itemModel.getModel(labelName)
      };

      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        var stateName = SPECIAL_STATES[i];
        statesModels[stateName] = itemModel.getModel([stateName, labelName]);
      }

      return statesModels;
    }
    /**
     * Set basic textStyle properties.
     */

    function createTextStyle(textStyleModel, specifiedTextStyle, // Fixed style in the code. Can't be set by model.
    opt, isNotNormal, isAttached // If text is attached on an element. If so, auto color will handling in zrender.
    ) {
      var textStyle = {};
      setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached);
      specifiedTextStyle && extend(textStyle, specifiedTextStyle); // textStyle.host && textStyle.host.dirty && textStyle.host.dirty(false);

      return textStyle;
    }
    function createTextConfig(textStyleModel, opt, isNotNormal) {
      opt = opt || {};
      var textConfig = {};
      var labelPosition;
      var labelRotate = textStyleModel.getShallow('rotate');
      var labelDistance = retrieve2(textStyleModel.getShallow('distance'), isNotNormal ? null : 5);
      var labelOffset = textStyleModel.getShallow('offset');
      labelPosition = textStyleModel.getShallow('position') || (isNotNormal ? null : 'inside'); // 'outside' is not a valid zr textPostion value, but used
      // in bar series, and magric type should be considered.

      labelPosition === 'outside' && (labelPosition = opt.defaultOutsidePosition || 'top');

      if (labelPosition != null) {
        textConfig.position = labelPosition;
      }

      if (labelOffset != null) {
        textConfig.offset = labelOffset;
      }

      if (labelRotate != null) {
        labelRotate *= Math.PI / 180;
        textConfig.rotation = labelRotate;
      }

      if (labelDistance != null) {
        textConfig.distance = labelDistance;
      } // fill and auto is determined by the color of path fill if it's not specified by developers.


      textConfig.outsideFill = textStyleModel.get('color') === 'inherit' ? opt.inheritColor || null : 'auto';
      return textConfig;
    }
    /**
     * The uniform entry of set text style, that is, retrieve style definitions
     * from `model` and set to `textStyle` object.
     *
     * Never in merge mode, but in overwrite mode, that is, all of the text style
     * properties will be set. (Consider the states of normal and emphasis and
     * default value can be adopted, merge would make the logic too complicated
     * to manage.)
     */

    function setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached) {
      // Consider there will be abnormal when merge hover style to normal style if given default value.
      opt = opt || EMPTY_OBJ;
      var ecModel = textStyleModel.ecModel;
      var globalTextStyle = ecModel && ecModel.option.textStyle; // Consider case:
      // {
      //     data: [{
      //         value: 12,
      //         label: {
      //             rich: {
      //                 // no 'a' here but using parent 'a'.
      //             }
      //         }
      //     }],
      //     rich: {
      //         a: { ... }
      //     }
      // }

      var richItemNames = getRichItemNames(textStyleModel);
      var richResult;

      if (richItemNames) {
        richResult = {};

        for (var name_1 in richItemNames) {
          if (richItemNames.hasOwnProperty(name_1)) {
            // Cascade is supported in rich.
            var richTextStyle = textStyleModel.getModel(['rich', name_1]); // In rich, never `disableBox`.
            // FIXME: consider `label: {formatter: '{a|xx}', color: 'blue', rich: {a: {}}}`,
            // the default color `'blue'` will not be adopted if no color declared in `rich`.
            // That might confuses users. So probably we should put `textStyleModel` as the
            // root ancestor of the `richTextStyle`. But that would be a break change.

            setTokenTextStyle(richResult[name_1] = {}, richTextStyle, globalTextStyle, opt, isNotNormal, isAttached, false, true);
          }
        }
      }

      if (richResult) {
        textStyle.rich = richResult;
      }

      var overflow = textStyleModel.get('overflow');

      if (overflow) {
        textStyle.overflow = overflow;
      }

      var margin = textStyleModel.get('minMargin');

      if (margin != null) {
        textStyle.margin = margin;
      }

      setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, true, false);
    } // Consider case:
    // {
    //     data: [{
    //         value: 12,
    //         label: {
    //             rich: {
    //                 // no 'a' here but using parent 'a'.
    //             }
    //         }
    //     }],
    //     rich: {
    //         a: { ... }
    //     }
    // }
    // TODO TextStyleModel


    function getRichItemNames(textStyleModel) {
      // Use object to remove duplicated names.
      var richItemNameMap;

      while (textStyleModel && textStyleModel !== textStyleModel.ecModel) {
        var rich = (textStyleModel.option || EMPTY_OBJ).rich;

        if (rich) {
          richItemNameMap = richItemNameMap || {};
          var richKeys = keys(rich);

          for (var i = 0; i < richKeys.length; i++) {
            var richKey = richKeys[i];
            richItemNameMap[richKey] = 1;
          }
        }

        textStyleModel = textStyleModel.parentModel;
      }

      return richItemNameMap;
    }

    var TEXT_PROPS_WITH_GLOBAL = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY'];
    var TEXT_PROPS_SELF = ['align', 'lineHeight', 'width', 'height', 'tag', 'verticalAlign'];
    var TEXT_PROPS_BOX = ['padding', 'borderWidth', 'borderRadius', 'borderDashOffset', 'backgroundColor', 'borderColor', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'];

    function setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, isBlock, inRich) {
      // In merge mode, default value should not be given.
      globalTextStyle = !isNotNormal && globalTextStyle || EMPTY_OBJ;
      var inheritColor = opt && opt.inheritColor;
      var fillColor = textStyleModel.getShallow('color');
      var strokeColor = textStyleModel.getShallow('textBorderColor');
      var opacity = retrieve2(textStyleModel.getShallow('opacity'), globalTextStyle.opacity);

      if (fillColor === 'inherit' || fillColor === 'auto') {
        if ("development" !== 'production') {
          if (fillColor === 'auto') {
            deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\'');
          }
        }

        if (inheritColor) {
          fillColor = inheritColor;
        } else {
          fillColor = null;
        }
      }

      if (strokeColor === 'inherit' || strokeColor === 'auto') {
        if ("development" !== 'production') {
          if (strokeColor === 'auto') {
            deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\'');
          }
        }

        if (inheritColor) {
          strokeColor = inheritColor;
        } else {
          strokeColor = null;
        }
      }

      if (!isAttached) {
        // Only use default global textStyle.color if text is individual.
        // Otherwise it will use the strategy of attached text color because text may be on a path.
        fillColor = fillColor || globalTextStyle.color;
        strokeColor = strokeColor || globalTextStyle.textBorderColor;
      }

      if (fillColor != null) {
        textStyle.fill = fillColor;
      }

      if (strokeColor != null) {
        textStyle.stroke = strokeColor;
      }

      var textBorderWidth = retrieve2(textStyleModel.getShallow('textBorderWidth'), globalTextStyle.textBorderWidth);

      if (textBorderWidth != null) {
        textStyle.lineWidth = textBorderWidth;
      }

      var textBorderType = retrieve2(textStyleModel.getShallow('textBorderType'), globalTextStyle.textBorderType);

      if (textBorderType != null) {
        textStyle.lineDash = textBorderType;
      }

      var textBorderDashOffset = retrieve2(textStyleModel.getShallow('textBorderDashOffset'), globalTextStyle.textBorderDashOffset);

      if (textBorderDashOffset != null) {
        textStyle.lineDashOffset = textBorderDashOffset;
      }

      if (!isNotNormal && opacity == null && !inRich) {
        opacity = opt && opt.defaultOpacity;
      }

      if (opacity != null) {
        textStyle.opacity = opacity;
      } // TODO


      if (!isNotNormal && !isAttached) {
        // Set default finally.
        if (textStyle.fill == null && opt.inheritColor) {
          textStyle.fill = opt.inheritColor;
        }
      } // Do not use `getFont` here, because merge should be supported, where
      // part of these properties may be changed in emphasis style, and the
      // others should remain their original value got from normal style.


      for (var i = 0; i < TEXT_PROPS_WITH_GLOBAL.length; i++) {
        var key = TEXT_PROPS_WITH_GLOBAL[i];
        var val = retrieve2(textStyleModel.getShallow(key), globalTextStyle[key]);

        if (val != null) {
          textStyle[key] = val;
        }
      }

      for (var i = 0; i < TEXT_PROPS_SELF.length; i++) {
        var key = TEXT_PROPS_SELF[i];
        var val = textStyleModel.getShallow(key);

        if (val != null) {
          textStyle[key] = val;
        }
      }

      if (textStyle.verticalAlign == null) {
        var baseline = textStyleModel.getShallow('baseline');

        if (baseline != null) {
          textStyle.verticalAlign = baseline;
        }
      }

      if (!isBlock || !opt.disableBox) {
        for (var i = 0; i < TEXT_PROPS_BOX.length; i++) {
          var key = TEXT_PROPS_BOX[i];
          var val = textStyleModel.getShallow(key);

          if (val != null) {
            textStyle[key] = val;
          }
        }

        var borderType = textStyleModel.getShallow('borderType');

        if (borderType != null) {
          textStyle.borderDash = borderType;
        }

        if ((textStyle.backgroundColor === 'auto' || textStyle.backgroundColor === 'inherit') && inheritColor) {
          if ("development" !== 'production') {
            if (textStyle.backgroundColor === 'auto') {
              deprecateReplaceLog('backgroundColor: \'auto\'', 'backgroundColor: \'inherit\'');
            }
          }

          textStyle.backgroundColor = inheritColor;
        }

        if ((textStyle.borderColor === 'auto' || textStyle.borderColor === 'inherit') && inheritColor) {
          if ("development" !== 'production') {
            if (textStyle.borderColor === 'auto') {
              deprecateReplaceLog('borderColor: \'auto\'', 'borderColor: \'inherit\'');
            }
          }

          textStyle.borderColor = inheritColor;
        }
      }
    }

    function getFont(opt, ecModel) {
      var gTextStyleModel = ecModel && ecModel.getModel('textStyle');
      return trim([// FIXME in node-canvas fontWeight is before fontStyle
      opt.fontStyle || gTextStyleModel && gTextStyleModel.getShallow('fontStyle') || '', opt.fontWeight || gTextStyleModel && gTextStyleModel.getShallow('fontWeight') || '', (opt.fontSize || gTextStyleModel && gTextStyleModel.getShallow('fontSize') || 12) + 'px', opt.fontFamily || gTextStyleModel && gTextStyleModel.getShallow('fontFamily') || 'sans-serif'].join(' '));
    }
    var labelInner = makeInner();
    function setLabelValueAnimation(label, labelStatesModels, value, getDefaultText) {
      if (!label) {
        return;
      }

      var obj = labelInner(label);
      obj.prevValue = obj.value;
      obj.value = value;
      var normalLabelModel = labelStatesModels.normal;
      obj.valueAnimation = normalLabelModel.get('valueAnimation');

      if (obj.valueAnimation) {
        obj.precision = normalLabelModel.get('precision');
        obj.defaultInterpolatedText = getDefaultText;
        obj.statesModels = labelStatesModels;
      }
    }

    var PATH_COLOR = ['textStyle', 'color'];
    var textStyleParams = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'padding', 'lineHeight', 'rich', 'width', 'height', 'overflow']; // TODO Performance improvement?

    var tmpText = new ZRText();

    var TextStyleMixin =
    /** @class */
    function () {
      function TextStyleMixin() {}
      /**
       * Get color property or get color from option.textStyle.color
       */
      // TODO Callback


      TextStyleMixin.prototype.getTextColor = function (isEmphasis) {
        var ecModel = this.ecModel;
        return this.getShallow('color') || (!isEmphasis && ecModel ? ecModel.get(PATH_COLOR) : null);
      };
      /**
       * Create font string from fontStyle, fontWeight, fontSize, fontFamily
       * @return {string}
       */


      TextStyleMixin.prototype.getFont = function () {
        return getFont({
          fontStyle: this.getShallow('fontStyle'),
          fontWeight: this.getShallow('fontWeight'),
          fontSize: this.getShallow('fontSize'),
          fontFamily: this.getShallow('fontFamily')
        }, this.ecModel);
      };

      TextStyleMixin.prototype.getTextRect = function (text) {
        var style = {
          text: text,
          verticalAlign: this.getShallow('verticalAlign') || this.getShallow('baseline')
        };

        for (var i = 0; i < textStyleParams.length; i++) {
          style[textStyleParams[i]] = this.getShallow(textStyleParams[i]);
        }

        tmpText.useStyle(style);
        tmpText.update();
        return tmpText.getBoundingRect();
      };

      return TextStyleMixin;
    }();

    var LINE_STYLE_KEY_MAP = [['lineWidth', 'width'], ['stroke', 'color'], ['opacity'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'], ['lineDash', 'type'], ['lineDashOffset', 'dashOffset'], ['lineCap', 'cap'], ['lineJoin', 'join'], ['miterLimit'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
    // So do not transfer decal directly.
    ];
    var getLineStyle = makeStyleMapper(LINE_STYLE_KEY_MAP);

    var LineStyleMixin =
    /** @class */
    function () {
      function LineStyleMixin() {}

      LineStyleMixin.prototype.getLineStyle = function (excludes) {
        return getLineStyle(this, excludes);
      };

      return LineStyleMixin;
    }();

    var ITEM_STYLE_KEY_MAP = [['fill', 'color'], ['stroke', 'borderColor'], ['lineWidth', 'borderWidth'], ['opacity'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'], ['lineDash', 'borderType'], ['lineDashOffset', 'borderDashOffset'], ['lineCap', 'borderCap'], ['lineJoin', 'borderJoin'], ['miterLimit', 'borderMiterLimit'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
    // So do not transfer decal directly.
    ];
    var getItemStyle = makeStyleMapper(ITEM_STYLE_KEY_MAP);

    var ItemStyleMixin =
    /** @class */
    function () {
      function ItemStyleMixin() {}

      ItemStyleMixin.prototype.getItemStyle = function (excludes, includes) {
        return getItemStyle(this, excludes, includes);
      };

      return ItemStyleMixin;
    }();

    var Model =
    /** @class */
    function () {
      function Model(option, parentModel, ecModel) {
        this.parentModel = parentModel;
        this.ecModel = ecModel;
        this.option = option; // Simple optimization
        // if (this.init) {
        //     if (arguments.length <= 4) {
        //         this.init(option, parentModel, ecModel, extraOpt);
        //     }
        //     else {
        //         this.init.apply(this, arguments);
        //     }
        // }
      }

      Model.prototype.init = function (option, parentModel, ecModel) {
        var rest = [];

        for (var _i = 3; _i < arguments.length; _i++) {
          rest[_i - 3] = arguments[_i];
        }
      };
      /**
       * Merge the input option to me.
       */


      Model.prototype.mergeOption = function (option, ecModel) {
        merge(this.option, option, true);
      }; // `path` can be 'a.b.c', so the return value type have to be `ModelOption`
      // TODO: TYPE strict key check?
      // get(path: string | string[], ignoreParent?: boolean): ModelOption;


      Model.prototype.get = function (path, ignoreParent) {
        if (path == null) {
          return this.option;
        }

        return this._doGet(this.parsePath(path), !ignoreParent && this.parentModel);
      };

      Model.prototype.getShallow = function (key, ignoreParent) {
        var option = this.option;
        var val = option == null ? option : option[key];

        if (val == null && !ignoreParent) {
          var parentModel = this.parentModel;

          if (parentModel) {
            // FIXME:TS do not know how to make it works
            val = parentModel.getShallow(key);
          }
        }

        return val;
      }; // `path` can be 'a.b.c', so the return value type have to be `Model<ModelOption>`
      // getModel(path: string | string[], parentModel?: Model): Model;
      // TODO 'a.b.c' is deprecated


      Model.prototype.getModel = function (path, parentModel) {
        var hasPath = path != null;
        var pathFinal = hasPath ? this.parsePath(path) : null;
        var obj = hasPath ? this._doGet(pathFinal) : this.option;
        parentModel = parentModel || this.parentModel && this.parentModel.getModel(this.resolveParentPath(pathFinal));
        return new Model(obj, parentModel, this.ecModel);
      };
      /**
       * If model has option
       */


      Model.prototype.isEmpty = function () {
        return this.option == null;
      };

      Model.prototype.restoreData = function () {}; // Pending


      Model.prototype.clone = function () {
        var Ctor = this.constructor;
        return new Ctor(clone(this.option));
      }; // setReadOnly(properties): void {
      // clazzUtil.setReadOnly(this, properties);
      // }
      // If path is null/undefined, return null/undefined.


      Model.prototype.parsePath = function (path) {
        if (typeof path === 'string') {
          return path.split('.');
        }

        return path;
      }; // Resolve path for parent. Perhaps useful when parent use a different property.
      // Default to be a identity resolver.
      // Can be modified to a different resolver.


      Model.prototype.resolveParentPath = function (path) {
        return path;
      }; // FIXME:TS check whether put this method here


      Model.prototype.isAnimationEnabled = function () {
        if (!env.node && this.option) {
          if (this.option.animation != null) {
            return !!this.option.animation;
          } else if (this.parentModel) {
            return this.parentModel.isAnimationEnabled();
          }
        }
      };

      Model.prototype._doGet = function (pathArr, parentModel) {
        var obj = this.option;

        if (!pathArr) {
          return obj;
        }

        for (var i = 0; i < pathArr.length; i++) {
          // Ignore empty
          if (!pathArr[i]) {
            continue;
          } // obj could be number/string/... (like 0)


          obj = obj && typeof obj === 'object' ? obj[pathArr[i]] : null;

          if (obj == null) {
            break;
          }
        }

        if (obj == null && parentModel) {
          obj = parentModel._doGet(this.resolveParentPath(pathArr), parentModel.parentModel);
        }

        return obj;
      };

      return Model;
    }();

    enableClassExtend(Model);
    enableClassCheck(Model);
    mixin(Model, LineStyleMixin);
    mixin(Model, ItemStyleMixin);
    mixin(Model, AreaStyleMixin);
    mixin(Model, TextStyleMixin);

    var base = Math.round(Math.random() * 10);
    /**
     * @public
     * @param {string} type
     * @return {string}
     */

    function getUID(type) {
      // Considering the case of crossing js context,
      // use Math.random to make id as unique as possible.
      return [type || '', base++].join('_');
    }
    /**
     * Implements `SubTypeDefaulterManager` for `target`.
     */

    function enableSubTypeDefaulter(target) {
      var subTypeDefaulters = {};

      target.registerSubTypeDefaulter = function (componentType, defaulter) {
        var componentTypeInfo = parseClassType(componentType);
        subTypeDefaulters[componentTypeInfo.main] = defaulter;
      };

      target.determineSubType = function (componentType, option) {
        var type = option.type;

        if (!type) {
          var componentTypeMain = parseClassType(componentType).main;

          if (target.hasSubTypes(componentType) && subTypeDefaulters[componentTypeMain]) {
            type = subTypeDefaulters[componentTypeMain](option);
          }
        }

        return type;
      };
    }
    /**
     * Implements `TopologicalTravelable<any>` for `entity`.
     *
     * Topological travel on Activity Network (Activity On Vertices).
     * Dependencies is defined in Model.prototype.dependencies, like ['xAxis', 'yAxis'].
     * If 'xAxis' or 'yAxis' is absent in componentTypeList, just ignore it in topology.
     * If there is circular dependencey, Error will be thrown.
     */

    function enableTopologicalTravel(entity, dependencyGetter) {
      /**
       * @param targetNameList Target Component type list.
       *                       Can be ['aa', 'bb', 'aa.xx']
       * @param fullNameList By which we can build dependency graph.
       * @param callback Params: componentType, dependencies.
       * @param context Scope of callback.
       */
      entity.topologicalTravel = function (targetNameList, fullNameList, callback, context) {
        if (!targetNameList.length) {
          return;
        }

        var result = makeDepndencyGraph(fullNameList);
        var graph = result.graph;
        var noEntryList = result.noEntryList;
        var targetNameSet = {};
        each(targetNameList, function (name) {
          targetNameSet[name] = true;
        });

        while (noEntryList.length) {
          var currComponentType = noEntryList.pop();
          var currVertex = graph[currComponentType];
          var isInTargetNameSet = !!targetNameSet[currComponentType];

          if (isInTargetNameSet) {
            callback.call(context, currComponentType, currVertex.originalDeps.slice());
            delete targetNameSet[currComponentType];
          }

          each(currVertex.successor, isInTargetNameSet ? removeEdgeAndAdd : removeEdge);
        }

        each(targetNameSet, function () {
          var errMsg = '';

          if ("development" !== 'production') {
            errMsg = makePrintable('Circular dependency may exists: ', targetNameSet, targetNameList, fullNameList);
          }

          throw new Error(errMsg);
        });

        function removeEdge(succComponentType) {
          graph[succComponentType].entryCount--;

          if (graph[succComponentType].entryCount === 0) {
            noEntryList.push(succComponentType);
          }
        } // Consider this case: legend depends on series, and we call
        // chart.setOption({series: [...]}), where only series is in option.
        // If we do not have 'removeEdgeAndAdd', legendModel.mergeOption will
        // not be called, but only sereis.mergeOption is called. Thus legend
        // have no chance to update its local record about series (like which
        // name of series is available in legend).


        function removeEdgeAndAdd(succComponentType) {
          targetNameSet[succComponentType] = true;
          removeEdge(succComponentType);
        }
      };

      function makeDepndencyGraph(fullNameList) {
        var graph = {};
        var noEntryList = [];
        each(fullNameList, function (name) {
          var thisItem = createDependencyGraphItem(graph, name);
          var originalDeps = thisItem.originalDeps = dependencyGetter(name);
          var availableDeps = getAvailableDependencies(originalDeps, fullNameList);
          thisItem.entryCount = availableDeps.length;

          if (thisItem.entryCount === 0) {
            noEntryList.push(name);
          }

          each(availableDeps, function (dependentName) {
            if (indexOf(thisItem.predecessor, dependentName) < 0) {
              thisItem.predecessor.push(dependentName);
            }

            var thatItem = createDependencyGraphItem(graph, dependentName);

            if (indexOf(thatItem.successor, dependentName) < 0) {
              thatItem.successor.push(name);
            }
          });
        });
        return {
          graph: graph,
          noEntryList: noEntryList
        };
      }

      function createDependencyGraphItem(graph, name) {
        if (!graph[name]) {
          graph[name] = {
            predecessor: [],
            successor: []
          };
        }

        return graph[name];
      }

      function getAvailableDependencies(originalDeps, fullNameList) {
        var availableDeps = [];
        each(originalDeps, function (dep) {
          indexOf(fullNameList, dep) >= 0 && availableDeps.push(dep);
        });
        return availableDeps;
      }
    }
    function inheritDefaultOption(superOption, subOption) {
      // See also `model/Component.ts#getDefaultOption`
      return merge(merge({}, superOption, true), subOption, true);
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */

    /**
     * Language: English.
     */
    var langEN = {
      time: {
        month: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
        monthAbbr: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        dayOfWeek: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
        dayOfWeekAbbr: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
      },
      legend: {
        selector: {
          all: 'All',
          inverse: 'Inv'
        }
      },
      toolbox: {
        brush: {
          title: {
            rect: 'Box Select',
            polygon: 'Lasso Select',
            lineX: 'Horizontally Select',
            lineY: 'Vertically Select',
            keep: 'Keep Selections',
            clear: 'Clear Selections'
          }
        },
        dataView: {
          title: 'Data View',
          lang: ['Data View', 'Close', 'Refresh']
        },
        dataZoom: {
          title: {
            zoom: 'Zoom',
            back: 'Zoom Reset'
          }
        },
        magicType: {
          title: {
            line: 'Switch to Line Chart',
            bar: 'Switch to Bar Chart',
            stack: 'Stack',
            tiled: 'Tile'
          }
        },
        restore: {
          title: 'Restore'
        },
        saveAsImage: {
          title: 'Save as Image',
          lang: ['Right Click to Save Image']
        }
      },
      series: {
        typeNames: {
          pie: 'Pie chart',
          bar: 'Bar chart',
          line: 'Line chart',
          scatter: 'Scatter plot',
          effectScatter: 'Ripple scatter plot',
          radar: 'Radar chart',
          tree: 'Tree',
          treemap: 'Treemap',
          boxplot: 'Boxplot',
          candlestick: 'Candlestick',
          k: 'K line chart',
          heatmap: 'Heat map',
          map: 'Map',
          parallel: 'Parallel coordinate map',
          lines: 'Line graph',
          graph: 'Relationship graph',
          sankey: 'Sankey diagram',
          funnel: 'Funnel chart',
          gauge: 'Gauge',
          pictorialBar: 'Pictorial bar',
          themeRiver: 'Theme River Map',
          sunburst: 'Sunburst'
        }
      },
      aria: {
        general: {
          withTitle: 'This is a chart about "{title}"',
          withoutTitle: 'This is a chart'
        },
        series: {
          single: {
            prefix: '',
            withName: ' with type {seriesType} named {seriesName}.',
            withoutName: ' with type {seriesType}.'
          },
          multiple: {
            prefix: '. It consists of {seriesCount} series count.',
            withName: ' The {seriesId} series is a {seriesType} representing {seriesName}.',
            withoutName: ' The {seriesId} series is a {seriesType}.',
            separator: {
              middle: '',
              end: ''
            }
          }
        },
        data: {
          allData: 'The data is as follows: ',
          partialData: 'The first {displayCnt} items are: ',
          withName: 'the data for {name} is {value}',
          withoutName: '{value}',
          separator: {
            middle: ', ',
            end: '. '
          }
        }
      }
    };

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
     * Licensed to the Apache Software Foundation (ASF) under one
     * or more contributor license agreements.  See the NOTICE file
     * distributed with this work for additional information
     * regarding copyright ownership.  The ASF licenses this file
     * to you under the Apache License, Version 2.0 (the
     * "License"); you may not use this file except in compliance
     * with the License.  You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing,
     * software distributed under the License is distributed on an
     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     * KIND, either express or implied.  See the License for the
     * specific language governing permissions and limitations
     * under the License.
     */
    var langZH = {
      time: {
        month: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
        monthAbbr: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
        dayOfWeek: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
        dayOfWeekAbbr: ['日', '一', '二', '三', '四', '五', '六']
      },
      legend: {
        selector: {
          all: '全选',
          inverse: '反选'
        }
      },
      toolbox: {
        brush: {
          title: {
            rect: '矩形选择',
            polygon: '圈选',
            lineX: '横向选择',
            lineY: '纵向选择',
            keep: '保持选择',
            clear: '清除选择'
          }
        },
        dataView: {
          title: '数据视图',
          lang: ['数据视图', '关闭', '刷新']
        },
        dataZoom: {
          title: {
            zoom: '区域缩放',
            back: '区域缩放还原'
          }
        },
        magicType: {
          title: {
            line: '切换为折线图',
            bar: '切换为柱状图',
            stack: '切换为堆叠',
            tiled: '切换为平铺'
          }
        },
        restore: {
          title: '还原'
        },
        saveAsImage: {
          title: '保存为图片',
          lang: ['右键另存为图片']
        }
      },
      series: {
        typeNames: {
          pie: '饼图',
          bar: '柱状图',
          line: '折线图',
          scatter: '散点图',
          effectScatter: '涟漪散点图',
          radar: '雷达图',
          tree: '树图',
          treemap: '矩形树图',
          boxplot: '箱型图',
          candlestick: 'K线图',
          k: 'K线图',
          heatmap: '热力图',
          map: '地图',
          parallel: '平行坐标图',
          lines: '线图',
          graph: '关系图',
          sankey: '桑基图',
          funnel: '漏斗图',
          gauge: '仪表盘图',
          pictorialBar: '象形柱图',
          themeRiver: '主题河流图',
          sunburst: '旭日图'
        }
      },
      aria: {
        general: {
          withTitle: '这是一个关于“{title}”的图表。',
          withoutTitle: '这是一个图表，'
        },
        series: {
          single: {
            prefix: '',
            withName: '图表类型是{seriesType}，表示{seriesName}。',
            withoutName: '图表类型是{seriesType}。'
          },
          multiple: {
            prefix: '它由{seriesCount}个图表系列组成。',
            withName: '第{seriesId}个系列是一个表示{seriesName}的{seriesType}，',
            withoutName: '第{seriesId}个系列是一个{seriesType}，',
            separator: {
              middle: '；',
              end: '。'
            }
          }
        },
        data: {
          allData: '其数据是——',
          partialData: '其中，前{displayCnt}项是——',
          withName: '{name}的数据是{value}',
          withoutName: '{value}',
          separator: {
            middle: '，',
            end: ''
          }
        }
      }
    };

    var LOCALE_ZH = 'ZH';
    var LOCALE_EN = 'EN';
    var DEFAULT_LOCALE = LOCALE_EN;
    var localeStorage = {};
    var localeModels = {};
    var SYSTEM_LANG = !env.domSupported ? DEFAULT_LOCALE : function () {
      var langStr = (
      /* eslint-disable-next-line */
      document.documentElement.lang || navigator.language || navigator.browserLanguage).toUpperCase();
      return langStr.indexOf(LOCALE_ZH) > -1 ? LOCALE_ZH : DEFAULT_LOCALE;
    }();
    function registerLocale(locale, localeObj) {
      locale = locale.toUpperCase();
      localeModels[locale] = new Model(localeObj);
      localeStorage[locale] = localeObj;
    } // export function getLocale(locale: string) {
    //     return localeStorage[locale];
    // }

    function createLocaleObject(locale) {
      if (isString(locale)) {
        var localeObj = localeStorage[locale.toUpperCase()] || {};

        if (locale === LOCALE_ZH || locale === LOCALE_EN) {
          return clone(localeObj);
        } else {
          return merge(clone(localeObj), clone(localeStorage[DEFAULT_LOCALE]), false);
        }
      } else {
        return merge(clone(locale), clone(localeStorage[DEFAULT_LOCALE]), false);
      }
    }
    function getLocaleModel(lang) {
      return localeModels[lang];
    }
    function getDefaultLocaleModel() {
      return localeModels[DEFAULT_LOCALE];
    } // Default locale

    registerLocale(LOCALE_EN, langEN);
    registerLocale(LOCALE_ZH, langZH);

    var ONE_SECOND = 1000;
    var ONE_MINUTE = ONE_SECOND * 60;
    var ONE_HOUR = ONE_MINUTE * 60;
    var ONE_DAY = ONE_HOUR * 24;
    var ONE_YEAR = ONE_DAY * 365;
    var defaultLeveledFormatter = {
      year: '{yyyy}',
      month: '{MMM}',
      day: '{d}',
      hour: '{HH}:{mm}',
      minute: '{HH}:{mm}',
      second: '{HH}:{mm}:{ss}',
      millisecond: '{HH}:{mm}:{ss} {SSS}',
      none: '{yyyy}-{MM}-{dd} {HH}:{mm}:{ss} {SSS}'
    };
    var fullDayFormatter = '{yyyy}-{MM}-{dd}';
    var fullLeveledFormatter = {
      year: '{yyyy}',
      month: '{yyyy}-{MM}',
      day: fullDayFormatter,
      hour: fullDayFormatter + ' ' + defaultLeveledFormatter.hour,
      minute: fullDayFormatter + ' ' + defaultLeveledFormatter.minute,
      second: fullDayFormatter + ' ' + defaultLeveledFormatter.second,
      millisecond: defaultLeveledFormatter.none
    };
    var primaryTimeUnits = ['year', 'month', 'day', 'hour', 'minute', 'second', 'millisecond'];
    var timeUnits = ['year', 'half-year', 'quarter', 'month', 'week', 'half-week', 'day', 'half-day', 'quarter-day', 'hour', 'minute', 'second', 'millisecond'];
    function pad(str, len) {
      str += '';
      return '0000'.substr(0, len - str.length) + str;
    }
    function getPrimaryTimeUnit(timeUnit) {
      switch (timeUnit) {
        case 'half-year':
        case 'quarter':
          return 'month';

        case 'week':
        case 'half-week':
          return 'day';

        case 'half-day':
        case 'quarter-day':
          return 'hour';

        default:
          // year, minutes, second, milliseconds
          return timeUnit;
      }
    }
    function isPrimaryTimeUnit(timeUnit) {
      return timeUnit === getPrimaryTimeUnit(timeUnit);
    }
    function getDefaultFormatPrecisionOfInterval(timeUnit) {
      switch (timeUnit) {
        case 'year':
        case 'month':
          return 'day';

        case 'millisecond':
          return 'millisecond';

        default:
          // Also for day, hour, minute, second
          return 'second';
      }
    }
    function format( // Note: The result based on `isUTC` are totally different, which can not be just simply
    // substituted by the result without `isUTC`. So we make the param `isUTC` mandatory.
    time, template, isUTC, lang) {
      var date = parseDate(time);
      var y = date[fullYearGetterName(isUTC)]();
      var M = date[monthGetterName(isUTC)]() + 1;
      var q = Math.floor((M - 1) / 3) + 1;
      var d = date[dateGetterName(isUTC)]();
      var e = date['get' + (isUTC ? 'UTC' : '') + 'Day']();
      var H = date[hoursGetterName(isUTC)]();
      var h = (H - 1) % 12 + 1;
      var m = date[minutesGetterName(isUTC)]();
      var s = date[secondsGetterName(isUTC)]();
      var S = date[millisecondsGetterName(isUTC)]();
      var localeModel = lang instanceof Model ? lang : getLocaleModel(lang || SYSTEM_LANG) || getDefaultLocaleModel();
      var timeModel = localeModel.getModel('time');
      var month = timeModel.get('month');
      var monthAbbr = timeModel.get('monthAbbr');
      var dayOfWeek = timeModel.get('dayOfWeek');
      var dayOfWeekAbbr = timeModel.get('dayOfWeekAbbr');
      return (template || '').replace(/{yyyy}/g, y + '').replace(/{yy}/g, y % 100 + '').replace(/{Q}/g, q + '').replace(/{MMMM}/g, month[M - 1]).replace(/{MMM}/g, monthAbbr[M - 1]).replace(/{MM}/g, pad(M, 2)).replace(/{M}/g, M + '').replace(/{dd}/g, pad(d, 2)).replace(/{d}/g, d + '').replace(/{eeee}/g, dayOfWeek[e]).replace(/{ee}/g, dayOfWeekAbbr[e]).replace(/{e}/g, e + '').replace(/{HH}/g, pad(H, 2)).replace(/{H}/g, H + '').replace(/{hh}/g, pad(h + '', 2)).replace(/{h}/g, h + '').replace(/{mm}/g, pad(m, 2)).replace(/{m}/g, m + '').replace(/{ss}/g, pad(s, 2)).replace(/{s}/g, s + '').replace(/{SSS}/g, pad(S, 3)).replace(/{S}/g, S + '');
    }
    function leveledFormat(tick, idx, formatter, lang, isUTC) {
      var template = null;

      if (isString(formatter)) {
        // Single formatter for all units at all levels
        template = formatter;
      } else if (isFunction(formatter)) {
        // Callback formatter
        template = formatter(tick.value, idx, {
          level: tick.level
        });
      } else {
        var defaults$1 = extend({}, defaultLeveledFormatter);

        if (tick.level > 0) {
          for (var i = 0; i < primaryTimeUnits.length; ++i) {
            defaults$1[primaryTimeUnits[i]] = "{primary|" + defaults$1[primaryTimeUnits[i]] + "}";
          }
        }

        var mergedFormatter = formatter ? formatter.inherit === false ? formatter // Use formatter with bigger units
        : defaults(formatter, defaults$1) : defaults$1;
        var unit = getUnitFromValue(tick.value, isUTC);

        if (mergedFormatter[unit]) {
          template = mergedFormatter[unit];
        } else if (mergedFormatter.inherit) {
          // Unit formatter is not defined and should inherit from bigger units
          var targetId = timeUnits.indexOf(unit);

          for (var i = targetId - 1; i >= 0; --i) {
            if (mergedFormatter[unit]) {
              template = mergedFormatter[unit];
              break;
            }
          }

          template = template || defaults$1.none;
        }

        if (isArray(template)) {
          var levelId = tick.level == null ? 0 : tick.level >= 0 ? tick.level : template.length + tick.level;
          levelId = Math.min(levelId, template.length - 1);
          template = template[levelId];
        }
      }

      return format(new Date(tick.value), template, isUTC, lang);
    }
    function getUnitFromValue(value, isUTC) {
      var date = parseDate(value);
      var M = date[monthGetterName(isUTC)]() + 1;
      var d = date[dateGetterName(isUTC)]();
      var h = date[hoursGetterName(isUTC)]();
      var m = date[minutesGetterName(isUTC)]();
      var s = date[secondsGetterName(isUTC)]();
      var S = date[millisecondsGetterName(isUTC)]();
      var isSecond = S === 0;
      var isMinute = isSecond && s === 0;
      var isHour = isMinute && m === 0;
      var isDay = isHour && h === 0;
      var isMonth = isDay && d === 1;
      var isYear = isMonth && M === 1;

      if (isYear) {
        return 'year';
      } else if (isMonth) {
        return 'month';
      } else if (isDay) {
        return 'day';
      } else if (isHour) {
        return 'hour';
      } else if (isMinute) {
        return 'minute';
      } else if (isSecond) {
        return 'second';
      } else {
        return 'millisecond';
      }
    }
    function getUnitValue(value, unit, isUTC) {
      var date = isNumber(value) ? parseDate(value) : value;
      unit = unit || getUnitFromValue(value, isUTC);

      switch (unit) {
        case 'year':
          return date[fullYearGetterName(isUTC)]();

        case 'half-year':
          return date[monthGetterName(isUTC)]() >= 6 ? 1 : 0;

        case 'quarter':
          return Math.floor((date[monthGetterName(isUTC)]() + 1) / 4);

        case 'month':
          return date[monthGetterName(isUTC)]();

        case 'day':
          return date[dateGetterName(isUTC)]();

        case 'half-day':
          return date[hoursGetterName(isUTC)]() / 24;

        case 'hour':
          return date[hoursGetterName(isUTC)]();

        case 'minute':
          return date[minutesGetterName(isUTC)]();

        case 'second':
          return date[secondsGetterName(isUTC)]();

        case 'millisecond':
          return date[millisecondsGetterName(isUTC)]();
      }
    }
    function fullYearGetterName(isUTC) {
      return isUTC ? 'getUTCFullYear' : 'getFullYear';
    }
    function monthGetterName(isUTC) {
      return isUTC ? 'getUTCMonth' : 'getMonth';
    }
    function dateGetterName(isUTC) {
      return isUTC ? 'getUTCDate' : 'getDate';
    }
    function hoursGetterName(isUTC) {
      return isUTC ? 'getUTCHours' : 'getHours';
    }
    function minutesGetterName(isUTC) {
      return isUTC ? 'getUTCMinutes' : 'getMinutes';
    }
    function secondsGetterName(isUTC) {
      return isUTC ? 'getUTCSeconds' : 'getSeconds';
    }
    function millisecondsGetterName(isUTC) {
      return isUTC ? 'getUTCMilliseconds' : 'getMilliseconds';
    }
    function fullYearSetterName(isUTC) {
      return isUTC ? 'setUTCFullYear' : 'setFullYear';
    }
    function monthSetterName(isUTC) {
      return isUTC ? 'setUTCMonth' : 'setMonth';
    }
    function dateSetterName(isUTC) {
      return isUTC ? 'setUTCDate' : 'setDate';
    }
    function hoursSetterName(isUTC) {
      return isUTC ? 'setUTCHours' : 'setHours';
    }
    function minutesSetterName(isUTC) {
      return isUTC ? 'setUTCMinutes' : 'setMinutes';
    }
    function secondsSetterName(isUTC) {
      return isUTC ? 'setUTCSeconds' : 'setSeconds';
    }
    function millisecondsSetterName(isUTC) {
      return isUTC ? 'setUTCMilliseconds' : 'setMilliseconds';
    }

    function getTextRect(text, font, align, verticalAlign, padding, rich, truncate, lineHeight) {
      var textEl = new ZRText({
        style: {
          text: text,
          font: font,
          align: align,
          verticalAlign: verticalAlign,
          padding: padding,
          rich: rich,
          overflow: truncate ? 'truncate' : null,
          lineHeight: lineHeight
        }
      });
      return textEl.getBoundingRect();
    }

    /**
     * Add a comma each three digit.
     */

    function addCommas(x) {
      if (!isNumeric(x)) {
        return isString(x) ? x : '-';
      }

      var parts = (x + '').split('.');
      return parts[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g, '$1,') + (parts.length > 1 ? '.' + parts[1] : '');
    }
    function toCamelCase(str, upperCaseFirst) {
      str = (str || '').toLowerCase().replace(/-(.)/g, function (match, group1) {
        return group1.toUpperCase();
      });

      if (upperCaseFirst && str) {
        str = str.charAt(0).toUpperCase() + str.slice(1);
      }

      return str;
    }
    var normalizeCssArray$1 = normalizeCssArray;
    /**
     * Make value user readable for tooltip and label.
     * "User readable":
     *     Try to not print programmer-specific text like NaN, Infinity, null, undefined.
     *     Avoid to display an empty string, which users can not recognize there is
     *     a value and it might look like a bug.
     */

    function makeValueReadable(value, valueType, useUTC) {
      var USER_READABLE_DEFUALT_TIME_PATTERN = '{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}';

      function stringToUserReadable(str) {
        return str && trim(str) ? str : '-';
      }

      function isNumberUserReadable(num) {
        return !!(num != null && !isNaN(num) && isFinite(num));
      }

      var isTypeTime = valueType === 'time';
      var isValueDate = value instanceof Date;

      if (isTypeTime || isValueDate) {
        var date = isTypeTime ? parseDate(value) : value;

        if (!isNaN(+date)) {
          return format(date, USER_READABLE_DEFUALT_TIME_PATTERN, useUTC);
        } else if (isValueDate) {
          return '-';
        } // In other cases, continue to try to display the value in the following code.

      }

      if (valueType === 'ordinal') {
        return isStringSafe(value) ? stringToUserReadable(value) : isNumber(value) ? isNumberUserReadable(value) ? value + '' : '-' : '-';
      } // By default.


      var numericResult = numericToNumber(value);
      return isNumberUserReadable(numericResult) ? addCommas(numericResult) : isStringSafe(value) ? stringToUserReadable(value) : typeof value === 'boolean' ? value + '' : '-';
    }
    var TPL_VAR_ALIAS = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

    var wrapVar = function (varName, seriesIdx) {
      return '{' + varName + (seriesIdx == null ? '' : seriesIdx) + '}';
    };
    /**
     * Template formatter
     * @param {Array.<Object>|Object} paramsList
     */


    function formatTpl(tpl, paramsList, encode) {
      if (!isArray(paramsList)) {
        paramsList = [paramsList];
      }

      var seriesLen = paramsList.length;

      if (!seriesLen) {
        return '';
      }

      var $vars = paramsList[0].$vars || [];

      for (var i = 0; i < $vars.length; i++) {
        var alias = TPL_VAR_ALIAS[i];
        tpl = tpl.replace(wrapVar(alias), wrapVar(alias, 0));
      }

      for (var seriesIdx = 0; seriesIdx < seriesLen; seriesIdx++) {
        for (var k = 0; k < $vars.length; k++) {
          var val = paramsList[seriesIdx][$vars[k]];
          tpl = tpl.replace(wrapVar(TPL_VAR_ALIAS[k], seriesIdx), encode ? encodeHTML(val) : val);
        }
      }

      return tpl;
    }
    function getTooltipMarker(inOpt, extraCssText) {
      var opt = isString(inOpt) ? {
        color: inOpt,
        extraCssText: extraCssText
      } : inOpt || {};
      var color = opt.color;
      var type = opt.type;
      extraCssText = opt.extraCssText;
      var renderMode = opt.renderMode || 'html';

      if (!color) {
        return '';
      }

      if (renderMode === 'html') {
        return type === 'subItem' ? '<span style="display:inline-block;vertical-align:middle;margin-right:8px;margin-left:3px;' + 'border-radius:4px;width:4px;height:4px;background-color:' // Only support string
        + encodeHTML(color) + ';' + (extraCssText || '') + '"></span>' : '<span style="display:inline-block;margin-right:4px;' + 'border-radius:10px;width:10px;height:10px;background-color:' + encodeHTML(color) + ';' + (extraCssText || '') + '"></span>';
      } else {
        // Should better not to auto generate style name by auto-increment number here.
        // Because this util is usually called in tooltip formatter, which is probably
        // called repeatedly when mouse move and the auto-increment number increases fast.
        // Users can make their own style name by theirselves, make it unique and readable.
        var markerId = opt.markerId || 'markerX';
        return {
          renderMode: renderMode,
          content: '{' + markerId + '|}  ',
          style: type === 'subItem' ? {
            width: 4,
            height: 4,
            borderRadius: 2,
            backgroundColor: color
          } : {
            width: 10,
            height: 10,
            borderRadius: 5,
            backgroundColor: color
          }
        };
      }
    }
    /**
     * @deprecated Use `time/format` instead.
     * ISO Date format
     * @param {string} tpl
     * @param {number} value
     * @param {boolean} [isUTC=false] Default in local time.
     *           see `module:echarts/scale/Time`
     *           and `module:echarts/util/number#parseDate`.
     * @inner
     */

    function formatTime(tpl, value, isUTC) {
      if ("development" !== 'production') {
        deprecateReplaceLog('echarts.format.formatTime', 'echarts.time.format');
      }

      if (tpl === 'week' || tpl === 'month' || tpl === 'quarter' || tpl === 'half-year' || tpl === 'year') {
        tpl = 'MM-dd\nyyyy';
      }

      var date = parseDate(value);
      var getUTC = isUTC ? 'getUTC' : 'get';
      var y = date[getUTC + 'FullYear']();
      var M = date[getUTC + 'Month']() + 1;
      var d = date[getUTC + 'Date']();
      var h = date[getUTC + 'Hours']();
      var m = date[getUTC + 'Minutes']();
      var s = date[getUTC + 'Seconds']();
      var S = date[getUTC + 'Milliseconds']();
      tpl = tpl.replace('MM', pad(M, 2)).replace('M', M).replace('yyyy', y).replace('yy', pad(y % 100 + '', 2)).replace('dd', pad(d, 2)).replace('d', d).replace('hh', pad(h, 2)).replace('h', h).replace('mm', pad(m, 2)).replace('m', m).replace('ss', pad(s, 2)).replace('s', s).replace('SSS', pad(S, 3));
      return tpl;
    }
    /**
     * Capital first
     * @param {string} str
     * @return {string}
     */

    function capitalFirst(str) {
      return str ? str.charAt(0).toUpperCase() + str.substr(1) : str;
    }
    /**
     * @return Never be null/undefined.
     */

    function convertToColorString(color, defaultColor) {
      defaultColor = defaultColor || 'transparent';
      return isString(color) ? color : isObject(color) ? color.colorStops && (color.colorStops[0] || {}).color || defaultColor : defaultColor;
    }
    /**
     * open new tab
     * @param link url
     * @param target blank or self
     */

    function windowOpen(link, target) {
      /* global window */
      if (target === '_blank' || target === 'blank') {
        var blank = window.open();
        blank.opener = null;
        blank.location.href = link;
      } else {
        window.open(link, target);
      }
    }

    var each$1 = each;
    /**
     * @public
     */

    var LOCATION_PARAMS = ['left', 'right', 'top', 'bottom', 'width', 'height'];
    /**
     * @public
     */

    var HV_NAMES = [['width', 'left', 'right'], ['height', 'top', 'bottom']];

    function boxLayout(orient, group, gap, maxWidth, maxHeight) {
      var x = 0;
      var y = 0;

      if (maxWidth == null) {
        maxWidth = Infinity;
      }

      if (maxHeight == null) {
        maxHeight = Infinity;
      }

      var currentLineMaxSize = 0;
      group.eachChild(function (child, idx) {
        var rect = child.getBoundingRect();
        var nextChild = group.childAt(idx + 1);
        var nextChildRect = nextChild && nextChild.getBoundingRect();
        var nextX;
        var nextY;

        if (orient === 'horizontal') {
          var moveX = rect.width + (nextChildRect ? -nextChildRect.x + rect.x : 0);
          nextX = x + moveX; // Wrap when width exceeds maxWidth or meet a `newline` group
          // FIXME compare before adding gap?

          if (nextX > maxWidth || child.newline) {
            x = 0;
            nextX = moveX;
            y += currentLineMaxSize + gap;
            currentLineMaxSize = rect.height;
          } else {
            // FIXME: consider rect.y is not `0`?
            currentLineMaxSize = Math.max(currentLineMaxSize, rect.height);
          }
        } else {
          var moveY = rect.height + (nextChildRect ? -nextChildRect.y + rect.y : 0);
          nextY = y + moveY; // Wrap when width exceeds maxHeight or meet a `newline` group

          if (nextY > maxHeight || child.newline) {
            x += currentLineMaxSize + gap;
            y = 0;
            nextY = moveY;
            currentLineMaxSize = rect.width;
          } else {
            currentLineMaxSize = Math.max(currentLineMaxSize, rect.width);
          }
        }

        if (child.newline) {
          return;
        }

        child.x = x;
        child.y = y;
        child.markRedraw();
        orient === 'horizontal' ? x = nextX + gap : y = nextY + gap;
      });
    }
    /**
     * VBox or HBox layouting
     * @param {string} orient
     * @param {module:zrender/graphic/Group} group
     * @param {number} gap
     * @param {number} [width=Infinity]
     * @param {number} [height=Infinity]
     */


    var box = boxLayout;
    /**
     * VBox layouting
     * @param {module:zrender/graphic/Group} group
     * @param {number} gap
     * @param {number} [width=Infinity]
     * @param {number} [height=Infinity]
     */

    var vbox = curry(boxLayout, 'vertical');
    /**
     * HBox layouting
     * @param {module:zrender/graphic/Group} group
     * @param {number} gap
     * @param {number} [width=Infinity]
     * @param {number} [height=Infinity]
     */

    var hbox = curry(boxLayout, 'horizontal');
    /**
     * Parse position info.
     */

    function getLayoutRect(positionInfo, containerRect, margin) {
      margin = normalizeCssArray$1(margin || 0);
      var containerWidth = containerRect.width;
      var containerHeight = containerRect.height;
      var left = parsePercent$1(positionInfo.left, containerWidth);
      var top = parsePercent$1(positionInfo.top, containerHeight);
      var right = parsePercent$1(positionInfo.right, containerWidth);
      var bottom = parsePercent$1(positionInfo.bottom, containerHeight);
      var width = parsePercent$1(positionInfo.width, containerWidth);
      var height = parsePercent$1(positionInfo.height, containerHeight);
      var verticalMargin = margin[2] + margin[0];
      var horizontalMargin = margin[1] + margin[3];
      var aspect = positionInfo.aspect; // If width is not specified, calculate width from left and right

      if (isNaN(width)) {
        width = containerWidth - right - horizontalMargin - left;
      }

      if (isNaN(height)) {
        height = containerHeight - bottom - verticalMargin - top;
      }

      if (aspect != null) {
        // If width and height are not given
        // 1. Graph should not exceeds the container
        // 2. Aspect must be keeped
        // 3. Graph should take the space as more as possible
        // FIXME
        // Margin is not considered, because there is no case that both
        // using margin and aspect so far.
        if (isNaN(width) && isNaN(height)) {
          if (aspect > containerWidth / containerHeight) {
            width = containerWidth * 0.8;
          } else {
            height = containerHeight * 0.8;
          }
        } // Calculate width or height with given aspect


        if (isNaN(width)) {
          width = aspect * height;
        }

        if (isNaN(height)) {
          height = width / aspect;
        }
      } // If left is not specified, calculate left from right and width


      if (isNaN(left)) {
        left = containerWidth - right - width - horizontalMargin;
      }

      if (isNaN(top)) {
        top = containerHeight - bottom - height - verticalMargin;
      } // Align left and top


      switch (positionInfo.left || positionInfo.right) {
        case 'center':
          left = containerWidth / 2 - width / 2 - margin[3];
          break;

        case 'right':
          left = containerWidth - width - horizontalMargin;
          break;
      }

      switch (positionInfo.top || positionInfo.bottom) {
        case 'middle':
        case 'center':
          top = containerHeight / 2 - height / 2 - margin[0];
          break;

        case 'bottom':
          top = containerHeight - height - verticalMargin;
          break;
      } // If something is wrong and left, top, width, height are calculated as NaN


      left = left || 0;
      top = top || 0;

      if (isNaN(width)) {
        // Width may be NaN if only one value is given except width
        width = containerWidth - horizontalMargin - left - (right || 0);
      }

      if (isNaN(height)) {
        // Height may be NaN if only one value is given except height
        height = containerHeight - verticalMargin - top - (bottom || 0);
      }

      var rect = new BoundingRect(left + margin[3], top + margin[0], width, height);
      rect.margin = margin;
      return rect;
    }
    /**
     * Position a zr element in viewport
     *  Group position is specified by either
     *  {left, top}, {right, bottom}
     *  If all properties exists, right and bottom will be igonred.
     *
     * Logic:
     *     1. Scale (against origin point in parent coord)
     *     2. Rotate (against origin point in parent coord)
     *     3. Translate (with el.position by this method)
     * So this method only fixes the last step 'Translate', which does not affect
     * scaling and rotating.
     *
     * If be called repeatedly with the same input el, the same result will be gotten.
     *
     * Return true if the layout happened.
     *
     * @param el Should have `getBoundingRect` method.
     * @param positionInfo
     * @param positionInfo.left
     * @param positionInfo.top
     * @param positionInfo.right
     * @param positionInfo.bottom
     * @param positionInfo.width Only for opt.boundingModel: 'raw'
     * @param positionInfo.height Only for opt.boundingModel: 'raw'
     * @param containerRect
     * @param margin
     * @param opt
     * @param opt.hv Only horizontal or only vertical. Default to be [1, 1]
     * @param opt.boundingMode
     *        Specify how to calculate boundingRect when locating.
     *        'all': Position the boundingRect that is transformed and uioned
     *               both itself and its descendants.
     *               This mode simplies confine the elements in the bounding
     *               of their container (e.g., using 'right: 0').
     *        'raw': Position the boundingRect that is not transformed and only itself.
     *               This mode is useful when you want a element can overflow its
     *               container. (Consider a rotated circle needs to be located in a corner.)
     *               In this mode positionInfo.width/height can only be number.
     */

    function positionElement(el, positionInfo, containerRect, margin, opt, out) {
      var h = !opt || !opt.hv || opt.hv[0];
      var v = !opt || !opt.hv || opt.hv[1];
      var boundingMode = opt && opt.boundingMode || 'all';
      out = out || el;
      out.x = el.x;
      out.y = el.y;

      if (!h && !v) {
        return false;
      }

      var rect;

      if (boundingMode === 'raw') {
        rect = el.type === 'group' ? new BoundingRect(0, 0, +positionInfo.width || 0, +positionInfo.height || 0) : el.getBoundingRect();
      } else {
        rect = el.getBoundingRect();

        if (el.needLocalTransform()) {
          var transform = el.getLocalTransform(); // Notice: raw rect may be inner object of el,
          // which should not be modified.

          rect = rect.clone();
          rect.applyTransform(transform);
        }
      } // The real width and height can not be specified but calculated by the given el.


      var layoutRect = getLayoutRect(defaults({
        width: rect.width,
        height: rect.height
      }, positionInfo), containerRect, margin); // Because 'tranlate' is the last step in transform
      // (see zrender/core/Transformable#getLocalTransform),
      // we can just only modify el.position to get final result.

      var dx = h ? layoutRect.x - rect.x : 0;
      var dy = v ? layoutRect.y - rect.y : 0;

      if (boundingMode === 'raw') {
        out.x = dx;
        out.y = dy;
      } else {
        out.x += dx;
        out.y += dy;
      }

      if (out === el) {
        el.markRedraw();
      }

      return true;
    }
    function fetchLayoutMode(ins) {
      var layoutMode = ins.layoutMode || ins.constructor.layoutMode;
      return isObject(layoutMode) ? layoutMode : layoutMode ? {
        type: layoutMode
      } : null;
    }
    /**
     * Consider Case:
     * When default option has {left: 0, width: 100}, and we set {right: 0}
     * through setOption or media query, using normal zrUtil.merge will cause
     * {right: 0} does not take effect.
     *
     * @example
     * ComponentModel.extend({
     *     init: function () {
     *         ...
     *         let inputPositionParams = layout.getLayoutParams(option);
     *         this.mergeOption(inputPositionParams);
     *     },
     *     mergeOption: function (newOption) {
     *         newOption && zrUtil.merge(thisOption, newOption, true);
     *         layout.mergeLayoutParam(thisOption, newOption);
     *     }
     * });
     *
     * @param targetOption
     * @param newOption
     * @param opt
     */

    function mergeLayoutParam(targetOption, newOption, opt) {
      var ignoreSize = opt && opt.ignoreSize;
      !isArray(ignoreSize) && (ignoreSize = [ignoreSize, ignoreSize]);
      var hResult = merge(HV_NAMES[0], 0);
      var vResult = merge(HV_NAMES[1], 1);
      copy(HV_NAMES[0], targetOption, hResult);
      copy(HV_NAMES[1], targetOption, vResult);

      function merge(names, hvIdx) {
        var newParams = {};
        var newValueCount = 0;
        var merged = {};
        var mergedValueCount = 0;
        var enoughParamNumber = 2;
        each$1(names, function (name) {
          merged[name] = targetOption[name];
        });
        each$1(names, function (name) {
          // Consider case: newOption.width is null, which is
          // set by user for removing width setting.
          hasProp(newOption, name) && (newParams[name] = merged[name] = newOption[name]);
          hasValue(newParams, name) && newValueCount++;
          hasValue(merged, name) && mergedValueCount++;
        });

        if (ignoreSize[hvIdx]) {
          // Only one of left/right is premitted to exist.
          if (hasValue(newOption, names[1])) {
            merged[names[2]] = null;
          } else if (hasValue(newOption, names[2])) {
            merged[names[1]] = null;
          }

          return merged;
        } // Case: newOption: {width: ..., right: ...},
        // or targetOption: {right: ...} and newOption: {width: ...},
        // There is no conflict when merged only has params count
        // little than enoughParamNumber.


        if (mergedValueCount === enoughParamNumber || !newValueCount) {
          return merged;
        } // Case: newOption: {width: ..., right: ...},
        // Than we can make sure user only want those two, and ignore
        // all origin params in targetOption.
        else if (newValueCount >= enoughParamNumber) {
            return newParams;
          } else {
            // Chose another param from targetOption by priority.
            for (var i = 0; i < names.length; i++) {
              var name_1 = names[i];

              if (!hasProp(newParams, name_1) && hasProp(targetOption, name_1)) {
                newParams[name_1] = targetOption[name_1];
                break;
              }
            }

            return newParams;
          }
      }

      function hasProp(obj, name) {
        return obj.hasOwnProperty(name);
      }

      function hasValue(obj, name) {
        return obj[name] != null && obj[name] !== 'auto';
      }

      function copy(names, target, source) {
        each$1(names, function (name) {
          target[name] = source[name];
        });
      }
    }
    /**
     * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.
     */

    function getLayoutParams(source) {
      return copyLayoutParams({}, source);
    }
    /**
     * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.
     * @param {Object} source
     * @return {Object} Result contains those props.
     */

    function copyLayoutParams(target, source) {
      source && target && each$1(LOCATION_PARAMS, function (name) {
        source.hasOwnProperty(name) && (target[name] = source[name]);
      });
      return target;
    }

    var inner = makeInner();

    var ComponentModel =
    /** @class */
    function (_super) {
      __extends(ComponentModel, _super);

      function ComponentModel(option, parentModel, ecModel) {
        var _this = _super.call(this, option, parentModel, ecModel) || this;

        _this.uid = getUID('ec_cpt_model');
        return _this;
      }

      ComponentModel.prototype.init = function (option, parentModel, ecModel) {
        this.mergeDefaultAndTheme(option, ecModel);
      };

      ComponentModel.prototype.mergeDefaultAndTheme = function (option, ecModel) {
        var layoutMode = fetchLayoutMode(this);
        var inputPositionParams = layoutMode ? getLayoutParams(option) : {};
        var themeModel = ecModel.getTheme();
        merge(option, themeModel.get(this.mainType));
        merge(option, this.getDefaultOption());

        if (layoutMode) {
          mergeLayoutParam(option, inputPositionParams, layoutMode);
        }
      };

      ComponentModel.prototype.mergeOption = function (option, ecModel) {
        merge(this.option, option, true);
        var layoutMode = fetchLayoutMode(this);

        if (layoutMode) {
          mergeLayoutParam(this.option, option, layoutMode);
        }
      };
      /**
       * Called immediately after `init` or `mergeOption` of this instance called.
       */


      ComponentModel.prototype.optionUpdated = function (newCptOption, isInit) {};
      /**
       * [How to declare defaultOption]:
       *
       * (A) If using class declaration in typescript (since echarts 5):
       * ```ts
       * import {ComponentOption} from '../model/option.js';
       * export interface XxxOption extends ComponentOption {
       *     aaa: number
       * }
       * export class XxxModel extends Component {
       *     static type = 'xxx';
       *     static defaultOption: XxxOption = {
       *         aaa: 123
       *     }
       * }
       * Component.registerClass(XxxModel);
       * ```
       * ```ts
       * import {inheritDefaultOption} from '../util/component.js';
       * import {XxxModel, XxxOption} from './XxxModel.js';
       * export interface XxxSubOption extends XxxOption {
       *     bbb: number
       * }
       * class XxxSubModel extends XxxModel {
       *     static defaultOption: XxxSubOption = inheritDefaultOption(XxxModel.defaultOption, {
       *         bbb: 456
       *     })
       *     fn() {
       *         let opt = this.getDefaultOption();
       *         // opt is {aaa: 123, bbb: 456}
       *     }
       * }
       * ```
       *
       * (B) If using class extend (previous approach in echarts 3 & 4):
       * ```js
       * let XxxComponent = Component.extend({
       *     defaultOption: {
       *         xx: 123
       *     }
       * })
       * ```
       * ```js
       * let XxxSubComponent = XxxComponent.extend({
       *     defaultOption: {
       *         yy: 456
       *     },
       *     fn: function () {
       *         let opt = this.getDefaultOption();
       *         // opt is {xx: 123, yy: 456}
       *     }
       * })
       * ```
       */


      ComponentModel.prototype.getDefaultOption = function () {
        var ctor = this.constructor; // If using class declaration, it is different to travel super class
        // in legacy env and auto merge defaultOption. So if using class
        // declaration, defaultOption should be merged manually.

        if (!isExtendedClass(ctor)) {
          // When using ts class, defaultOption must be declared as static.
          return ctor.defaultOption;
        } // FIXME: remove this approach?


        var fields = inner(this);

        if (!fields.defaultOption) {
          var optList = [];
          var clz = ctor;

          while (clz) {
            var opt = clz.prototype.defaultOption;
            opt && optList.push(opt);
            clz = clz.superClass;
          }

          var defaultOption = {};

          for (var i = optList.length - 1; i >= 0; i--) {
            defaultOption = merge(defaultOption, optList[i], true);
          }

          fields.defaultOption = defaultOption;
        }

        return fields.defaultOption;
      };
      /**
       * Notice: always force to input param `useDefault` in case that forget to consider it.
       * The same behavior as `modelUtil.parseFinder`.
       *
       * @param useDefault In many cases like series refer axis and axis refer grid,
       *        If axis index / axis id not specified, use the first target as default.
       *        In other cases like dataZoom refer axis, if not specified, measn no refer.
       */


      ComponentModel.prototype.getReferringComponents = function (mainType, opt) {
        var indexKey = mainType + 'Index';
        var idKey = mainType + 'Id';
        return queryReferringComponents(this.ecModel, mainType, {
          index: this.get(indexKey, true),
          id: this.get(idKey, true)
        }, opt);
      };

      ComponentModel.prototype.getBoxLayoutParams = function () {
        // Consider itself having box layout configs.
        var boxLayoutModel = this;
        return {
          left: boxLayoutModel.get('left'),
          top: boxLayoutModel.get('top'),
          right: boxLayoutModel.get('right'),
          bottom: boxLayoutModel.get('bottom'),
          width: boxLayoutModel.get('width'),
          height: boxLayoutModel.get('height')
        };
      };
      /**
       * Get key for zlevel.
       * If developers don't configure zlevel. We will assign zlevel to series based on the key.
       * For example, lines with trail effect and progressive series will in an individual zlevel.
       */


      ComponentModel.prototype.getZLevelKey = function () {
        return '';
      };

      ComponentModel.prototype.setZLevel = function (zlevel) {
        this.option.zlevel = zlevel;
      };

      ComponentModel.protoInitialize = function () {
        var proto = ComponentModel.prototype;
        proto.type = 'component';
        proto.id = '';
        proto.name = '';
        proto.mainType = '';
        proto.subType = '';
        proto.componentIndex = 0;
      }();

      return ComponentModel;
    }(Model);

    mountExtend(ComponentModel, Model);
    enableClassManagement(ComponentModel);
    enableSubTypeDefaulter(ComponentModel);
    enableTopologicalTravel(ComponentModel, getDependencies);

    function getDependencies(componentType) {
      var deps = [];
      each(ComponentModel.getClassesByMainType(componentType), function (clz) {
        deps = deps.concat(clz.dependencies || clz.prototype.dependencies || []);
      }); // Ensure main type.

      deps = map(deps, function (type) {
        return parseClassType(type).main;
      }); // Hack dataset for convenience.

      if (componentType !== 'dataset' && indexOf(deps, 'dataset') <= 0) {
        deps.unshift('dataset');
      }

      return deps;
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var platform = ''; // Navigator not exists in node

    if (typeof navigator !== 'undefined') {
      /* global navigator */
      platform = navigator.platform || '';
    }

    var decalColor = 'rgba(0, 0, 0, 0.2)';
    var globalDefault = {
      darkMode: 'auto',
      // backgroundColor: 'rgba(0,0,0,0)',
      colorBy: 'series',
      color: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'],
      gradientColor: ['#f6efa6', '#d88273', '#bf444c'],
      aria: {
        decal: {
          decals: [{
            color: decalColor,
            dashArrayX: [1, 0],
            dashArrayY: [2, 5],
            symbolSize: 1,
            rotation: Math.PI / 6
          }, {
            color: decalColor,
            symbol: 'circle',
            dashArrayX: [[8, 8], [0, 8, 8, 0]],
            dashArrayY: [6, 0],
            symbolSize: 0.8
          }, {
            color: decalColor,
            dashArrayX: [1, 0],
            dashArrayY: [4, 3],
            rotation: -Math.PI / 4
          }, {
            color: decalColor,
            dashArrayX: [[6, 6], [0, 6, 6, 0]],
            dashArrayY: [6, 0]
          }, {
            color: decalColor,
            dashArrayX: [[1, 0], [1, 6]],
            dashArrayY: [1, 0, 6, 0],
            rotation: Math.PI / 4
          }, {
            color: decalColor,
            symbol: 'triangle',
            dashArrayX: [[9, 9], [0, 9, 9, 0]],
            dashArrayY: [7, 2],
            symbolSize: 0.75
          }]
        }
      },
      // If xAxis and yAxis declared, grid is created by default.
      // grid: {},
      textStyle: {
        // color: '#000',
        // decoration: 'none',
        // PENDING
        fontFamily: platform.match(/^Win/) ? 'Microsoft YaHei' : 'sans-serif',
        // fontFamily: 'Arial, Verdana, sans-serif',
        fontSize: 12,
        fontStyle: 'normal',
        fontWeight: 'normal'
      },
      // http://blogs.adobe.com/webplatform/2014/02/24/using-blend-modes-in-html-canvas/
      // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
      // Default is source-over
      blendMode: null,
      stateAnimation: {
        duration: 300,
        easing: 'cubicOut'
      },
      animation: 'auto',
      animationDuration: 1000,
      animationDurationUpdate: 500,
      animationEasing: 'cubicInOut',
      animationEasingUpdate: 'cubicInOut',
      animationThreshold: 2000,
      // Configuration for progressive/incremental rendering
      progressiveThreshold: 3000,
      progressive: 400,
      // Threshold of if use single hover layer to optimize.
      // It is recommended that `hoverLayerThreshold` is equivalent to or less than
      // `progressiveThreshold`, otherwise hover will cause restart of progressive,
      // which is unexpected.
      // see example <echarts/test/heatmap-large.html>.
      hoverLayerThreshold: 3000,
      // See: module:echarts/scale/Time
      useUTC: false
    };

    var VISUAL_DIMENSIONS = createHashMap(['tooltip', 'label', 'itemName', 'itemId', 'itemGroupId', 'seriesName']);
    var SOURCE_FORMAT_ORIGINAL = 'original';
    var SOURCE_FORMAT_ARRAY_ROWS = 'arrayRows';
    var SOURCE_FORMAT_OBJECT_ROWS = 'objectRows';
    var SOURCE_FORMAT_KEYED_COLUMNS = 'keyedColumns';
    var SOURCE_FORMAT_TYPED_ARRAY = 'typedArray';
    var SOURCE_FORMAT_UNKNOWN = 'unknown';
    var SERIES_LAYOUT_BY_COLUMN = 'column';
    var SERIES_LAYOUT_BY_ROW = 'row';

    var BE_ORDINAL = {
      Must: 1,
      Might: 2,
      Not: 3 // Other cases

    };
    var innerGlobalModel = makeInner();
    /**
     * MUST be called before mergeOption of all series.
     */

    function resetSourceDefaulter(ecModel) {
      // `datasetMap` is used to make default encode.
      innerGlobalModel(ecModel).datasetMap = createHashMap();
    }
    /**
     * [The strategy of the arrengment of data dimensions for dataset]:
     * "value way": all axes are non-category axes. So series one by one take
     *     several (the number is coordSysDims.length) dimensions from dataset.
     *     The result of data arrengment of data dimensions like:
     *     | ser0_x | ser0_y | ser1_x | ser1_y | ser2_x | ser2_y |
     * "category way": at least one axis is category axis. So the the first data
     *     dimension is always mapped to the first category axis and shared by
     *     all of the series. The other data dimensions are taken by series like
     *     "value way" does.
     *     The result of data arrengment of data dimensions like:
     *     | ser_shared_x | ser0_y | ser1_y | ser2_y |
     *
     * @return encode Never be `null/undefined`.
     */

    function makeSeriesEncodeForAxisCoordSys(coordDimensions, seriesModel, source) {
      var encode = {};
      var datasetModel = querySeriesUpstreamDatasetModel(seriesModel); // Currently only make default when using dataset, util more reqirements occur.

      if (!datasetModel || !coordDimensions) {
        return encode;
      }

      var encodeItemName = [];
      var encodeSeriesName = [];
      var ecModel = seriesModel.ecModel;
      var datasetMap = innerGlobalModel(ecModel).datasetMap;
      var key = datasetModel.uid + '_' + source.seriesLayoutBy;
      var baseCategoryDimIndex;
      var categoryWayValueDimStart;
      coordDimensions = coordDimensions.slice();
      each(coordDimensions, function (coordDimInfoLoose, coordDimIdx) {
        var coordDimInfo = isObject(coordDimInfoLoose) ? coordDimInfoLoose : coordDimensions[coordDimIdx] = {
          name: coordDimInfoLoose
        };

        if (coordDimInfo.type === 'ordinal' && baseCategoryDimIndex == null) {
          baseCategoryDimIndex = coordDimIdx;
          categoryWayValueDimStart = getDataDimCountOnCoordDim(coordDimInfo);
        }

        encode[coordDimInfo.name] = [];
      });
      var datasetRecord = datasetMap.get(key) || datasetMap.set(key, {
        categoryWayDim: categoryWayValueDimStart,
        valueWayDim: 0
      }); // TODO
      // Auto detect first time axis and do arrangement.

      each(coordDimensions, function (coordDimInfo, coordDimIdx) {
        var coordDimName = coordDimInfo.name;
        var count = getDataDimCountOnCoordDim(coordDimInfo); // In value way.

        if (baseCategoryDimIndex == null) {
          var start = datasetRecord.valueWayDim;
          pushDim(encode[coordDimName], start, count);
          pushDim(encodeSeriesName, start, count);
          datasetRecord.valueWayDim += count; // ??? TODO give a better default series name rule?
          // especially when encode x y specified.
          // consider: when multiple series share one dimension
          // category axis, series name should better use
          // the other dimension name. On the other hand, use
          // both dimensions name.
        } // In category way, the first category axis.
        else if (baseCategoryDimIndex === coordDimIdx) {
            pushDim(encode[coordDimName], 0, count);
            pushDim(encodeItemName, 0, count);
          } // In category way, the other axis.
          else {
              var start = datasetRecord.categoryWayDim;
              pushDim(encode[coordDimName], start, count);
              pushDim(encodeSeriesName, start, count);
              datasetRecord.categoryWayDim += count;
            }
      });

      function pushDim(dimIdxArr, idxFrom, idxCount) {
        for (var i = 0; i < idxCount; i++) {
          dimIdxArr.push(idxFrom + i);
        }
      }

      function getDataDimCountOnCoordDim(coordDimInfo) {
        var dimsDef = coordDimInfo.dimsDef;
        return dimsDef ? dimsDef.length : 1;
      }

      encodeItemName.length && (encode.itemName = encodeItemName);
      encodeSeriesName.length && (encode.seriesName = encodeSeriesName);
      return encode;
    }
    /**
     * Work for data like [{name: ..., value: ...}, ...].
     *
     * @return encode Never be `null/undefined`.
     */

    function makeSeriesEncodeForNameBased(seriesModel, source, dimCount) {
      var encode = {};
      var datasetModel = querySeriesUpstreamDatasetModel(seriesModel); // Currently only make default when using dataset, util more reqirements occur.

      if (!datasetModel) {
        return encode;
      }

      var sourceFormat = source.sourceFormat;
      var dimensionsDefine = source.dimensionsDefine;
      var potentialNameDimIndex;

      if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
        each(dimensionsDefine, function (dim, idx) {
          if ((isObject(dim) ? dim.name : dim) === 'name') {
            potentialNameDimIndex = idx;
          }
        });
      }

      var idxResult = function () {
        var idxRes0 = {};
        var idxRes1 = {};
        var guessRecords = []; // 5 is an experience value.

        for (var i = 0, len = Math.min(5, dimCount); i < len; i++) {
          var guessResult = doGuessOrdinal(source.data, sourceFormat, source.seriesLayoutBy, dimensionsDefine, source.startIndex, i);
          guessRecords.push(guessResult);
          var isPureNumber = guessResult === BE_ORDINAL.Not; // [Strategy of idxRes0]: find the first BE_ORDINAL.Not as the value dim,
          // and then find a name dim with the priority:
          // "BE_ORDINAL.Might|BE_ORDINAL.Must" > "other dim" > "the value dim itself".

          if (isPureNumber && idxRes0.v == null && i !== potentialNameDimIndex) {
            idxRes0.v = i;
          }

          if (idxRes0.n == null || idxRes0.n === idxRes0.v || !isPureNumber && guessRecords[idxRes0.n] === BE_ORDINAL.Not) {
            idxRes0.n = i;
          }

          if (fulfilled(idxRes0) && guessRecords[idxRes0.n] !== BE_ORDINAL.Not) {
            return idxRes0;
          } // [Strategy of idxRes1]: if idxRes0 not satisfied (that is, no BE_ORDINAL.Not),
          // find the first BE_ORDINAL.Might as the value dim,
          // and then find a name dim with the priority:
          // "other dim" > "the value dim itself".
          // That is for backward compat: number-like (e.g., `'3'`, `'55'`) can be
          // treated as number.


          if (!isPureNumber) {
            if (guessResult === BE_ORDINAL.Might && idxRes1.v == null && i !== potentialNameDimIndex) {
              idxRes1.v = i;
            }

            if (idxRes1.n == null || idxRes1.n === idxRes1.v) {
              idxRes1.n = i;
            }
          }
        }

        function fulfilled(idxResult) {
          return idxResult.v != null && idxResult.n != null;
        }

        return fulfilled(idxRes0) ? idxRes0 : fulfilled(idxRes1) ? idxRes1 : null;
      }();

      if (idxResult) {
        encode.value = [idxResult.v]; // `potentialNameDimIndex` has highest priority.

        var nameDimIndex = potentialNameDimIndex != null ? potentialNameDimIndex : idxResult.n; // By default, label uses itemName in charts.
        // So we don't set encodeLabel here.

        encode.itemName = [nameDimIndex];
        encode.seriesName = [nameDimIndex];
      }

      return encode;
    }
    /**
     * @return If return null/undefined, indicate that should not use datasetModel.
     */

    function querySeriesUpstreamDatasetModel(seriesModel) {
      // Caution: consider the scenario:
      // A dataset is declared and a series is not expected to use the dataset,
      // and at the beginning `setOption({series: { noData })` (just prepare other
      // option but no data), then `setOption({series: {data: [...]}); In this case,
      // the user should set an empty array to avoid that dataset is used by default.
      var thisData = seriesModel.get('data', true);

      if (!thisData) {
        return queryReferringComponents(seriesModel.ecModel, 'dataset', {
          index: seriesModel.get('datasetIndex', true),
          id: seriesModel.get('datasetId', true)
        }, SINGLE_REFERRING).models[0];
      }
    }
    /**
     * @return Always return an array event empty.
     */

    function queryDatasetUpstreamDatasetModels(datasetModel) {
      // Only these attributes declared, we by defualt reference to `datasetIndex: 0`.
      // Otherwise, no reference.
      if (!datasetModel.get('transform', true) && !datasetModel.get('fromTransformResult', true)) {
        return [];
      }

      return queryReferringComponents(datasetModel.ecModel, 'dataset', {
        index: datasetModel.get('fromDatasetIndex', true),
        id: datasetModel.get('fromDatasetId', true)
      }, SINGLE_REFERRING).models;
    }
    /**
     * The rule should not be complex, otherwise user might not
     * be able to known where the data is wrong.
     * The code is ugly, but how to make it neat?
     */

    function guessOrdinal(source, dimIndex) {
      return doGuessOrdinal(source.data, source.sourceFormat, source.seriesLayoutBy, source.dimensionsDefine, source.startIndex, dimIndex);
    } // dimIndex may be overflow source data.
    // return {BE_ORDINAL}

    function doGuessOrdinal(data, sourceFormat, seriesLayoutBy, dimensionsDefine, startIndex, dimIndex) {
      var result; // Experience value.

      var maxLoop = 5;

      if (isTypedArray(data)) {
        return BE_ORDINAL.Not;
      } // When sourceType is 'objectRows' or 'keyedColumns', dimensionsDefine
      // always exists in source.


      var dimName;
      var dimType;

      if (dimensionsDefine) {
        var dimDefItem = dimensionsDefine[dimIndex];

        if (isObject(dimDefItem)) {
          dimName = dimDefItem.name;
          dimType = dimDefItem.type;
        } else if (isString(dimDefItem)) {
          dimName = dimDefItem;
        }
      }

      if (dimType != null) {
        return dimType === 'ordinal' ? BE_ORDINAL.Must : BE_ORDINAL.Not;
      }

      if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
        var dataArrayRows = data;

        if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) {
          var sample = dataArrayRows[dimIndex];

          for (var i = 0; i < (sample || []).length && i < maxLoop; i++) {
            if ((result = detectValue(sample[startIndex + i])) != null) {
              return result;
            }
          }
        } else {
          for (var i = 0; i < dataArrayRows.length && i < maxLoop; i++) {
            var row = dataArrayRows[startIndex + i];

            if (row && (result = detectValue(row[dimIndex])) != null) {
              return result;
            }
          }
        }
      } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
        var dataObjectRows = data;

        if (!dimName) {
          return BE_ORDINAL.Not;
        }

        for (var i = 0; i < dataObjectRows.length && i < maxLoop; i++) {
          var item = dataObjectRows[i];

          if (item && (result = detectValue(item[dimName])) != null) {
            return result;
          }
        }
      } else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
        var dataKeyedColumns = data;

        if (!dimName) {
          return BE_ORDINAL.Not;
        }

        var sample = dataKeyedColumns[dimName];

        if (!sample || isTypedArray(sample)) {
          return BE_ORDINAL.Not;
        }

        for (var i = 0; i < sample.length && i < maxLoop; i++) {
          if ((result = detectValue(sample[i])) != null) {
            return result;
          }
        }
      } else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        var dataOriginal = data;

        for (var i = 0; i < dataOriginal.length && i < maxLoop; i++) {
          var item = dataOriginal[i];
          var val = getDataItemValue(item);

          if (!isArray(val)) {
            return BE_ORDINAL.Not;
          }

          if ((result = detectValue(val[dimIndex])) != null) {
            return result;
          }
        }
      }

      function detectValue(val) {
        var beStr = isString(val); // Consider usage convenience, '1', '2' will be treated as "number".
        // `isFinit('')` get `true`.

        if (val != null && isFinite(val) && val !== '') {
          return beStr ? BE_ORDINAL.Might : BE_ORDINAL.Not;
        } else if (beStr && val !== '-') {
          return BE_ORDINAL.Must;
        }
      }

      return BE_ORDINAL.Not;
    }

    var internalOptionCreatorMap = createHashMap();
    function registerInternalOptionCreator(mainType, creator) {
      assert(internalOptionCreatorMap.get(mainType) == null && creator);
      internalOptionCreatorMap.set(mainType, creator);
    }
    function concatInternalOptions(ecModel, mainType, newCmptOptionList) {
      var internalOptionCreator = internalOptionCreatorMap.get(mainType);

      if (!internalOptionCreator) {
        return newCmptOptionList;
      }

      var internalOptions = internalOptionCreator(ecModel);

      if (!internalOptions) {
        return newCmptOptionList;
      }

      if ("development" !== 'production') {
        for (var i = 0; i < internalOptions.length; i++) {
          assert(isComponentIdInternal(internalOptions[i]));
        }
      }

      return newCmptOptionList.concat(internalOptions);
    }

    var innerColor = makeInner();
    var innerDecal = makeInner();

    var PaletteMixin =
    /** @class */
    function () {
      function PaletteMixin() {}

      PaletteMixin.prototype.getColorFromPalette = function (name, scope, requestNum) {
        var defaultPalette = normalizeToArray(this.get('color', true));
        var layeredPalette = this.get('colorLayer', true);
        return getFromPalette(this, innerColor, defaultPalette, layeredPalette, name, scope, requestNum);
      };

      PaletteMixin.prototype.clearColorPalette = function () {
        clearPalette(this, innerColor);
      };

      return PaletteMixin;
    }();

    function getDecalFromPalette(ecModel, name, scope, requestNum) {
      var defaultDecals = normalizeToArray(ecModel.get(['aria', 'decal', 'decals']));
      return getFromPalette(ecModel, innerDecal, defaultDecals, null, name, scope, requestNum);
    }

    function getNearestPalette(palettes, requestColorNum) {
      var paletteNum = palettes.length; // TODO palettes must be in order

      for (var i = 0; i < paletteNum; i++) {
        if (palettes[i].length > requestColorNum) {
          return palettes[i];
        }
      }

      return palettes[paletteNum - 1];
    }
    /**
     * @param name MUST NOT be null/undefined. Otherwise call this function
     *             twise with the same parameters will get different result.
     * @param scope default this.
     * @return Can be null/undefined
     */


    function getFromPalette(that, inner, defaultPalette, layeredPalette, name, scope, requestNum) {
      scope = scope || that;
      var scopeFields = inner(scope);
      var paletteIdx = scopeFields.paletteIdx || 0;
      var paletteNameMap = scopeFields.paletteNameMap = scopeFields.paletteNameMap || {}; // Use `hasOwnProperty` to avoid conflict with Object.prototype.

      if (paletteNameMap.hasOwnProperty(name)) {
        return paletteNameMap[name];
      }

      var palette = requestNum == null || !layeredPalette ? defaultPalette : getNearestPalette(layeredPalette, requestNum); // In case can't find in layered color palette.

      palette = palette || defaultPalette;

      if (!palette || !palette.length) {
        return;
      }

      var pickedPaletteItem = palette[paletteIdx];

      if (name) {
        paletteNameMap[name] = pickedPaletteItem;
      }

      scopeFields.paletteIdx = (paletteIdx + 1) % palette.length;
      return pickedPaletteItem;
    }

    function clearPalette(that, inner) {
      inner(that).paletteIdx = 0;
      inner(that).paletteNameMap = {};
    }

    // Internal method names:
    // -----------------------

    var reCreateSeriesIndices;
    var assertSeriesInitialized;
    var initBase;
    var OPTION_INNER_KEY = '\0_ec_inner';
    var OPTION_INNER_VALUE = 1;
    var BUITIN_COMPONENTS_MAP = {
      grid: 'GridComponent',
      polar: 'PolarComponent',
      geo: 'GeoComponent',
      singleAxis: 'SingleAxisComponent',
      parallel: 'ParallelComponent',
      calendar: 'CalendarComponent',
      graphic: 'GraphicComponent',
      toolbox: 'ToolboxComponent',
      tooltip: 'TooltipComponent',
      axisPointer: 'AxisPointerComponent',
      brush: 'BrushComponent',
      title: 'TitleComponent',
      timeline: 'TimelineComponent',
      markPoint: 'MarkPointComponent',
      markLine: 'MarkLineComponent',
      markArea: 'MarkAreaComponent',
      legend: 'LegendComponent',
      dataZoom: 'DataZoomComponent',
      visualMap: 'VisualMapComponent',
      // aria: 'AriaComponent',
      // dataset: 'DatasetComponent',
      // Dependencies
      xAxis: 'GridComponent',
      yAxis: 'GridComponent',
      angleAxis: 'PolarComponent',
      radiusAxis: 'PolarComponent'
    };
    var BUILTIN_CHARTS_MAP = {
      line: 'LineChart',
      bar: 'BarChart',
      pie: 'PieChart',
      scatter: 'ScatterChart',
      radar: 'RadarChart',
      map: 'MapChart',
      tree: 'TreeChart',
      treemap: 'TreemapChart',
      graph: 'GraphChart',
      gauge: 'GaugeChart',
      funnel: 'FunnelChart',
      parallel: 'ParallelChart',
      sankey: 'SankeyChart',
      boxplot: 'BoxplotChart',
      candlestick: 'CandlestickChart',
      effectScatter: 'EffectScatterChart',
      lines: 'LinesChart',
      heatmap: 'HeatmapChart',
      pictorialBar: 'PictorialBarChart',
      themeRiver: 'ThemeRiverChart',
      sunburst: 'SunburstChart',
      custom: 'CustomChart'
    };
    var componetsMissingLogPrinted = {};

    function checkMissingComponents(option) {
      each(option, function (componentOption, mainType) {
        if (!ComponentModel.hasClass(mainType)) {
          var componentImportName = BUITIN_COMPONENTS_MAP[mainType];

          if (componentImportName && !componetsMissingLogPrinted[componentImportName]) {
            error("Component " + mainType + " is used but not imported.\nimport { " + componentImportName + " } from 'echarts/components';\necharts.use([" + componentImportName + "]);");
            componetsMissingLogPrinted[componentImportName] = true;
          }
        }
      });
    }

    var GlobalModel =
    /** @class */
    function (_super) {
      __extends(GlobalModel, _super);

      function GlobalModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      GlobalModel.prototype.init = function (option, parentModel, ecModel, theme, locale, optionManager) {
        theme = theme || {};
        this.option = null; // Mark as not initialized.

        this._theme = new Model(theme);
        this._locale = new Model(locale);
        this._optionManager = optionManager;
      };

      GlobalModel.prototype.setOption = function (option, opts, optionPreprocessorFuncs) {
        if ("development" !== 'production') {
          assert(option != null, 'option is null/undefined');
          assert(option[OPTION_INNER_KEY] !== OPTION_INNER_VALUE, 'please use chart.getOption()');
        }

        var innerOpt = normalizeSetOptionInput(opts);

        this._optionManager.setOption(option, optionPreprocessorFuncs, innerOpt);

        this._resetOption(null, innerOpt);
      };
      /**
       * @param type null/undefined: reset all.
       *        'recreate': force recreate all.
       *        'timeline': only reset timeline option
       *        'media': only reset media query option
       * @return Whether option changed.
       */


      GlobalModel.prototype.resetOption = function (type, opt) {
        return this._resetOption(type, normalizeSetOptionInput(opt));
      };

      GlobalModel.prototype._resetOption = function (type, opt) {
        var optionChanged = false;
        var optionManager = this._optionManager;

        if (!type || type === 'recreate') {
          var baseOption = optionManager.mountOption(type === 'recreate');

          if ("development" !== 'production') {
            checkMissingComponents(baseOption);
          }

          if (!this.option || type === 'recreate') {
            initBase(this, baseOption);
          } else {
            this.restoreData();

            this._mergeOption(baseOption, opt);
          }

          optionChanged = true;
        }

        if (type === 'timeline' || type === 'media') {
          this.restoreData();
        } // By design, if `setOption(option2)` at the second time, and `option2` is a `ECUnitOption`,
        // it should better not have the same props with `MediaUnit['option']`.
        // Because either `option2` or `MediaUnit['option']` will be always merged to "current option"
        // rather than original "baseOption". If they both override a prop, the result might be
        // unexpected when media state changed after `setOption` called.
        // If we really need to modify a props in each `MediaUnit['option']`, use the full version
        // (`{baseOption, media}`) in `setOption`.
        // For `timeline`, the case is the same.


        if (!type || type === 'recreate' || type === 'timeline') {
          var timelineOption = optionManager.getTimelineOption(this);

          if (timelineOption) {
            optionChanged = true;

            this._mergeOption(timelineOption, opt);
          }
        }

        if (!type || type === 'recreate' || type === 'media') {
          var mediaOptions = optionManager.getMediaOption(this);

          if (mediaOptions.length) {
            each(mediaOptions, function (mediaOption) {
              optionChanged = true;

              this._mergeOption(mediaOption, opt);
            }, this);
          }
        }

        return optionChanged;
      };

      GlobalModel.prototype.mergeOption = function (option) {
        this._mergeOption(option, null);
      };

      GlobalModel.prototype._mergeOption = function (newOption, opt) {
        var option = this.option;
        var componentsMap = this._componentsMap;
        var componentsCount = this._componentsCount;
        var newCmptTypes = [];
        var newCmptTypeMap = createHashMap();
        var replaceMergeMainTypeMap = opt && opt.replaceMergeMainTypeMap;
        resetSourceDefaulter(this); // If no component class, merge directly.
        // For example: color, animaiton options, etc.

        each(newOption, function (componentOption, mainType) {
          if (componentOption == null) {
            return;
          }

          if (!ComponentModel.hasClass(mainType)) {
            // globalSettingTask.dirty();
            option[mainType] = option[mainType] == null ? clone(componentOption) : merge(option[mainType], componentOption, true);
          } else if (mainType) {
            newCmptTypes.push(mainType);
            newCmptTypeMap.set(mainType, true);
          }
        });

        if (replaceMergeMainTypeMap) {
          // If there is a mainType `xxx` in `replaceMerge` but not declared in option,
          // we trade it as it is declared in option as `{xxx: []}`. Because:
          // (1) for normal merge, `{xxx: null/undefined}` are the same meaning as `{xxx: []}`.
          // (2) some preprocessor may convert some of `{xxx: null/undefined}` to `{xxx: []}`.
          replaceMergeMainTypeMap.each(function (val, mainTypeInReplaceMerge) {
            if (ComponentModel.hasClass(mainTypeInReplaceMerge) && !newCmptTypeMap.get(mainTypeInReplaceMerge)) {
              newCmptTypes.push(mainTypeInReplaceMerge);
              newCmptTypeMap.set(mainTypeInReplaceMerge, true);
            }
          });
        }

        ComponentModel.topologicalTravel(newCmptTypes, ComponentModel.getAllClassMainTypes(), visitComponent, this);

        function visitComponent(mainType) {
          var newCmptOptionList = concatInternalOptions(this, mainType, normalizeToArray(newOption[mainType]));
          var oldCmptList = componentsMap.get(mainType);
          var mergeMode = // `!oldCmptList` means init. See the comment in `mappingToExists`
          !oldCmptList ? 'replaceAll' : replaceMergeMainTypeMap && replaceMergeMainTypeMap.get(mainType) ? 'replaceMerge' : 'normalMerge';
          var mappingResult = mappingToExists(oldCmptList, newCmptOptionList, mergeMode); // Set mainType and complete subType.

          setComponentTypeToKeyInfo(mappingResult, mainType, ComponentModel); // Empty it before the travel, in order to prevent `this._componentsMap`
          // from being used in the `init`/`mergeOption`/`optionUpdated` of some
          // components, which is probably incorrect logic.

          option[mainType] = null;
          componentsMap.set(mainType, null);
          componentsCount.set(mainType, 0);
          var optionsByMainType = [];
          var cmptsByMainType = [];
          var cmptsCountByMainType = 0;
          var tooltipExists;
          var tooltipWarningLogged;
          each(mappingResult, function (resultItem, index) {
            var componentModel = resultItem.existing;
            var newCmptOption = resultItem.newOption;

            if (!newCmptOption) {
              if (componentModel) {
                // Consider where is no new option and should be merged using {},
                // see removeEdgeAndAdd in topologicalTravel and
                // ComponentModel.getAllClassMainTypes.
                componentModel.mergeOption({}, this);
                componentModel.optionUpdated({}, false);
              } // If no both `resultItem.exist` and `resultItem.option`,
              // either it is in `replaceMerge` and not matched by any id,
              // or it has been removed in previous `replaceMerge` and left a "hole" in this component index.

            } else {
              var isSeriesType = mainType === 'series';
              var ComponentModelClass = ComponentModel.getClass(mainType, resultItem.keyInfo.subType, !isSeriesType // Give a more detailed warn later if series don't exists
              );

              if (!ComponentModelClass) {
                if ("development" !== 'production') {
                  var subType = resultItem.keyInfo.subType;
                  var seriesImportName = BUILTIN_CHARTS_MAP[subType];

                  if (!componetsMissingLogPrinted[subType]) {
                    componetsMissingLogPrinted[subType] = true;

                    if (seriesImportName) {
                      error("Series " + subType + " is used but not imported.\nimport { " + seriesImportName + " } from 'echarts/charts';\necharts.use([" + seriesImportName + "]);");
                    } else {
                      error("Unknown series " + subType);
                    }
                  }
                }

                return;
              } // TODO Before multiple tooltips get supported, we do this check to avoid unexpected exception.


              if (mainType === 'tooltip') {
                if (tooltipExists) {
                  if ("development" !== 'production') {
                    if (!tooltipWarningLogged) {
                      warn('Currently only one tooltip component is allowed.');
                      tooltipWarningLogged = true;
                    }
                  }

                  return;
                }

                tooltipExists = true;
              }

              if (componentModel && componentModel.constructor === ComponentModelClass) {
                componentModel.name = resultItem.keyInfo.name; // componentModel.settingTask && componentModel.settingTask.dirty();

                componentModel.mergeOption(newCmptOption, this);
                componentModel.optionUpdated(newCmptOption, false);
              } else {
                // PENDING Global as parent ?
                var extraOpt = extend({
                  componentIndex: index
                }, resultItem.keyInfo);
                componentModel = new ComponentModelClass(newCmptOption, this, this, extraOpt); // Assign `keyInfo`

                extend(componentModel, extraOpt);

                if (resultItem.brandNew) {
                  componentModel.__requireNewView = true;
                }

                componentModel.init(newCmptOption, this, this); // Call optionUpdated after init.
                // newCmptOption has been used as componentModel.option
                // and may be merged with theme and default, so pass null
                // to avoid confusion.

                componentModel.optionUpdated(null, true);
              }
            }

            if (componentModel) {
              optionsByMainType.push(componentModel.option);
              cmptsByMainType.push(componentModel);
              cmptsCountByMainType++;
            } else {
              // Always do assign to avoid elided item in array.
              optionsByMainType.push(void 0);
              cmptsByMainType.push(void 0);
            }
          }, this);
          option[mainType] = optionsByMainType;
          componentsMap.set(mainType, cmptsByMainType);
          componentsCount.set(mainType, cmptsCountByMainType); // Backup series for filtering.

          if (mainType === 'series') {
            reCreateSeriesIndices(this);
          }
        } // If no series declared, ensure `_seriesIndices` initialized.


        if (!this._seriesIndices) {
          reCreateSeriesIndices(this);
        }
      };
      /**
       * Get option for output (cloned option and inner info removed)
       */


      GlobalModel.prototype.getOption = function () {
        var option = clone(this.option);
        each(option, function (optInMainType, mainType) {
          if (ComponentModel.hasClass(mainType)) {
            var opts = normalizeToArray(optInMainType); // Inner cmpts need to be removed.
            // Inner cmpts might not be at last since ec5.0, but still
            // compatible for users: if inner cmpt at last, splice the returned array.

            var realLen = opts.length;
            var metNonInner = false;

            for (var i = realLen - 1; i >= 0; i--) {
              // Remove options with inner id.
              if (opts[i] && !isComponentIdInternal(opts[i])) {
                metNonInner = true;
              } else {
                opts[i] = null;
                !metNonInner && realLen--;
              }
            }

            opts.length = realLen;
            option[mainType] = opts;
          }
        });
        delete option[OPTION_INNER_KEY];
        return option;
      };

      GlobalModel.prototype.getTheme = function () {
        return this._theme;
      };

      GlobalModel.prototype.getLocaleModel = function () {
        return this._locale;
      };

      GlobalModel.prototype.setUpdatePayload = function (payload) {
        this._payload = payload;
      };

      GlobalModel.prototype.getUpdatePayload = function () {
        return this._payload;
      };
      /**
       * @param idx If not specified, return the first one.
       */


      GlobalModel.prototype.getComponent = function (mainType, idx) {
        var list = this._componentsMap.get(mainType);

        if (list) {
          var cmpt = list[idx || 0];

          if (cmpt) {
            return cmpt;
          } else if (idx == null) {
            for (var i = 0; i < list.length; i++) {
              if (list[i]) {
                return list[i];
              }
            }
          }
        }
      };
      /**
       * @return Never be null/undefined.
       */


      GlobalModel.prototype.queryComponents = function (condition) {
        var mainType = condition.mainType;

        if (!mainType) {
          return [];
        }

        var index = condition.index;
        var id = condition.id;
        var name = condition.name;

        var cmpts = this._componentsMap.get(mainType);

        if (!cmpts || !cmpts.length) {
          return [];
        }

        var result;

        if (index != null) {
          result = [];
          each(normalizeToArray(index), function (idx) {
            cmpts[idx] && result.push(cmpts[idx]);
          });
        } else if (id != null) {
          result = queryByIdOrName('id', id, cmpts);
        } else if (name != null) {
          result = queryByIdOrName('name', name, cmpts);
        } else {
          // Return all non-empty components in that mainType
          result = filter(cmpts, function (cmpt) {
            return !!cmpt;
          });
        }

        return filterBySubType(result, condition);
      };
      /**
       * The interface is different from queryComponents,
       * which is convenient for inner usage.
       *
       * @usage
       * let result = findComponents(
       *     {mainType: 'dataZoom', query: {dataZoomId: 'abc'}}
       * );
       * let result = findComponents(
       *     {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}}
       * );
       * let result = findComponents(
       *     {mainType: 'series',
       *     filter: function (model, index) {...}}
       * );
       * // result like [component0, componnet1, ...]
       */


      GlobalModel.prototype.findComponents = function (condition) {
        var query = condition.query;
        var mainType = condition.mainType;
        var queryCond = getQueryCond(query);
        var result = queryCond ? this.queryComponents(queryCond) // Retrieve all non-empty components.
        : filter(this._componentsMap.get(mainType), function (cmpt) {
          return !!cmpt;
        });
        return doFilter(filterBySubType(result, condition));

        function getQueryCond(q) {
          var indexAttr = mainType + 'Index';
          var idAttr = mainType + 'Id';
          var nameAttr = mainType + 'Name';
          return q && (q[indexAttr] != null || q[idAttr] != null || q[nameAttr] != null) ? {
            mainType: mainType,
            // subType will be filtered finally.
            index: q[indexAttr],
            id: q[idAttr],
            name: q[nameAttr]
          } : null;
        }

        function doFilter(res) {
          return condition.filter ? filter(res, condition.filter) : res;
        }
      };

      GlobalModel.prototype.eachComponent = function (mainType, cb, context) {
        var componentsMap = this._componentsMap;

        if (isFunction(mainType)) {
          var ctxForAll_1 = cb;
          var cbForAll_1 = mainType;
          componentsMap.each(function (cmpts, componentType) {
            for (var i = 0; cmpts && i < cmpts.length; i++) {
              var cmpt = cmpts[i];
              cmpt && cbForAll_1.call(ctxForAll_1, componentType, cmpt, cmpt.componentIndex);
            }
          });
        } else {
          var cmpts = isString(mainType) ? componentsMap.get(mainType) : isObject(mainType) ? this.findComponents(mainType) : null;

          for (var i = 0; cmpts && i < cmpts.length; i++) {
            var cmpt = cmpts[i];
            cmpt && cb.call(context, cmpt, cmpt.componentIndex);
          }
        }
      };
      /**
       * Get series list before filtered by name.
       */


      GlobalModel.prototype.getSeriesByName = function (name) {
        var nameStr = convertOptionIdName(name, null);
        return filter(this._componentsMap.get('series'), function (oneSeries) {
          return !!oneSeries && nameStr != null && oneSeries.name === nameStr;
        });
      };
      /**
       * Get series list before filtered by index.
       */


      GlobalModel.prototype.getSeriesByIndex = function (seriesIndex) {
        return this._componentsMap.get('series')[seriesIndex];
      };
      /**
       * Get series list before filtered by type.
       * FIXME: rename to getRawSeriesByType?
       */


      GlobalModel.prototype.getSeriesByType = function (subType) {
        return filter(this._componentsMap.get('series'), function (oneSeries) {
          return !!oneSeries && oneSeries.subType === subType;
        });
      };
      /**
       * Get all series before filtered.
       */


      GlobalModel.prototype.getSeries = function () {
        return filter(this._componentsMap.get('series'), function (oneSeries) {
          return !!oneSeries;
        });
      };
      /**
       * Count series before filtered.
       */


      GlobalModel.prototype.getSeriesCount = function () {
        return this._componentsCount.get('series');
      };
      /**
       * After filtering, series may be different
       * from raw series.
       */


      GlobalModel.prototype.eachSeries = function (cb, context) {
        assertSeriesInitialized(this);
        each(this._seriesIndices, function (rawSeriesIndex) {
          var series = this._componentsMap.get('series')[rawSeriesIndex];

          cb.call(context, series, rawSeriesIndex);
        }, this);
      };
      /**
       * Iterate raw series before filtered.
       *
       * @param {Function} cb
       * @param {*} context
       */


      GlobalModel.prototype.eachRawSeries = function (cb, context) {
        each(this._componentsMap.get('series'), function (series) {
          series && cb.call(context, series, series.componentIndex);
        });
      };
      /**
       * After filtering, series may be different.
       * from raw series.
       */


      GlobalModel.prototype.eachSeriesByType = function (subType, cb, context) {
        assertSeriesInitialized(this);
        each(this._seriesIndices, function (rawSeriesIndex) {
          var series = this._componentsMap.get('series')[rawSeriesIndex];

          if (series.subType === subType) {
            cb.call(context, series, rawSeriesIndex);
          }
        }, this);
      };
      /**
       * Iterate raw series before filtered of given type.
       */


      GlobalModel.prototype.eachRawSeriesByType = function (subType, cb, context) {
        return each(this.getSeriesByType(subType), cb, context);
      };

      GlobalModel.prototype.isSeriesFiltered = function (seriesModel) {
        assertSeriesInitialized(this);
        return this._seriesIndicesMap.get(seriesModel.componentIndex) == null;
      };

      GlobalModel.prototype.getCurrentSeriesIndices = function () {
        return (this._seriesIndices || []).slice();
      };

      GlobalModel.prototype.filterSeries = function (cb, context) {
        assertSeriesInitialized(this);
        var newSeriesIndices = [];
        each(this._seriesIndices, function (seriesRawIdx) {
          var series = this._componentsMap.get('series')[seriesRawIdx];

          cb.call(context, series, seriesRawIdx) && newSeriesIndices.push(seriesRawIdx);
        }, this);
        this._seriesIndices = newSeriesIndices;
        this._seriesIndicesMap = createHashMap(newSeriesIndices);
      };

      GlobalModel.prototype.restoreData = function (payload) {
        reCreateSeriesIndices(this);
        var componentsMap = this._componentsMap;
        var componentTypes = [];
        componentsMap.each(function (components, componentType) {
          if (ComponentModel.hasClass(componentType)) {
            componentTypes.push(componentType);
          }
        });
        ComponentModel.topologicalTravel(componentTypes, ComponentModel.getAllClassMainTypes(), function (componentType) {
          each(componentsMap.get(componentType), function (component) {
            if (component && (componentType !== 'series' || !isNotTargetSeries(component, payload))) {
              component.restoreData();
            }
          });
        });
      };

      GlobalModel.internalField = function () {
        reCreateSeriesIndices = function (ecModel) {
          var seriesIndices = ecModel._seriesIndices = [];
          each(ecModel._componentsMap.get('series'), function (series) {
            // series may have been removed by `replaceMerge`.
            series && seriesIndices.push(series.componentIndex);
          });
          ecModel._seriesIndicesMap = createHashMap(seriesIndices);
        };

        assertSeriesInitialized = function (ecModel) {
          // Components that use _seriesIndices should depends on series component,
          // which make sure that their initialization is after series.
          if ("development" !== 'production') {
            if (!ecModel._seriesIndices) {
              throw new Error('Option should contains series.');
            }
          }
        };

        initBase = function (ecModel, baseOption) {
          // Using OPTION_INNER_KEY to mark that this option cannot be used outside,
          // i.e. `chart.setOption(chart.getModel().option);` is forbidden.
          ecModel.option = {};
          ecModel.option[OPTION_INNER_KEY] = OPTION_INNER_VALUE; // Init with series: [], in case of calling findSeries method
          // before series initialized.

          ecModel._componentsMap = createHashMap({
            series: []
          });
          ecModel._componentsCount = createHashMap(); // If user spefied `option.aria`, aria will be enable. This detection should be
          // performed before theme and globalDefault merge.

          var airaOption = baseOption.aria;

          if (isObject(airaOption) && airaOption.enabled == null) {
            airaOption.enabled = true;
          }

          mergeTheme(baseOption, ecModel._theme.option); // TODO Needs clone when merging to the unexisted property

          merge(baseOption, globalDefault, false);

          ecModel._mergeOption(baseOption, null);
        };
      }();

      return GlobalModel;
    }(Model);

    function isNotTargetSeries(seriesModel, payload) {
      if (payload) {
        var index = payload.seriesIndex;
        var id = payload.seriesId;
        var name_1 = payload.seriesName;
        return index != null && seriesModel.componentIndex !== index || id != null && seriesModel.id !== id || name_1 != null && seriesModel.name !== name_1;
      }
    }

    function mergeTheme(option, theme) {
      // PENDING
      // NOT use `colorLayer` in theme if option has `color`
      var notMergeColorLayer = option.color && !option.colorLayer;
      each(theme, function (themeItem, name) {
        if (name === 'colorLayer' && notMergeColorLayer) {
          return;
        } // If it is component model mainType, the model handles that merge later.
        // otherwise, merge them here.


        if (!ComponentModel.hasClass(name)) {
          if (typeof themeItem === 'object') {
            option[name] = !option[name] ? clone(themeItem) : merge(option[name], themeItem, false);
          } else {
            if (option[name] == null) {
              option[name] = themeItem;
            }
          }
        }
      });
    }

    function queryByIdOrName(attr, idOrName, cmpts) {
      // Here is a break from echarts4: string and number are
      // treated as equal.
      if (isArray(idOrName)) {
        var keyMap_1 = createHashMap();
        each(idOrName, function (idOrNameItem) {
          if (idOrNameItem != null) {
            var idName = convertOptionIdName(idOrNameItem, null);
            idName != null && keyMap_1.set(idOrNameItem, true);
          }
        });
        return filter(cmpts, function (cmpt) {
          return cmpt && keyMap_1.get(cmpt[attr]);
        });
      } else {
        var idName_1 = convertOptionIdName(idOrName, null);
        return filter(cmpts, function (cmpt) {
          return cmpt && idName_1 != null && cmpt[attr] === idName_1;
        });
      }
    }

    function filterBySubType(components, condition) {
      // Using hasOwnProperty for restrict. Consider
      // subType is undefined in user payload.
      return condition.hasOwnProperty('subType') ? filter(components, function (cmpt) {
        return cmpt && cmpt.subType === condition.subType;
      }) : components;
    }

    function normalizeSetOptionInput(opts) {
      var replaceMergeMainTypeMap = createHashMap();
      opts && each(normalizeToArray(opts.replaceMerge), function (mainType) {
        if ("development" !== 'production') {
          assert(ComponentModel.hasClass(mainType), '"' + mainType + '" is not valid component main type in "replaceMerge"');
        }

        replaceMergeMainTypeMap.set(mainType, true);
      });
      return {
        replaceMergeMainTypeMap: replaceMergeMainTypeMap
      };
    }

    mixin(GlobalModel, PaletteMixin);

    var availableMethods = ['getDom', 'getZr', 'getWidth', 'getHeight', 'getDevicePixelRatio', 'dispatchAction', 'isSSR', 'isDisposed', 'on', 'off', 'getDataURL', 'getConnectedDataURL', // 'getModel',
    'getOption', // 'getViewOfComponentModel',
    // 'getViewOfSeriesModel',
    'getId', 'updateLabelLayout'];

    var ExtensionAPI =
    /** @class */
    function () {
      function ExtensionAPI(ecInstance) {
        each(availableMethods, function (methodName) {
          this[methodName] = bind(ecInstance[methodName], ecInstance);
        }, this);
      }

      return ExtensionAPI;
    }();

    var coordinateSystemCreators = {};

    var CoordinateSystemManager =
    /** @class */
    function () {
      function CoordinateSystemManager() {
        this._coordinateSystems = [];
      }

      CoordinateSystemManager.prototype.create = function (ecModel, api) {
        var coordinateSystems = [];
        each(coordinateSystemCreators, function (creator, type) {
          var list = creator.create(ecModel, api);
          coordinateSystems = coordinateSystems.concat(list || []);
        });
        this._coordinateSystems = coordinateSystems;
      };

      CoordinateSystemManager.prototype.update = function (ecModel, api) {
        each(this._coordinateSystems, function (coordSys) {
          coordSys.update && coordSys.update(ecModel, api);
        });
      };

      CoordinateSystemManager.prototype.getCoordinateSystems = function () {
        return this._coordinateSystems.slice();
      };

      CoordinateSystemManager.register = function (type, creator) {
        coordinateSystemCreators[type] = creator;
      };

      CoordinateSystemManager.get = function (type) {
        return coordinateSystemCreators[type];
      };

      return CoordinateSystemManager;
    }();

    var QUERY_REG = /^(min|max)?(.+)$/; // Key: mainType
    // type FakeComponentsMap = HashMap<(MappingExistingItem & { subType: string })[]>;

    /**
     * TERM EXPLANATIONS:
     * See `ECOption` and `ECUnitOption` in `src/util/types.ts`.
     */

    var OptionManager =
    /** @class */
    function () {
      // timeline.notMerge is not supported in ec3. Firstly there is rearly
      // case that notMerge is needed. Secondly supporting 'notMerge' requires
      // rawOption cloned and backuped when timeline changed, which does no
      // good to performance. What's more, that both timeline and setOption
      // method supply 'notMerge' brings complex and some problems.
      // Consider this case:
      // (step1) chart.setOption({timeline: {notMerge: false}, ...}, false);
      // (step2) chart.setOption({timeline: {notMerge: true}, ...}, false);
      function OptionManager(api) {
        this._timelineOptions = [];
        this._mediaList = [];
        /**
         * -1, means default.
         * empty means no media.
         */

        this._currentMediaIndices = [];
        this._api = api;
      }

      OptionManager.prototype.setOption = function (rawOption, optionPreprocessorFuncs, opt) {
        if (rawOption) {
          // That set dat primitive is dangerous if user reuse the data when setOption again.
          each(normalizeToArray(rawOption.series), function (series) {
            series && series.data && isTypedArray(series.data) && setAsPrimitive(series.data);
          });
          each(normalizeToArray(rawOption.dataset), function (dataset) {
            dataset && dataset.source && isTypedArray(dataset.source) && setAsPrimitive(dataset.source);
          });
        } // Caution: some series modify option data, if do not clone,
        // it should ensure that the repeat modify correctly
        // (create a new object when modify itself).


        rawOption = clone(rawOption); // FIXME
        // If some property is set in timeline options or media option but
        // not set in baseOption, a warning should be given.

        var optionBackup = this._optionBackup;
        var newParsedOption = parseRawOption(rawOption, optionPreprocessorFuncs, !optionBackup);
        this._newBaseOption = newParsedOption.baseOption; // For setOption at second time (using merge mode);

        if (optionBackup) {
          // FIXME
          // the restore merge solution is essentially incorrect.
          // the mapping can not be 100% consistent with ecModel, which probably brings
          // potential bug!
          // The first merge is delayed, because in most cases, users do not call `setOption` twice.
          // let fakeCmptsMap = this._fakeCmptsMap;
          // if (!fakeCmptsMap) {
          //     fakeCmptsMap = this._fakeCmptsMap = createHashMap();
          //     mergeToBackupOption(fakeCmptsMap, null, optionBackup.baseOption, null);
          // }
          // mergeToBackupOption(
          //     fakeCmptsMap, optionBackup.baseOption, newParsedOption.baseOption, opt
          // );
          // For simplicity, timeline options and media options do not support merge,
          // that is, if you `setOption` twice and both has timeline options, the latter
          // timeline options will not be merged to the former, but just substitute them.
          if (newParsedOption.timelineOptions.length) {
            optionBackup.timelineOptions = newParsedOption.timelineOptions;
          }

          if (newParsedOption.mediaList.length) {
            optionBackup.mediaList = newParsedOption.mediaList;
          }

          if (newParsedOption.mediaDefault) {
            optionBackup.mediaDefault = newParsedOption.mediaDefault;
          }
        } else {
          this._optionBackup = newParsedOption;
        }
      };

      OptionManager.prototype.mountOption = function (isRecreate) {
        var optionBackup = this._optionBackup;
        this._timelineOptions = optionBackup.timelineOptions;
        this._mediaList = optionBackup.mediaList;
        this._mediaDefault = optionBackup.mediaDefault;
        this._currentMediaIndices = [];
        return clone(isRecreate // this._optionBackup.baseOption, which is created at the first `setOption`
        // called, and is merged into every new option by inner method `mergeToBackupOption`
        // each time `setOption` called, can be only used in `isRecreate`, because
        // its reliability is under suspicion. In other cases option merge is
        // performed by `model.mergeOption`.
        ? optionBackup.baseOption : this._newBaseOption);
      };

      OptionManager.prototype.getTimelineOption = function (ecModel) {
        var option;
        var timelineOptions = this._timelineOptions;

        if (timelineOptions.length) {
          // getTimelineOption can only be called after ecModel inited,
          // so we can get currentIndex from timelineModel.
          var timelineModel = ecModel.getComponent('timeline');

          if (timelineModel) {
            option = clone( // FIXME:TS as TimelineModel or quivlant interface
            timelineOptions[timelineModel.getCurrentIndex()]);
          }
        }

        return option;
      };

      OptionManager.prototype.getMediaOption = function (ecModel) {
        var ecWidth = this._api.getWidth();

        var ecHeight = this._api.getHeight();

        var mediaList = this._mediaList;
        var mediaDefault = this._mediaDefault;
        var indices = [];
        var result = []; // No media defined.

        if (!mediaList.length && !mediaDefault) {
          return result;
        } // Multi media may be applied, the latter defined media has higher priority.


        for (var i = 0, len = mediaList.length; i < len; i++) {
          if (applyMediaQuery(mediaList[i].query, ecWidth, ecHeight)) {
            indices.push(i);
          }
        } // FIXME
        // Whether mediaDefault should force users to provide? Otherwise
        // the change by media query can not be recorvered.


        if (!indices.length && mediaDefault) {
          indices = [-1];
        }

        if (indices.length && !indicesEquals(indices, this._currentMediaIndices)) {
          result = map(indices, function (index) {
            return clone(index === -1 ? mediaDefault.option : mediaList[index].option);
          });
        } // Otherwise return nothing.


        this._currentMediaIndices = indices;
        return result;
      };

      return OptionManager;
    }();
    /**
     * [RAW_OPTION_PATTERNS]
     * (Note: "series: []" represents all other props in `ECUnitOption`)
     *
     * (1) No prop "baseOption" declared:
     * Root option is used as "baseOption" (except prop "options" and "media").
     * ```js
     * option = {
     *     series: [],
     *     timeline: {},
     *     options: [],
     * };
     * option = {
     *     series: [],
     *     media: {},
     * };
     * option = {
     *     series: [],
     *     timeline: {},
     *     options: [],
     *     media: {},
     * }
     * ```
     *
     * (2) Prop "baseOption" declared:
     * If "baseOption" declared, `ECUnitOption` props can only be declared
     * inside "baseOption" except prop "timeline" (compat ec2).
     * ```js
     * option = {
     *     baseOption: {
     *         timeline: {},
     *         series: [],
     *     },
     *     options: []
     * };
     * option = {
     *     baseOption: {
     *         series: [],
     *     },
     *     media: []
     * };
     * option = {
     *     baseOption: {
     *         timeline: {},
     *         series: [],
     *     },
     *     options: []
     *     media: []
     * };
     * option = {
     *     // ec3 compat ec2: allow (only) `timeline` declared
     *     // outside baseOption. Keep this setting for compat.
     *     timeline: {},
     *     baseOption: {
     *         series: [],
     *     },
     *     options: [],
     *     media: []
     * };
     * ```
     */


    function parseRawOption( // `rawOption` May be modified
    rawOption, optionPreprocessorFuncs, isNew) {
      var mediaList = [];
      var mediaDefault;
      var baseOption;
      var declaredBaseOption = rawOption.baseOption; // Compatible with ec2, [RAW_OPTION_PATTERNS] above.

      var timelineOnRoot = rawOption.timeline;
      var timelineOptionsOnRoot = rawOption.options;
      var mediaOnRoot = rawOption.media;
      var hasMedia = !!rawOption.media;
      var hasTimeline = !!(timelineOptionsOnRoot || timelineOnRoot || declaredBaseOption && declaredBaseOption.timeline);

      if (declaredBaseOption) {
        baseOption = declaredBaseOption; // For merge option.

        if (!baseOption.timeline) {
          baseOption.timeline = timelineOnRoot;
        }
      } // For convenience, enable to use the root option as the `baseOption`:
      // `{ ...normalOptionProps, media: [{ ... }, { ... }] }`
      else {
          if (hasTimeline || hasMedia) {
            rawOption.options = rawOption.media = null;
          }

          baseOption = rawOption;
        }

      if (hasMedia) {
        if (isArray(mediaOnRoot)) {
          each(mediaOnRoot, function (singleMedia) {
            if ("development" !== 'production') {
              // Real case of wrong config.
              if (singleMedia && !singleMedia.option && isObject(singleMedia.query) && isObject(singleMedia.query.option)) {
                error('Illegal media option. Must be like { media: [ { query: {}, option: {} } ] }');
              }
            }

            if (singleMedia && singleMedia.option) {
              if (singleMedia.query) {
                mediaList.push(singleMedia);
              } else if (!mediaDefault) {
                // Use the first media default.
                mediaDefault = singleMedia;
              }
            }
          });
        } else {
          if ("development" !== 'production') {
            // Real case of wrong config.
            error('Illegal media option. Must be an array. Like { media: [ {...}, {...} ] }');
          }
        }
      }

      doPreprocess(baseOption);
      each(timelineOptionsOnRoot, function (option) {
        return doPreprocess(option);
      });
      each(mediaList, function (media) {
        return doPreprocess(media.option);
      });

      function doPreprocess(option) {
        each(optionPreprocessorFuncs, function (preProcess) {
          preProcess(option, isNew);
        });
      }

      return {
        baseOption: baseOption,
        timelineOptions: timelineOptionsOnRoot || [],
        mediaDefault: mediaDefault,
        mediaList: mediaList
      };
    }
    /**
     * @see <http://www.w3.org/TR/css3-mediaqueries/#media1>
     * Support: width, height, aspectRatio
     * Can use max or min as prefix.
     */


    function applyMediaQuery(query, ecWidth, ecHeight) {
      var realMap = {
        width: ecWidth,
        height: ecHeight,
        aspectratio: ecWidth / ecHeight // lower case for convenience.

      };
      var applicable = true;
      each(query, function (value, attr) {
        var matched = attr.match(QUERY_REG);

        if (!matched || !matched[1] || !matched[2]) {
          return;
        }

        var operator = matched[1];
        var realAttr = matched[2].toLowerCase();

        if (!compare(realMap[realAttr], value, operator)) {
          applicable = false;
        }
      });
      return applicable;
    }

    function compare(real, expect, operator) {
      if (operator === 'min') {
        return real >= expect;
      } else if (operator === 'max') {
        return real <= expect;
      } else {
        // Equals
        return real === expect;
      }
    }

    function indicesEquals(indices1, indices2) {
      // indices is always order by asc and has only finite number.
      return indices1.join(',') === indices2.join(',');
    }

    var each$2 = each;
    var isObject$1 = isObject;
    var POSSIBLE_STYLES = ['areaStyle', 'lineStyle', 'nodeStyle', 'linkStyle', 'chordStyle', 'label', 'labelLine'];

    function compatEC2ItemStyle(opt) {
      var itemStyleOpt = opt && opt.itemStyle;

      if (!itemStyleOpt) {
        return;
      }

      for (var i = 0, len = POSSIBLE_STYLES.length; i < len; i++) {
        var styleName = POSSIBLE_STYLES[i];
        var normalItemStyleOpt = itemStyleOpt.normal;
        var emphasisItemStyleOpt = itemStyleOpt.emphasis;

        if (normalItemStyleOpt && normalItemStyleOpt[styleName]) {
          if ("development" !== 'production') {
            deprecateReplaceLog("itemStyle.normal." + styleName, styleName);
          }

          opt[styleName] = opt[styleName] || {};

          if (!opt[styleName].normal) {
            opt[styleName].normal = normalItemStyleOpt[styleName];
          } else {
            merge(opt[styleName].normal, normalItemStyleOpt[styleName]);
          }

          normalItemStyleOpt[styleName] = null;
        }

        if (emphasisItemStyleOpt && emphasisItemStyleOpt[styleName]) {
          if ("development" !== 'production') {
            deprecateReplaceLog("itemStyle.emphasis." + styleName, "emphasis." + styleName);
          }

          opt[styleName] = opt[styleName] || {};

          if (!opt[styleName].emphasis) {
            opt[styleName].emphasis = emphasisItemStyleOpt[styleName];
          } else {
            merge(opt[styleName].emphasis, emphasisItemStyleOpt[styleName]);
          }

          emphasisItemStyleOpt[styleName] = null;
        }
      }
    }

    function convertNormalEmphasis(opt, optType, useExtend) {
      if (opt && opt[optType] && (opt[optType].normal || opt[optType].emphasis)) {
        var normalOpt = opt[optType].normal;
        var emphasisOpt = opt[optType].emphasis;

        if (normalOpt) {
          if ("development" !== 'production') {
            // eslint-disable-next-line max-len
            deprecateLog("'normal' hierarchy in " + optType + " has been removed since 4.0. All style properties are configured in " + optType + " directly now.");
          } // Timeline controlStyle has other properties besides normal and emphasis


          if (useExtend) {
            opt[optType].normal = opt[optType].emphasis = null;
            defaults(opt[optType], normalOpt);
          } else {
            opt[optType] = normalOpt;
          }
        }

        if (emphasisOpt) {
          if ("development" !== 'production') {
            deprecateLog(optType + ".emphasis has been changed to emphasis." + optType + " since 4.0");
          }

          opt.emphasis = opt.emphasis || {};
          opt.emphasis[optType] = emphasisOpt; // Also compat the case user mix the style and focus together in ec3 style
          // for example: { itemStyle: { normal: {}, emphasis: {focus, shadowBlur} } }

          if (emphasisOpt.focus) {
            opt.emphasis.focus = emphasisOpt.focus;
          }

          if (emphasisOpt.blurScope) {
            opt.emphasis.blurScope = emphasisOpt.blurScope;
          }
        }
      }
    }

    function removeEC3NormalStatus(opt) {
      convertNormalEmphasis(opt, 'itemStyle');
      convertNormalEmphasis(opt, 'lineStyle');
      convertNormalEmphasis(opt, 'areaStyle');
      convertNormalEmphasis(opt, 'label');
      convertNormalEmphasis(opt, 'labelLine'); // treemap

      convertNormalEmphasis(opt, 'upperLabel'); // graph

      convertNormalEmphasis(opt, 'edgeLabel');
    }

    function compatTextStyle(opt, propName) {
      // Check whether is not object (string\null\undefined ...)
      var labelOptSingle = isObject$1(opt) && opt[propName];
      var textStyle = isObject$1(labelOptSingle) && labelOptSingle.textStyle;

      if (textStyle) {
        if ("development" !== 'production') {
          // eslint-disable-next-line max-len
          deprecateLog("textStyle hierarchy in " + propName + " has been removed since 4.0. All textStyle properties are configured in " + propName + " directly now.");
        }

        for (var i = 0, len = TEXT_STYLE_OPTIONS.length; i < len; i++) {
          var textPropName = TEXT_STYLE_OPTIONS[i];

          if (textStyle.hasOwnProperty(textPropName)) {
            labelOptSingle[textPropName] = textStyle[textPropName];
          }
        }
      }
    }

    function compatEC3CommonStyles(opt) {
      if (opt) {
        removeEC3NormalStatus(opt);
        compatTextStyle(opt, 'label');
        opt.emphasis && compatTextStyle(opt.emphasis, 'label');
      }
    }

    function processSeries(seriesOpt) {
      if (!isObject$1(seriesOpt)) {
        return;
      }

      compatEC2ItemStyle(seriesOpt);
      removeEC3NormalStatus(seriesOpt);
      compatTextStyle(seriesOpt, 'label'); // treemap

      compatTextStyle(seriesOpt, 'upperLabel'); // graph

      compatTextStyle(seriesOpt, 'edgeLabel');

      if (seriesOpt.emphasis) {
        compatTextStyle(seriesOpt.emphasis, 'label'); // treemap

        compatTextStyle(seriesOpt.emphasis, 'upperLabel'); // graph

        compatTextStyle(seriesOpt.emphasis, 'edgeLabel');
      }

      var markPoint = seriesOpt.markPoint;

      if (markPoint) {
        compatEC2ItemStyle(markPoint);
        compatEC3CommonStyles(markPoint);
      }

      var markLine = seriesOpt.markLine;

      if (markLine) {
        compatEC2ItemStyle(markLine);
        compatEC3CommonStyles(markLine);
      }

      var markArea = seriesOpt.markArea;

      if (markArea) {
        compatEC3CommonStyles(markArea);
      }

      var data = seriesOpt.data; // Break with ec3: if `setOption` again, there may be no `type` in option,
      // then the backward compat based on option type will not be performed.

      if (seriesOpt.type === 'graph') {
        data = data || seriesOpt.nodes;
        var edgeData = seriesOpt.links || seriesOpt.edges;

        if (edgeData && !isTypedArray(edgeData)) {
          for (var i = 0; i < edgeData.length; i++) {
            compatEC3CommonStyles(edgeData[i]);
          }
        }

        each(seriesOpt.categories, function (opt) {
          removeEC3NormalStatus(opt);
        });
      }

      if (data && !isTypedArray(data)) {
        for (var i = 0; i < data.length; i++) {
          compatEC3CommonStyles(data[i]);
        }
      } // mark point data


      markPoint = seriesOpt.markPoint;

      if (markPoint && markPoint.data) {
        var mpData = markPoint.data;

        for (var i = 0; i < mpData.length; i++) {
          compatEC3CommonStyles(mpData[i]);
        }
      } // mark line data


      markLine = seriesOpt.markLine;

      if (markLine && markLine.data) {
        var mlData = markLine.data;

        for (var i = 0; i < mlData.length; i++) {
          if (isArray(mlData[i])) {
            compatEC3CommonStyles(mlData[i][0]);
            compatEC3CommonStyles(mlData[i][1]);
          } else {
            compatEC3CommonStyles(mlData[i]);
          }
        }
      } // Series


      if (seriesOpt.type === 'gauge') {
        compatTextStyle(seriesOpt, 'axisLabel');
        compatTextStyle(seriesOpt, 'title');
        compatTextStyle(seriesOpt, 'detail');
      } else if (seriesOpt.type === 'treemap') {
        convertNormalEmphasis(seriesOpt.breadcrumb, 'itemStyle');
        each(seriesOpt.levels, function (opt) {
          removeEC3NormalStatus(opt);
        });
      } else if (seriesOpt.type === 'tree') {
        removeEC3NormalStatus(seriesOpt.leaves);
      } // sunburst starts from ec4, so it does not need to compat levels.

    }

    function toArr(o) {
      return isArray(o) ? o : o ? [o] : [];
    }

    function toObj(o) {
      return (isArray(o) ? o[0] : o) || {};
    }

    function globalCompatStyle(option, isTheme) {
      each$2(toArr(option.series), function (seriesOpt) {
        isObject$1(seriesOpt) && processSeries(seriesOpt);
      });
      var axes = ['xAxis', 'yAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'parallelAxis', 'radar'];
      isTheme && axes.push('valueAxis', 'categoryAxis', 'logAxis', 'timeAxis');
      each$2(axes, function (axisName) {
        each$2(toArr(option[axisName]), function (axisOpt) {
          if (axisOpt) {
            compatTextStyle(axisOpt, 'axisLabel');
            compatTextStyle(axisOpt.axisPointer, 'label');
          }
        });
      });
      each$2(toArr(option.parallel), function (parallelOpt) {
        var parallelAxisDefault = parallelOpt && parallelOpt.parallelAxisDefault;
        compatTextStyle(parallelAxisDefault, 'axisLabel');
        compatTextStyle(parallelAxisDefault && parallelAxisDefault.axisPointer, 'label');
      });
      each$2(toArr(option.calendar), function (calendarOpt) {
        convertNormalEmphasis(calendarOpt, 'itemStyle');
        compatTextStyle(calendarOpt, 'dayLabel');
        compatTextStyle(calendarOpt, 'monthLabel');
        compatTextStyle(calendarOpt, 'yearLabel');
      }); // radar.name.textStyle

      each$2(toArr(option.radar), function (radarOpt) {
        compatTextStyle(radarOpt, 'name'); // Use axisName instead of name because component has name property

        if (radarOpt.name && radarOpt.axisName == null) {
          radarOpt.axisName = radarOpt.name;
          delete radarOpt.name;

          if ("development" !== 'production') {
            deprecateLog('name property in radar component has been changed to axisName');
          }
        }

        if (radarOpt.nameGap != null && radarOpt.axisNameGap == null) {
          radarOpt.axisNameGap = radarOpt.nameGap;
          delete radarOpt.nameGap;

          if ("development" !== 'production') {
            deprecateLog('nameGap property in radar component has been changed to axisNameGap');
          }
        }

        if ("development" !== 'production') {
          each$2(radarOpt.indicator, function (indicatorOpt) {
            if (indicatorOpt.text) {
              deprecateReplaceLog('text', 'name', 'radar.indicator');
            }
          });
        }
      });
      each$2(toArr(option.geo), function (geoOpt) {
        if (isObject$1(geoOpt)) {
          compatEC3CommonStyles(geoOpt);
          each$2(toArr(geoOpt.regions), function (regionObj) {
            compatEC3CommonStyles(regionObj);
          });
        }
      });
      each$2(toArr(option.timeline), function (timelineOpt) {
        compatEC3CommonStyles(timelineOpt);
        convertNormalEmphasis(timelineOpt, 'label');
        convertNormalEmphasis(timelineOpt, 'itemStyle');
        convertNormalEmphasis(timelineOpt, 'controlStyle', true);
        var data = timelineOpt.data;
        isArray(data) && each(data, function (item) {
          if (isObject(item)) {
            convertNormalEmphasis(item, 'label');
            convertNormalEmphasis(item, 'itemStyle');
          }
        });
      });
      each$2(toArr(option.toolbox), function (toolboxOpt) {
        convertNormalEmphasis(toolboxOpt, 'iconStyle');
        each$2(toolboxOpt.feature, function (featureOpt) {
          convertNormalEmphasis(featureOpt, 'iconStyle');
        });
      });
      compatTextStyle(toObj(option.axisPointer), 'label');
      compatTextStyle(toObj(option.tooltip).axisPointer, 'label'); // Clean logs
      // storedLogs = {};
    }

    function get(opt, path) {
      var pathArr = path.split(',');
      var obj = opt;

      for (var i = 0; i < pathArr.length; i++) {
        obj = obj && obj[pathArr[i]];

        if (obj == null) {
          break;
        }
      }

      return obj;
    }

    function set$1(opt, path, val, overwrite) {
      var pathArr = path.split(',');
      var obj = opt;
      var key;
      var i = 0;

      for (; i < pathArr.length - 1; i++) {
        key = pathArr[i];

        if (obj[key] == null) {
          obj[key] = {};
        }

        obj = obj[key];
      }

      if (overwrite || obj[pathArr[i]] == null) {
        obj[pathArr[i]] = val;
      }
    }

    function compatLayoutProperties(option) {
      option && each(LAYOUT_PROPERTIES, function (prop) {
        if (prop[0] in option && !(prop[1] in option)) {
          option[prop[1]] = option[prop[0]];
        }
      });
    }

    var LAYOUT_PROPERTIES = [['x', 'left'], ['y', 'top'], ['x2', 'right'], ['y2', 'bottom']];
    var COMPATITABLE_COMPONENTS = ['grid', 'geo', 'parallel', 'legend', 'toolbox', 'title', 'visualMap', 'dataZoom', 'timeline'];
    var BAR_ITEM_STYLE_MAP = [['borderRadius', 'barBorderRadius'], ['borderColor', 'barBorderColor'], ['borderWidth', 'barBorderWidth']];

    function compatBarItemStyle(option) {
      var itemStyle = option && option.itemStyle;

      if (itemStyle) {
        for (var i = 0; i < BAR_ITEM_STYLE_MAP.length; i++) {
          var oldName = BAR_ITEM_STYLE_MAP[i][1];
          var newName = BAR_ITEM_STYLE_MAP[i][0];

          if (itemStyle[oldName] != null) {
            itemStyle[newName] = itemStyle[oldName];

            if ("development" !== 'production') {
              deprecateReplaceLog(oldName, newName);
            }
          }
        }
      }
    }

    function compatPieLabel(option) {
      if (!option) {
        return;
      }

      if (option.alignTo === 'edge' && option.margin != null && option.edgeDistance == null) {
        if ("development" !== 'production') {
          deprecateReplaceLog('label.margin', 'label.edgeDistance', 'pie');
        }

        option.edgeDistance = option.margin;
      }
    }

    function compatSunburstState(option) {
      if (!option) {
        return;
      }

      if (option.downplay && !option.blur) {
        option.blur = option.downplay;

        if ("development" !== 'production') {
          deprecateReplaceLog('downplay', 'blur', 'sunburst');
        }
      }
    }

    function compatGraphFocus(option) {
      if (!option) {
        return;
      }

      if (option.focusNodeAdjacency != null) {
        option.emphasis = option.emphasis || {};

        if (option.emphasis.focus == null) {
          if ("development" !== 'production') {
            deprecateReplaceLog('focusNodeAdjacency', 'emphasis: { focus: \'adjacency\'}', 'graph/sankey');
          }

          option.emphasis.focus = 'adjacency';
        }
      }
    }

    function traverseTree(data, cb) {
      if (data) {
        for (var i = 0; i < data.length; i++) {
          cb(data[i]);
          data[i] && traverseTree(data[i].children, cb);
        }
      }
    }

    function globalBackwardCompat(option, isTheme) {
      globalCompatStyle(option, isTheme); // Make sure series array for model initialization.

      option.series = normalizeToArray(option.series);
      each(option.series, function (seriesOpt) {
        if (!isObject(seriesOpt)) {
          return;
        }

        var seriesType = seriesOpt.type;

        if (seriesType === 'line') {
          if (seriesOpt.clipOverflow != null) {
            seriesOpt.clip = seriesOpt.clipOverflow;

            if ("development" !== 'production') {
              deprecateReplaceLog('clipOverflow', 'clip', 'line');
            }
          }
        } else if (seriesType === 'pie' || seriesType === 'gauge') {
          if (seriesOpt.clockWise != null) {
            seriesOpt.clockwise = seriesOpt.clockWise;

            if ("development" !== 'production') {
              deprecateReplaceLog('clockWise', 'clockwise');
            }
          }

          compatPieLabel(seriesOpt.label);
          var data = seriesOpt.data;

          if (data && !isTypedArray(data)) {
            for (var i = 0; i < data.length; i++) {
              compatPieLabel(data[i]);
            }
          }

          if (seriesOpt.hoverOffset != null) {
            seriesOpt.emphasis = seriesOpt.emphasis || {};

            if (seriesOpt.emphasis.scaleSize = null) {
              if ("development" !== 'production') {
                deprecateReplaceLog('hoverOffset', 'emphasis.scaleSize');
              }

              seriesOpt.emphasis.scaleSize = seriesOpt.hoverOffset;
            }
          }
        } else if (seriesType === 'gauge') {
          var pointerColor = get(seriesOpt, 'pointer.color');
          pointerColor != null && set$1(seriesOpt, 'itemStyle.color', pointerColor);
        } else if (seriesType === 'bar') {
          compatBarItemStyle(seriesOpt);
          compatBarItemStyle(seriesOpt.backgroundStyle);
          compatBarItemStyle(seriesOpt.emphasis);
          var data = seriesOpt.data;

          if (data && !isTypedArray(data)) {
            for (var i = 0; i < data.length; i++) {
              if (typeof data[i] === 'object') {
                compatBarItemStyle(data[i]);
                compatBarItemStyle(data[i] && data[i].emphasis);
              }
            }
          }
        } else if (seriesType === 'sunburst') {
          var highlightPolicy = seriesOpt.highlightPolicy;

          if (highlightPolicy) {
            seriesOpt.emphasis = seriesOpt.emphasis || {};

            if (!seriesOpt.emphasis.focus) {
              seriesOpt.emphasis.focus = highlightPolicy;

              if ("development" !== 'production') {
                deprecateReplaceLog('highlightPolicy', 'emphasis.focus', 'sunburst');
              }
            }
          }

          compatSunburstState(seriesOpt);
          traverseTree(seriesOpt.data, compatSunburstState);
        } else if (seriesType === 'graph' || seriesType === 'sankey') {
          compatGraphFocus(seriesOpt); // TODO nodes, edges?
        } else if (seriesType === 'map') {
          if (seriesOpt.mapType && !seriesOpt.map) {
            if ("development" !== 'production') {
              deprecateReplaceLog('mapType', 'map', 'map');
            }

            seriesOpt.map = seriesOpt.mapType;
          }

          if (seriesOpt.mapLocation) {
            if ("development" !== 'production') {
              deprecateLog('`mapLocation` is not used anymore.');
            }

            defaults(seriesOpt, seriesOpt.mapLocation);
          }
        }

        if (seriesOpt.hoverAnimation != null) {
          seriesOpt.emphasis = seriesOpt.emphasis || {};

          if (seriesOpt.emphasis && seriesOpt.emphasis.scale == null) {
            if ("development" !== 'production') {
              deprecateReplaceLog('hoverAnimation', 'emphasis.scale');
            }

            seriesOpt.emphasis.scale = seriesOpt.hoverAnimation;
          }
        }

        compatLayoutProperties(seriesOpt);
      }); // dataRange has changed to visualMap

      if (option.dataRange) {
        option.visualMap = option.dataRange;
      }

      each(COMPATITABLE_COMPONENTS, function (componentName) {
        var options = option[componentName];

        if (options) {
          if (!isArray(options)) {
            options = [options];
          }

          each(options, function (option) {
            compatLayoutProperties(option);
          });
        }
      });
    }

    //     data processing stage is blocked in stream.
    //     See <module:echarts/stream/Scheduler#performDataProcessorTasks>
    // (2) Only register once when import repeatedly.
    //     Should be executed after series is filtered and before stack calculation.

    function dataStack(ecModel) {
      var stackInfoMap = createHashMap();
      ecModel.eachSeries(function (seriesModel) {
        var stack = seriesModel.get('stack'); // Compatible: when `stack` is set as '', do not stack.

        if (stack) {
          var stackInfoList = stackInfoMap.get(stack) || stackInfoMap.set(stack, []);
          var data = seriesModel.getData();
          var stackInfo = {
            // Used for calculate axis extent automatically.
            // TODO: Type getCalculationInfo return more specific type?
            stackResultDimension: data.getCalculationInfo('stackResultDimension'),
            stackedOverDimension: data.getCalculationInfo('stackedOverDimension'),
            stackedDimension: data.getCalculationInfo('stackedDimension'),
            stackedByDimension: data.getCalculationInfo('stackedByDimension'),
            isStackedByIndex: data.getCalculationInfo('isStackedByIndex'),
            data: data,
            seriesModel: seriesModel
          }; // If stacked on axis that do not support data stack.

          if (!stackInfo.stackedDimension || !(stackInfo.isStackedByIndex || stackInfo.stackedByDimension)) {
            return;
          }

          stackInfoList.length && data.setCalculationInfo('stackedOnSeries', stackInfoList[stackInfoList.length - 1].seriesModel);
          stackInfoList.push(stackInfo);
        }
      });
      stackInfoMap.each(calculateStack);
    }

    function calculateStack(stackInfoList) {
      each(stackInfoList, function (targetStackInfo, idxInStack) {
        var resultVal = [];
        var resultNaN = [NaN, NaN];
        var dims = [targetStackInfo.stackResultDimension, targetStackInfo.stackedOverDimension];
        var targetData = targetStackInfo.data;
        var isStackedByIndex = targetStackInfo.isStackedByIndex;
        var stackStrategy = targetStackInfo.seriesModel.get('stackStrategy') || 'samesign'; // Should not write on raw data, because stack series model list changes
        // depending on legend selection.

        targetData.modify(dims, function (v0, v1, dataIndex) {
          var sum = targetData.get(targetStackInfo.stackedDimension, dataIndex); // Consider `connectNulls` of line area, if value is NaN, stackedOver
          // should also be NaN, to draw a appropriate belt area.

          if (isNaN(sum)) {
            return resultNaN;
          }

          var byValue;
          var stackedDataRawIndex;

          if (isStackedByIndex) {
            stackedDataRawIndex = targetData.getRawIndex(dataIndex);
          } else {
            byValue = targetData.get(targetStackInfo.stackedByDimension, dataIndex);
          } // If stackOver is NaN, chart view will render point on value start.


          var stackedOver = NaN;

          for (var j = idxInStack - 1; j >= 0; j--) {
            var stackInfo = stackInfoList[j]; // Has been optimized by inverted indices on `stackedByDimension`.

            if (!isStackedByIndex) {
              stackedDataRawIndex = stackInfo.data.rawIndexOf(stackInfo.stackedByDimension, byValue);
            }

            if (stackedDataRawIndex >= 0) {
              var val = stackInfo.data.getByRawIndex(stackInfo.stackResultDimension, stackedDataRawIndex); // Considering positive stack, negative stack and empty data

              if (stackStrategy === 'all' // single stack group
              || stackStrategy === 'positive' && val > 0 || stackStrategy === 'negative' && val < 0 || stackStrategy === 'samesign' && sum > 0 && val > 0 // All positive stack
              || stackStrategy === 'samesign' && sum < 0 && val < 0 // All negative stack
              ) {
                  // The sum has to be very small to be affected by the
                  // floating arithmetic problem. An incorrect result will probably
                  // cause axis min/max to be filtered incorrectly.
                  sum = addSafe(sum, val);
                  stackedOver = val;
                  break;
                }
            }
          }

          resultVal[0] = sum;
          resultVal[1] = stackedOver;
          return resultVal;
        });
      });
    }

    var SourceImpl =
    /** @class */
    function () {
      function SourceImpl(fields) {
        this.data = fields.data || (fields.sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS ? {} : []);
        this.sourceFormat = fields.sourceFormat || SOURCE_FORMAT_UNKNOWN; // Visit config

        this.seriesLayoutBy = fields.seriesLayoutBy || SERIES_LAYOUT_BY_COLUMN;
        this.startIndex = fields.startIndex || 0;
        this.dimensionsDetectedCount = fields.dimensionsDetectedCount;
        this.metaRawOption = fields.metaRawOption;
        var dimensionsDefine = this.dimensionsDefine = fields.dimensionsDefine;

        if (dimensionsDefine) {
          for (var i = 0; i < dimensionsDefine.length; i++) {
            var dim = dimensionsDefine[i];

            if (dim.type == null) {
              if (guessOrdinal(this, i) === BE_ORDINAL.Must) {
                dim.type = 'ordinal';
              }
            }
          }
        }
      }

      return SourceImpl;
    }();

    function isSourceInstance(val) {
      return val instanceof SourceImpl;
    }
    /**
     * Create a source from option.
     * NOTE: Created source is immutable. Don't change any properties in it.
     */

    function createSource(sourceData, thisMetaRawOption, // can be null. If not provided, auto detect it from `sourceData`.
    sourceFormat) {
      sourceFormat = sourceFormat || detectSourceFormat(sourceData);
      var seriesLayoutBy = thisMetaRawOption.seriesLayoutBy;
      var determined = determineSourceDimensions(sourceData, sourceFormat, seriesLayoutBy, thisMetaRawOption.sourceHeader, thisMetaRawOption.dimensions);
      var source = new SourceImpl({
        data: sourceData,
        sourceFormat: sourceFormat,
        seriesLayoutBy: seriesLayoutBy,
        dimensionsDefine: determined.dimensionsDefine,
        startIndex: determined.startIndex,
        dimensionsDetectedCount: determined.dimensionsDetectedCount,
        metaRawOption: clone(thisMetaRawOption)
      });
      return source;
    }
    /**
     * Wrap original series data for some compatibility cases.
     */

    function createSourceFromSeriesDataOption(data) {
      return new SourceImpl({
        data: data,
        sourceFormat: isTypedArray(data) ? SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL
      });
    }
    /**
     * Clone source but excludes source data.
     */

    function cloneSourceShallow(source) {
      return new SourceImpl({
        data: source.data,
        sourceFormat: source.sourceFormat,
        seriesLayoutBy: source.seriesLayoutBy,
        dimensionsDefine: clone(source.dimensionsDefine),
        startIndex: source.startIndex,
        dimensionsDetectedCount: source.dimensionsDetectedCount
      });
    }
    /**
     * Note: An empty array will be detected as `SOURCE_FORMAT_ARRAY_ROWS`.
     */

    function detectSourceFormat(data) {
      var sourceFormat = SOURCE_FORMAT_UNKNOWN;

      if (isTypedArray(data)) {
        sourceFormat = SOURCE_FORMAT_TYPED_ARRAY;
      } else if (isArray(data)) {
        // FIXME Whether tolerate null in top level array?
        if (data.length === 0) {
          sourceFormat = SOURCE_FORMAT_ARRAY_ROWS;
        }

        for (var i = 0, len = data.length; i < len; i++) {
          var item = data[i];

          if (item == null) {
            continue;
          } else if (isArray(item)) {
            sourceFormat = SOURCE_FORMAT_ARRAY_ROWS;
            break;
          } else if (isObject(item)) {
            sourceFormat = SOURCE_FORMAT_OBJECT_ROWS;
            break;
          }
        }
      } else if (isObject(data)) {
        for (var key in data) {
          if (hasOwn(data, key) && isArrayLike(data[key])) {
            sourceFormat = SOURCE_FORMAT_KEYED_COLUMNS;
            break;
          }
        }
      }

      return sourceFormat;
    }
    /**
     * Determine the source definitions from data standalone dimensions definitions
     * are not specified.
     */

    function determineSourceDimensions(data, sourceFormat, seriesLayoutBy, sourceHeader, // standalone raw dimensions definition, like:
    // {
    //     dimensions: ['aa', 'bb', { name: 'cc', type: 'time' }]
    // }
    // in `dataset` or `series`
    dimensionsDefine) {
      var dimensionsDetectedCount;
      var startIndex; // PENDING: Could data be null/undefined here?
      // currently, if `dataset.source` not specified, error thrown.
      // if `series.data` not specified, nothing rendered without error thrown.
      // Should test these cases.

      if (!data) {
        return {
          dimensionsDefine: normalizeDimensionsOption(dimensionsDefine),
          startIndex: startIndex,
          dimensionsDetectedCount: dimensionsDetectedCount
        };
      }

      if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
        var dataArrayRows = data; // Rule: Most of the first line are string: it is header.
        // Caution: consider a line with 5 string and 1 number,
        // it still can not be sure it is a head, because the
        // 5 string may be 5 values of category columns.

        if (sourceHeader === 'auto' || sourceHeader == null) {
          arrayRowsTravelFirst(function (val) {
            // '-' is regarded as null/undefined.
            if (val != null && val !== '-') {
              if (isString(val)) {
                startIndex == null && (startIndex = 1);
              } else {
                startIndex = 0;
              }
            } // 10 is an experience number, avoid long loop.

          }, seriesLayoutBy, dataArrayRows, 10);
        } else {
          startIndex = isNumber(sourceHeader) ? sourceHeader : sourceHeader ? 1 : 0;
        }

        if (!dimensionsDefine && startIndex === 1) {
          dimensionsDefine = [];
          arrayRowsTravelFirst(function (val, index) {
            dimensionsDefine[index] = val != null ? val + '' : '';
          }, seriesLayoutBy, dataArrayRows, Infinity);
        }

        dimensionsDetectedCount = dimensionsDefine ? dimensionsDefine.length : seriesLayoutBy === SERIES_LAYOUT_BY_ROW ? dataArrayRows.length : dataArrayRows[0] ? dataArrayRows[0].length : null;
      } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
        if (!dimensionsDefine) {
          dimensionsDefine = objectRowsCollectDimensions(data);
        }
      } else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
        if (!dimensionsDefine) {
          dimensionsDefine = [];
          each(data, function (colArr, key) {
            dimensionsDefine.push(key);
          });
        }
      } else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        var value0 = getDataItemValue(data[0]);
        dimensionsDetectedCount = isArray(value0) && value0.length || 1;
      } else if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
        if ("development" !== 'production') {
          assert(!!dimensionsDefine, 'dimensions must be given if data is TypedArray.');
        }
      }

      return {
        startIndex: startIndex,
        dimensionsDefine: normalizeDimensionsOption(dimensionsDefine),
        dimensionsDetectedCount: dimensionsDetectedCount
      };
    }

    function objectRowsCollectDimensions(data) {
      var firstIndex = 0;
      var obj;

      while (firstIndex < data.length && !(obj = data[firstIndex++])) {} // jshint ignore: line


      if (obj) {
        var dimensions_1 = [];
        each(obj, function (value, key) {
          dimensions_1.push(key);
        });
        return dimensions_1;
      }
    } // Consider dimensions defined like ['A', 'price', 'B', 'price', 'C', 'price'],
    // which is reasonable. But dimension name is duplicated.
    // Returns undefined or an array contains only object without null/undefined or string.


    function normalizeDimensionsOption(dimensionsDefine) {
      if (!dimensionsDefine) {
        // The meaning of null/undefined is different from empty array.
        return;
      }

      var nameMap = createHashMap();
      return map(dimensionsDefine, function (rawItem, index) {
        rawItem = isObject(rawItem) ? rawItem : {
          name: rawItem
        }; // Other fields will be discarded.

        var item = {
          name: rawItem.name,
          displayName: rawItem.displayName,
          type: rawItem.type
        }; // User can set null in dimensions.
        // We don't auto specify name, otherwise a given name may
        // cause it to be referred unexpectedly.

        if (item.name == null) {
          return item;
        } // Also consider number form like 2012.


        item.name += ''; // User may also specify displayName.
        // displayName will always exists except user not
        // specified or dim name is not specified or detected.
        // (A auto generated dim name will not be used as
        // displayName).

        if (item.displayName == null) {
          item.displayName = item.name;
        }

        var exist = nameMap.get(item.name);

        if (!exist) {
          nameMap.set(item.name, {
            count: 1
          });
        } else {
          item.name += '-' + exist.count++;
        }

        return item;
      });
    }

    function arrayRowsTravelFirst(cb, seriesLayoutBy, data, maxLoop) {
      if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) {
        for (var i = 0; i < data.length && i < maxLoop; i++) {
          cb(data[i] ? data[i][0] : null, i);
        }
      } else {
        var value0 = data[0] || [];

        for (var i = 0; i < value0.length && i < maxLoop; i++) {
          cb(value0[i], i);
        }
      }
    }

    function shouldRetrieveDataByName(source) {
      var sourceFormat = source.sourceFormat;
      return sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS;
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var _a, _b, _c; // TODO
    var providerMethods;
    var mountMethods;
    /**
     * If normal array used, mutable chunk size is supported.
     * If typed array used, chunk size must be fixed.
     */

    var DefaultDataProvider =
    /** @class */
    function () {
      function DefaultDataProvider(sourceParam, dimSize) {
        // let source: Source;
        var source = !isSourceInstance(sourceParam) ? createSourceFromSeriesDataOption(sourceParam) : sourceParam; // declare source is Source;

        this._source = source;
        var data = this._data = source.data; // Typed array. TODO IE10+?

        if (source.sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
          if ("development" !== 'production') {
            if (dimSize == null) {
              throw new Error('Typed array data must specify dimension size');
            }
          }

          this._offset = 0;
          this._dimSize = dimSize;
          this._data = data;
        }

        mountMethods(this, data, source);
      }

      DefaultDataProvider.prototype.getSource = function () {
        return this._source;
      };

      DefaultDataProvider.prototype.count = function () {
        return 0;
      };

      DefaultDataProvider.prototype.getItem = function (idx, out) {
        return;
      };

      DefaultDataProvider.prototype.appendData = function (newData) {};

      DefaultDataProvider.prototype.clean = function () {};

      DefaultDataProvider.protoInitialize = function () {
        // PENDING: To avoid potential incompat (e.g., prototype
        // is visited somewhere), still init them on prototype.
        var proto = DefaultDataProvider.prototype;
        proto.pure = false;
        proto.persistent = true;
      }();

      DefaultDataProvider.internalField = function () {
        var _a;

        mountMethods = function (provider, data, source) {
          var sourceFormat = source.sourceFormat;
          var seriesLayoutBy = source.seriesLayoutBy;
          var startIndex = source.startIndex;
          var dimsDef = source.dimensionsDefine;
          var methods = providerMethods[getMethodMapKey(sourceFormat, seriesLayoutBy)];

          if ("development" !== 'production') {
            assert(methods, 'Invalide sourceFormat: ' + sourceFormat);
          }

          extend(provider, methods);

          if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
            provider.getItem = getItemForTypedArray;
            provider.count = countForTypedArray;
            provider.fillStorage = fillStorageForTypedArray;
          } else {
            var rawItemGetter = getRawSourceItemGetter(sourceFormat, seriesLayoutBy);
            provider.getItem = bind(rawItemGetter, null, data, startIndex, dimsDef);
            var rawCounter = getRawSourceDataCounter(sourceFormat, seriesLayoutBy);
            provider.count = bind(rawCounter, null, data, startIndex, dimsDef);
          }
        };

        var getItemForTypedArray = function (idx, out) {
          idx = idx - this._offset;
          out = out || [];
          var data = this._data;
          var dimSize = this._dimSize;
          var offset = dimSize * idx;

          for (var i = 0; i < dimSize; i++) {
            out[i] = data[offset + i];
          }

          return out;
        };

        var fillStorageForTypedArray = function (start, end, storage, extent) {
          var data = this._data;
          var dimSize = this._dimSize;

          for (var dim = 0; dim < dimSize; dim++) {
            var dimExtent = extent[dim];
            var min = dimExtent[0] == null ? Infinity : dimExtent[0];
            var max = dimExtent[1] == null ? -Infinity : dimExtent[1];
            var count = end - start;
            var arr = storage[dim];

            for (var i = 0; i < count; i++) {
              // appendData with TypedArray will always do replace in provider.
              var val = data[i * dimSize + dim];
              arr[start + i] = val;
              val < min && (min = val);
              val > max && (max = val);
            }

            dimExtent[0] = min;
            dimExtent[1] = max;
          }
        };

        var countForTypedArray = function () {
          return this._data ? this._data.length / this._dimSize : 0;
        };

        providerMethods = (_a = {}, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = {
          pure: true,
          appendData: appendDataSimply
        }, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = {
          pure: true,
          appendData: function () {
            throw new Error('Do not support appendData when set seriesLayoutBy: "row".');
          }
        }, _a[SOURCE_FORMAT_OBJECT_ROWS] = {
          pure: true,
          appendData: appendDataSimply
        }, _a[SOURCE_FORMAT_KEYED_COLUMNS] = {
          pure: true,
          appendData: function (newData) {
            var data = this._data;
            each(newData, function (newCol, key) {
              var oldCol = data[key] || (data[key] = []);

              for (var i = 0; i < (newCol || []).length; i++) {
                oldCol.push(newCol[i]);
              }
            });
          }
        }, _a[SOURCE_FORMAT_ORIGINAL] = {
          appendData: appendDataSimply
        }, _a[SOURCE_FORMAT_TYPED_ARRAY] = {
          persistent: false,
          pure: true,
          appendData: function (newData) {
            if ("development" !== 'production') {
              assert(isTypedArray(newData), 'Added data must be TypedArray if data in initialization is TypedArray');
            }

            this._data = newData;
          },
          // Clean self if data is already used.
          clean: function () {
            // PENDING
            this._offset += this.count();
            this._data = null;
          }
        }, _a);

        function appendDataSimply(newData) {
          for (var i = 0; i < newData.length; i++) {
            this._data.push(newData[i]);
          }
        }
      }();

      return DefaultDataProvider;
    }();

    var getItemSimply = function (rawData, startIndex, dimsDef, idx) {
      return rawData[idx];
    };

    var rawSourceItemGetterMap = (_a = {}, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = function (rawData, startIndex, dimsDef, idx) {
      return rawData[idx + startIndex];
    }, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = function (rawData, startIndex, dimsDef, idx, out) {
      idx += startIndex;
      var item = out || [];
      var data = rawData;

      for (var i = 0; i < data.length; i++) {
        var row = data[i];
        item[i] = row ? row[idx] : null;
      }

      return item;
    }, _a[SOURCE_FORMAT_OBJECT_ROWS] = getItemSimply, _a[SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef, idx, out) {
      var item = out || [];

      for (var i = 0; i < dimsDef.length; i++) {
        var dimName = dimsDef[i].name;

        if ("development" !== 'production') {
          if (dimName == null) {
            throw new Error();
          }
        }

        var col = rawData[dimName];
        item[i] = col ? col[idx] : null;
      }

      return item;
    }, _a[SOURCE_FORMAT_ORIGINAL] = getItemSimply, _a);
    function getRawSourceItemGetter(sourceFormat, seriesLayoutBy) {
      var method = rawSourceItemGetterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)];

      if ("development" !== 'production') {
        assert(method, 'Do not support get item on "' + sourceFormat + '", "' + seriesLayoutBy + '".');
      }

      return method;
    }

    var countSimply = function (rawData, startIndex, dimsDef) {
      return rawData.length;
    };

    var rawSourceDataCounterMap = (_b = {}, _b[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = function (rawData, startIndex, dimsDef) {
      return Math.max(0, rawData.length - startIndex);
    }, _b[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = function (rawData, startIndex, dimsDef) {
      var row = rawData[0];
      return row ? Math.max(0, row.length - startIndex) : 0;
    }, _b[SOURCE_FORMAT_OBJECT_ROWS] = countSimply, _b[SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef) {
      var dimName = dimsDef[0].name;

      if ("development" !== 'production') {
        if (dimName == null) {
          throw new Error();
        }
      }

      var col = rawData[dimName];
      return col ? col.length : 0;
    }, _b[SOURCE_FORMAT_ORIGINAL] = countSimply, _b);
    function getRawSourceDataCounter(sourceFormat, seriesLayoutBy) {
      var method = rawSourceDataCounterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)];

      if ("development" !== 'production') {
        assert(method, 'Do not support count on "' + sourceFormat + '", "' + seriesLayoutBy + '".');
      }

      return method;
    }

    var getRawValueSimply = function (dataItem, dimIndex, property) {
      return dataItem[dimIndex];
    };

    var rawSourceValueGetterMap = (_c = {}, _c[SOURCE_FORMAT_ARRAY_ROWS] = getRawValueSimply, _c[SOURCE_FORMAT_OBJECT_ROWS] = function (dataItem, dimIndex, property) {
      return dataItem[property];
    }, _c[SOURCE_FORMAT_KEYED_COLUMNS] = getRawValueSimply, _c[SOURCE_FORMAT_ORIGINAL] = function (dataItem, dimIndex, property) {
      // FIXME: In some case (markpoint in geo (geo-map.html)),
      // dataItem is {coord: [...]}
      var value = getDataItemValue(dataItem);
      return !(value instanceof Array) ? value : value[dimIndex];
    }, _c[SOURCE_FORMAT_TYPED_ARRAY] = getRawValueSimply, _c);
    function getRawSourceValueGetter(sourceFormat) {
      var method = rawSourceValueGetterMap[sourceFormat];

      if ("development" !== 'production') {
        assert(method, 'Do not support get value on "' + sourceFormat + '".');
      }

      return method;
    }

    function getMethodMapKey(sourceFormat, seriesLayoutBy) {
      return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS ? sourceFormat + '_' + seriesLayoutBy : sourceFormat;
    } // ??? FIXME can these logic be more neat: getRawValue, getRawDataItem,
    // Consider persistent.
    // Caution: why use raw value to display on label or tooltip?
    // A reason is to avoid format. For example time value we do not know
    // how to format is expected. More over, if stack is used, calculated
    // value may be 0.91000000001, which have brings trouble to display.
    // TODO: consider how to treat null/undefined/NaN when display?


    function retrieveRawValue(data, dataIndex, // If dimIndex is null/undefined, return OptionDataItem.
    // Otherwise, return OptionDataValue.
    dim) {
      if (!data) {
        return;
      } // Consider data may be not persistent.


      var dataItem = data.getRawDataItem(dataIndex);

      if (dataItem == null) {
        return;
      }

      var store = data.getStore();
      var sourceFormat = store.getSource().sourceFormat;

      if (dim != null) {
        var dimIndex = data.getDimensionIndex(dim);
        var property = store.getDimensionProperty(dimIndex);
        return getRawSourceValueGetter(sourceFormat)(dataItem, dimIndex, property);
      } else {
        var result = dataItem;

        if (sourceFormat === SOURCE_FORMAT_ORIGINAL) {
          result = getDataItemValue(dataItem);
        }

        return result;
      }
    }

    var DIMENSION_LABEL_REG = /\{@(.+?)\}/g;

    var DataFormatMixin =
    /** @class */
    function () {
      function DataFormatMixin() {}
      /**
       * Get params for formatter
       */


      DataFormatMixin.prototype.getDataParams = function (dataIndex, dataType) {
        var data = this.getData(dataType);
        var rawValue = this.getRawValue(dataIndex, dataType);
        var rawDataIndex = data.getRawIndex(dataIndex);
        var name = data.getName(dataIndex);
        var itemOpt = data.getRawDataItem(dataIndex);
        var style = data.getItemVisual(dataIndex, 'style');
        var color = style && style[data.getItemVisual(dataIndex, 'drawType') || 'fill'];
        var borderColor = style && style.stroke;
        var mainType = this.mainType;
        var isSeries = mainType === 'series';
        var userOutput = data.userOutput && data.userOutput.get();
        return {
          componentType: mainType,
          componentSubType: this.subType,
          componentIndex: this.componentIndex,
          seriesType: isSeries ? this.subType : null,
          seriesIndex: this.seriesIndex,
          seriesId: isSeries ? this.id : null,
          seriesName: isSeries ? this.name : null,
          name: name,
          dataIndex: rawDataIndex,
          data: itemOpt,
          dataType: dataType,
          value: rawValue,
          color: color,
          borderColor: borderColor,
          dimensionNames: userOutput ? userOutput.fullDimensions : null,
          encode: userOutput ? userOutput.encode : null,
          // Param name list for mapping `a`, `b`, `c`, `d`, `e`
          $vars: ['seriesName', 'name', 'value']
        };
      };
      /**
       * Format label
       * @param dataIndex
       * @param status 'normal' by default
       * @param dataType
       * @param labelDimIndex Only used in some chart that
       *        use formatter in different dimensions, like radar.
       * @param formatter Formatter given outside.
       * @return return null/undefined if no formatter
       */


      DataFormatMixin.prototype.getFormattedLabel = function (dataIndex, status, dataType, labelDimIndex, formatter, extendParams) {
        status = status || 'normal';
        var data = this.getData(dataType);
        var params = this.getDataParams(dataIndex, dataType);

        if (extendParams) {
          params.value = extendParams.interpolatedValue;
        }

        if (labelDimIndex != null && isArray(params.value)) {
          params.value = params.value[labelDimIndex];
        }

        if (!formatter) {
          var itemModel = data.getItemModel(dataIndex); // @ts-ignore

          formatter = itemModel.get(status === 'normal' ? ['label', 'formatter'] : [status, 'label', 'formatter']);
        }

        if (isFunction(formatter)) {
          params.status = status;
          params.dimensionIndex = labelDimIndex;
          return formatter(params);
        } else if (isString(formatter)) {
          var str = formatTpl(formatter, params); // Support 'aaa{@[3]}bbb{@product}ccc'.
          // Do not support '}' in dim name util have to.

          return str.replace(DIMENSION_LABEL_REG, function (origin, dimStr) {
            var len = dimStr.length;
            var dimLoose = dimStr;

            if (dimLoose.charAt(0) === '[' && dimLoose.charAt(len - 1) === ']') {
              dimLoose = +dimLoose.slice(1, len - 1); // Also support: '[]' => 0

              if ("development" !== 'production') {
                if (isNaN(dimLoose)) {
                  error("Invalide label formatter: @" + dimStr + ", only support @[0], @[1], @[2], ...");
                }
              }
            }

            var val = retrieveRawValue(data, dataIndex, dimLoose);

            if (extendParams && isArray(extendParams.interpolatedValue)) {
              var dimIndex = data.getDimensionIndex(dimLoose);

              if (dimIndex >= 0) {
                val = extendParams.interpolatedValue[dimIndex];
              }
            }

            return val != null ? val + '' : '';
          });
        }
      };
      /**
       * Get raw value in option
       */


      DataFormatMixin.prototype.getRawValue = function (idx, dataType) {
        return retrieveRawValue(this.getData(dataType), idx);
      };
      /**
       * Should be implemented.
       * @param {number} dataIndex
       * @param {boolean} [multipleSeries=false]
       * @param {string} [dataType]
       */


      DataFormatMixin.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        // Empty function
        return;
      };

      return DataFormatMixin;
    }();
    // but guess little chance has been used outside. Do we need to backward
    // compat it?
    // type TooltipFormatResultLegacyObject = {
    //     // `html` means the markup language text, either in 'html' or 'richText'.
    //     // The name `html` is not appropriate because in 'richText' it is not a HTML
    //     // string. But still support it for backward compatibility.
    //     html: string;
    //     markers: Dictionary<ColorString>;
    // };

    /**
     * For backward compat, normalize the return from `formatTooltip`.
     */

    function normalizeTooltipFormatResult(result) {
      var markupText; // let markers: Dictionary<ColorString>;

      var markupFragment;

      if (isObject(result)) {
        if (result.type) {
          markupFragment = result;
        } else {
          if ("development" !== 'production') {
            console.warn('The return type of `formatTooltip` is not supported: ' + makePrintable(result));
          }
        } // else {
        //     markupText = (result as TooltipFormatResultLegacyObject).html;
        //     markers = (result as TooltipFormatResultLegacyObject).markers;
        //     if (markersExisting) {
        //         markers = zrUtil.merge(markersExisting, markers);
        //     }
        // }

      } else {
        markupText = result;
      }

      return {
        text: markupText,
        // markers: markers || markersExisting,
        frag: markupFragment
      };
    }

    /**
     * @param {Object} define
     * @return See the return of `createTask`.
     */

    function createTask(define) {
      return new Task(define);
    }

    var Task =
    /** @class */
    function () {
      function Task(define) {
        define = define || {};
        this._reset = define.reset;
        this._plan = define.plan;
        this._count = define.count;
        this._onDirty = define.onDirty;
        this._dirty = true;
      }
      /**
       * @param step Specified step.
       * @param skip Skip customer perform call.
       * @param modBy Sampling window size.
       * @param modDataCount Sampling count.
       * @return whether unfinished.
       */


      Task.prototype.perform = function (performArgs) {
        var upTask = this._upstream;
        var skip = performArgs && performArgs.skip; // TODO some refactor.
        // Pull data. Must pull data each time, because context.data
        // may be updated by Series.setData.

        if (this._dirty && upTask) {
          var context = this.context;
          context.data = context.outputData = upTask.context.outputData;
        }

        if (this.__pipeline) {
          this.__pipeline.currentTask = this;
        }

        var planResult;

        if (this._plan && !skip) {
          planResult = this._plan(this.context);
        } // Support sharding by mod, which changes the render sequence and makes the rendered graphic
        // elements uniformed distributed when progress, especially when moving or zooming.


        var lastModBy = normalizeModBy(this._modBy);
        var lastModDataCount = this._modDataCount || 0;
        var modBy = normalizeModBy(performArgs && performArgs.modBy);
        var modDataCount = performArgs && performArgs.modDataCount || 0;

        if (lastModBy !== modBy || lastModDataCount !== modDataCount) {
          planResult = 'reset';
        }

        function normalizeModBy(val) {
          !(val >= 1) && (val = 1); // jshint ignore:line

          return val;
        }

        var forceFirstProgress;

        if (this._dirty || planResult === 'reset') {
          this._dirty = false;
          forceFirstProgress = this._doReset(skip);
        }

        this._modBy = modBy;
        this._modDataCount = modDataCount;
        var step = performArgs && performArgs.step;

        if (upTask) {
          if ("development" !== 'production') {
            assert(upTask._outputDueEnd != null);
          }

          this._dueEnd = upTask._outputDueEnd;
        } // DataTask or overallTask
        else {
            if ("development" !== 'production') {
              assert(!this._progress || this._count);
            }

            this._dueEnd = this._count ? this._count(this.context) : Infinity;
          } // Note: Stubs, that its host overall task let it has progress, has progress.
        // If no progress, pass index from upstream to downstream each time plan called.


        if (this._progress) {
          var start = this._dueIndex;
          var end = Math.min(step != null ? this._dueIndex + step : Infinity, this._dueEnd);

          if (!skip && (forceFirstProgress || start < end)) {
            var progress = this._progress;

            if (isArray(progress)) {
              for (var i = 0; i < progress.length; i++) {
                this._doProgress(progress[i], start, end, modBy, modDataCount);
              }
            } else {
              this._doProgress(progress, start, end, modBy, modDataCount);
            }
          }

          this._dueIndex = end; // If no `outputDueEnd`, assume that output data and
          // input data is the same, so use `dueIndex` as `outputDueEnd`.

          var outputDueEnd = this._settedOutputEnd != null ? this._settedOutputEnd : end;

          if ("development" !== 'production') {
            // ??? Can not rollback.
            assert(outputDueEnd >= this._outputDueEnd);
          }

          this._outputDueEnd = outputDueEnd;
        } else {
          // (1) Some overall task has no progress.
          // (2) Stubs, that its host overall task do not let it has progress, has no progress.
          // This should always be performed so it can be passed to downstream.
          this._dueIndex = this._outputDueEnd = this._settedOutputEnd != null ? this._settedOutputEnd : this._dueEnd;
        }

        return this.unfinished();
      };

      Task.prototype.dirty = function () {
        this._dirty = true;
        this._onDirty && this._onDirty(this.context);
      };

      Task.prototype._doProgress = function (progress, start, end, modBy, modDataCount) {
        iterator.reset(start, end, modBy, modDataCount);
        this._callingProgress = progress;

        this._callingProgress({
          start: start,
          end: end,
          count: end - start,
          next: iterator.next
        }, this.context);
      };

      Task.prototype._doReset = function (skip) {
        this._dueIndex = this._outputDueEnd = this._dueEnd = 0;
        this._settedOutputEnd = null;
        var progress;
        var forceFirstProgress;

        if (!skip && this._reset) {
          progress = this._reset(this.context);

          if (progress && progress.progress) {
            forceFirstProgress = progress.forceFirstProgress;
            progress = progress.progress;
          } // To simplify no progress checking, array must has item.


          if (isArray(progress) && !progress.length) {
            progress = null;
          }
        }

        this._progress = progress;
        this._modBy = this._modDataCount = null;
        var downstream = this._downstream;
        downstream && downstream.dirty();
        return forceFirstProgress;
      };

      Task.prototype.unfinished = function () {
        return this._progress && this._dueIndex < this._dueEnd;
      };
      /**
       * @param downTask The downstream task.
       * @return The downstream task.
       */


      Task.prototype.pipe = function (downTask) {
        if ("development" !== 'production') {
          assert(downTask && !downTask._disposed && downTask !== this);
        } // If already downstream, do not dirty downTask.


        if (this._downstream !== downTask || this._dirty) {
          this._downstream = downTask;
          downTask._upstream = this;
          downTask.dirty();
        }
      };

      Task.prototype.dispose = function () {
        if (this._disposed) {
          return;
        }

        this._upstream && (this._upstream._downstream = null);
        this._downstream && (this._downstream._upstream = null);
        this._dirty = false;
        this._disposed = true;
      };

      Task.prototype.getUpstream = function () {
        return this._upstream;
      };

      Task.prototype.getDownstream = function () {
        return this._downstream;
      };

      Task.prototype.setOutputEnd = function (end) {
        // This only happens in dataTask, dataZoom, map, currently.
        // where dataZoom do not set end each time, but only set
        // when reset. So we should record the set end, in case
        // that the stub of dataZoom perform again and earse the
        // set end by upstream.
        this._outputDueEnd = this._settedOutputEnd = end;
      };

      return Task;
    }();

    var iterator = function () {
      var end;
      var current;
      var modBy;
      var modDataCount;
      var winCount;
      var it = {
        reset: function (s, e, sStep, sCount) {
          current = s;
          end = e;
          modBy = sStep;
          modDataCount = sCount;
          winCount = Math.ceil(modDataCount / modBy);
          it.next = modBy > 1 && modDataCount > 0 ? modNext : sequentialNext;
        }
      };
      return it;

      function sequentialNext() {
        return current < end ? current++ : null;
      }

      function modNext() {
        var dataIndex = current % winCount * modBy + Math.ceil(current / winCount);
        var result = current >= end ? null : dataIndex < modDataCount ? dataIndex // If modDataCount is smaller than data.count() (consider `appendData` case),
        // Use normal linear rendering mode.
        : current;
        current++;
        return result;
      }
    }(); // -----------------------------------------------------------------------------
    // For stream debug (Should be commented out after used!)
    // @usage: printTask(this, 'begin');
    // @usage: printTask(this, null, {someExtraProp});
    // @usage: Use `__idxInPipeline` as conditional breakpiont.
    //
    // window.printTask = function (task: any, prefix: string, extra: { [key: string]: unknown }): void {
    //     window.ecTaskUID == null && (window.ecTaskUID = 0);
    //     task.uidDebug == null && (task.uidDebug = `task_${window.ecTaskUID++}`);
    //     task.agent && task.agent.uidDebug == null && (task.agent.uidDebug = `task_${window.ecTaskUID++}`);
    //     let props = [];
    //     if (task.__pipeline) {
    //         let val = `${task.__idxInPipeline}/${task.__pipeline.tail.__idxInPipeline} ${task.agent ? '(stub)' : ''}`;
    //         props.push({text: '__idxInPipeline/total', value: val});
    //     } else {
    //         let stubCount = 0;
    //         task.agentStubMap.each(() => stubCount++);
    //         props.push({text: 'idx', value: `overall (stubs: ${stubCount})`});
    //     }
    //     props.push({text: 'uid', value: task.uidDebug});
    //     if (task.__pipeline) {
    //         props.push({text: 'pipelineId', value: task.__pipeline.id});
    //         task.agent && props.push(
    //             {text: 'stubFor', value: task.agent.uidDebug}
    //         );
    //     }
    //     props.push(
    //         {text: 'dirty', value: task._dirty},
    //         {text: 'dueIndex', value: task._dueIndex},
    //         {text: 'dueEnd', value: task._dueEnd},
    //         {text: 'outputDueEnd', value: task._outputDueEnd}
    //     );
    //     if (extra) {
    //         Object.keys(extra).forEach(key => {
    //             props.push({text: key, value: extra[key]});
    //         });
    //     }
    //     let args = ['color: blue'];
    //     let msg = `%c[${prefix || 'T'}] %c` + props.map(item => (
    //         args.push('color: green', 'color: red'),
    //         `${item.text}: %c${item.value}`
    //     )).join('%c, ');
    //     console.log.apply(console, [msg].concat(args));
    //     // console.log(this);
    // };
    // window.printPipeline = function (task: any, prefix: string) {
    //     const pipeline = task.__pipeline;
    //     let currTask = pipeline.head;
    //     while (currTask) {
    //         window.printTask(currTask, prefix);
    //         currTask = currTask._downstream;
    //     }
    // };
    // window.showChain = function (chainHeadTask) {
    //     var chain = [];
    //     var task = chainHeadTask;
    //     while (task) {
    //         chain.push({
    //             task: task,
    //             up: task._upstream,
    //             down: task._downstream,
    //             idxInPipeline: task.__idxInPipeline
    //         });
    //         task = task._downstream;
    //     }
    //     return chain;
    // };
    // window.findTaskInChain = function (task, chainHeadTask) {
    //     let chain = window.showChain(chainHeadTask);
    //     let result = [];
    //     for (let i = 0; i < chain.length; i++) {
    //         let chainItem = chain[i];
    //         if (chainItem.task === task) {
    //             result.push(i);
    //         }
    //     }
    //     return result;
    // };
    // window.printChainAEachInChainB = function (chainHeadTaskA, chainHeadTaskB) {
    //     let chainA = window.showChain(chainHeadTaskA);
    //     for (let i = 0; i < chainA.length; i++) {
    //         console.log('chainAIdx:', i, 'inChainB:', window.findTaskInChain(chainA[i].task, chainHeadTaskB));
    //     }
    // };

    /**
     * Convert raw the value in to inner value in List.
     *
     * [Performance sensitive]
     *
     * [Caution]: this is the key logic of user value parser.
     * For backward compatibility, do not modify it until you have to!
     */

    function parseDataValue(value, // For high performance, do not omit the second param.
    opt) {
      // Performance sensitive.
      var dimType = opt && opt.type;

      if (dimType === 'ordinal') {
        // If given value is a category string
        return value;
      }

      if (dimType === 'time' // spead up when using timestamp
      && !isNumber(value) && value != null && value !== '-') {
        value = +parseDate(value);
      } // dimType defaults 'number'.
      // If dimType is not ordinal and value is null or undefined or NaN or '-',
      // parse to NaN.
      // number-like string (like ' 123 ') can be converted to a number.
      // where null/undefined or other string will be converted to NaN.


      return value == null || value === '' ? NaN // If string (like '-'), using '+' parse to NaN
      // If object, also parse to NaN
      : +value;
    }
    var valueParserMap = createHashMap({
      'number': function (val) {
        // Do not use `numericToNumber` here. We have `numericToNumber` by default.
        // Here the number parser can have loose rule:
        // enable to cut suffix: "120px" => 120, "14%" => 14.
        return parseFloat(val);
      },
      'time': function (val) {
        // return timestamp.
        return +parseDate(val);
      },
      'trim': function (val) {
        return isString(val) ? trim(val) : val;
      }
    });

    var SortOrderComparator =
    /** @class */
    function () {
      /**
       * @param order by default: 'asc'
       * @param incomparable by default: Always on the tail.
       *        That is, if 'asc' => 'max', if 'desc' => 'min'
       *        See the definition of "incomparable" in [SORT_COMPARISON_RULE].
       */
      function SortOrderComparator(order, incomparable) {
        var isDesc = order === 'desc';
        this._resultLT = isDesc ? 1 : -1;

        if (incomparable == null) {
          incomparable = isDesc ? 'min' : 'max';
        }

        this._incomparable = incomparable === 'min' ? -Infinity : Infinity;
      } // See [SORT_COMPARISON_RULE].
      // Performance sensitive.


      SortOrderComparator.prototype.evaluate = function (lval, rval) {
        // Most cases is 'number', and typeof maybe 10 times faseter than parseFloat.
        var lvalFloat = isNumber(lval) ? lval : numericToNumber(lval);
        var rvalFloat = isNumber(rval) ? rval : numericToNumber(rval);
        var lvalNotNumeric = isNaN(lvalFloat);
        var rvalNotNumeric = isNaN(rvalFloat);

        if (lvalNotNumeric) {
          lvalFloat = this._incomparable;
        }

        if (rvalNotNumeric) {
          rvalFloat = this._incomparable;
        }

        if (lvalNotNumeric && rvalNotNumeric) {
          var lvalIsStr = isString(lval);
          var rvalIsStr = isString(rval);

          if (lvalIsStr) {
            lvalFloat = rvalIsStr ? lval : 0;
          }

          if (rvalIsStr) {
            rvalFloat = lvalIsStr ? rval : 0;
          }
        }

        return lvalFloat < rvalFloat ? this._resultLT : lvalFloat > rvalFloat ? -this._resultLT : 0;
      };

      return SortOrderComparator;
    }();

    /**
     * TODO: disable writable.
     * This structure will be exposed to users.
     */

    var ExternalSource =
    /** @class */
    function () {
      function ExternalSource() {}

      ExternalSource.prototype.getRawData = function () {
        // Only built-in transform available.
        throw new Error('not supported');
      };

      ExternalSource.prototype.getRawDataItem = function (dataIndex) {
        // Only built-in transform available.
        throw new Error('not supported');
      };

      ExternalSource.prototype.cloneRawData = function () {
        return;
      };
      /**
       * @return If dimension not found, return null/undefined.
       */


      ExternalSource.prototype.getDimensionInfo = function (dim) {
        return;
      };
      /**
       * dimensions defined if and only if either:
       * (a) dataset.dimensions are declared.
       * (b) dataset data include dimensions definitions in data (detected or via specified `sourceHeader`).
       * If dimensions are defined, `dimensionInfoAll` is corresponding to
       * the defined dimensions.
       * Otherwise, `dimensionInfoAll` is determined by data columns.
       * @return Always return an array (even empty array).
       */


      ExternalSource.prototype.cloneAllDimensionInfo = function () {
        return;
      };

      ExternalSource.prototype.count = function () {
        return;
      };
      /**
       * Only support by dimension index.
       * No need to support by dimension name in transform function,
       * because transform function is not case-specific, no need to use name literally.
       */


      ExternalSource.prototype.retrieveValue = function (dataIndex, dimIndex) {
        return;
      };

      ExternalSource.prototype.retrieveValueFromItem = function (dataItem, dimIndex) {
        return;
      };

      ExternalSource.prototype.convertValue = function (rawVal, dimInfo) {
        return parseDataValue(rawVal, dimInfo);
      };

      return ExternalSource;
    }();

    function createExternalSource(internalSource, externalTransform) {
      var extSource = new ExternalSource();
      var data = internalSource.data;
      var sourceFormat = extSource.sourceFormat = internalSource.sourceFormat;
      var sourceHeaderCount = internalSource.startIndex;
      var errMsg = '';

      if (internalSource.seriesLayoutBy !== SERIES_LAYOUT_BY_COLUMN) {
        // For the logic simplicity in transformer, only 'culumn' is
        // supported in data transform. Otherwise, the `dimensionsDefine`
        // might be detected by 'row', which probably confuses users.
        if ("development" !== 'production') {
          errMsg = '`seriesLayoutBy` of upstream dataset can only be "column" in data transform.';
        }

        throwError(errMsg);
      } // [MEMO]
      // Create a new dimensions structure for exposing.
      // Do not expose all dimension info to users directly.
      // Because the dimension is probably auto detected from data and not might reliable.
      // Should not lead the transformers to think that is reliable and return it.
      // See [DIMENSION_INHERIT_RULE] in `sourceManager.ts`.


      var dimensions = [];
      var dimsByName = {};
      var dimsDef = internalSource.dimensionsDefine;

      if (dimsDef) {
        each(dimsDef, function (dimDef, idx) {
          var name = dimDef.name;
          var dimDefExt = {
            index: idx,
            name: name,
            displayName: dimDef.displayName
          };
          dimensions.push(dimDefExt); // Users probably do not specify dimension name. For simplicity, data transform
          // does not generate dimension name.

          if (name != null) {
            // Dimension name should not be duplicated.
            // For simplicity, data transform forbids name duplication, do not generate
            // new name like module `completeDimensions.ts` did, but just tell users.
            var errMsg_1 = '';

            if (hasOwn(dimsByName, name)) {
              if ("development" !== 'production') {
                errMsg_1 = 'dimension name "' + name + '" duplicated.';
              }

              throwError(errMsg_1);
            }

            dimsByName[name] = dimDefExt;
          }
        });
      } // If dimension definitions are not defined and can not be detected.
      // e.g., pure data `[[11, 22], ...]`.
      else {
          for (var i = 0; i < internalSource.dimensionsDetectedCount || 0; i++) {
            // Do not generete name or anything others. The consequence process in
            // `transform` or `series` probably have there own name generation strategry.
            dimensions.push({
              index: i
            });
          }
        } // Implement public methods:


      var rawItemGetter = getRawSourceItemGetter(sourceFormat, SERIES_LAYOUT_BY_COLUMN);

      if (externalTransform.__isBuiltIn) {
        extSource.getRawDataItem = function (dataIndex) {
          return rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex);
        };

        extSource.getRawData = bind(getRawData, null, internalSource);
      }

      extSource.cloneRawData = bind(cloneRawData, null, internalSource);
      var rawCounter = getRawSourceDataCounter(sourceFormat, SERIES_LAYOUT_BY_COLUMN);
      extSource.count = bind(rawCounter, null, data, sourceHeaderCount, dimensions);
      var rawValueGetter = getRawSourceValueGetter(sourceFormat);

      extSource.retrieveValue = function (dataIndex, dimIndex) {
        var rawItem = rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex);
        return retrieveValueFromItem(rawItem, dimIndex);
      };

      var retrieveValueFromItem = extSource.retrieveValueFromItem = function (dataItem, dimIndex) {
        if (dataItem == null) {
          return;
        }

        var dimDef = dimensions[dimIndex]; // When `dimIndex` is `null`, `rawValueGetter` return the whole item.

        if (dimDef) {
          return rawValueGetter(dataItem, dimIndex, dimDef.name);
        }
      };

      extSource.getDimensionInfo = bind(getDimensionInfo, null, dimensions, dimsByName);
      extSource.cloneAllDimensionInfo = bind(cloneAllDimensionInfo, null, dimensions);
      return extSource;
    }

    function getRawData(upstream) {
      var sourceFormat = upstream.sourceFormat;

      if (!isSupportedSourceFormat(sourceFormat)) {
        var errMsg = '';

        if ("development" !== 'production') {
          errMsg = '`getRawData` is not supported in source format ' + sourceFormat;
        }

        throwError(errMsg);
      }

      return upstream.data;
    }

    function cloneRawData(upstream) {
      var sourceFormat = upstream.sourceFormat;
      var data = upstream.data;

      if (!isSupportedSourceFormat(sourceFormat)) {
        var errMsg = '';

        if ("development" !== 'production') {
          errMsg = '`cloneRawData` is not supported in source format ' + sourceFormat;
        }

        throwError(errMsg);
      }

      if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
        var result = [];

        for (var i = 0, len = data.length; i < len; i++) {
          // Not strictly clone for performance
          result.push(data[i].slice());
        }

        return result;
      } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
        var result = [];

        for (var i = 0, len = data.length; i < len; i++) {
          // Not strictly clone for performance
          result.push(extend({}, data[i]));
        }

        return result;
      }
    }

    function getDimensionInfo(dimensions, dimsByName, dim) {
      if (dim == null) {
        return;
      } // Keep the same logic as `List::getDimension` did.


      if (isNumber(dim) // If being a number-like string but not being defined a dimension name.
      || !isNaN(dim) && !hasOwn(dimsByName, dim)) {
        return dimensions[dim];
      } else if (hasOwn(dimsByName, dim)) {
        return dimsByName[dim];
      }
    }

    function cloneAllDimensionInfo(dimensions) {
      return clone(dimensions);
    }

    var externalTransformMap = createHashMap();
    function registerExternalTransform(externalTransform) {
      externalTransform = clone(externalTransform);
      var type = externalTransform.type;
      var errMsg = '';

      if (!type) {
        if ("development" !== 'production') {
          errMsg = 'Must have a `type` when `registerTransform`.';
        }

        throwError(errMsg);
      }

      var typeParsed = type.split(':');

      if (typeParsed.length !== 2) {
        if ("development" !== 'production') {
          errMsg = 'Name must include namespace like "ns:regression".';
        }

        throwError(errMsg);
      } // Namespace 'echarts:xxx' is official namespace, where the transforms should
      // be called directly via 'xxx' rather than 'echarts:xxx'.


      var isBuiltIn = false;

      if (typeParsed[0] === 'echarts') {
        type = typeParsed[1];
        isBuiltIn = true;
      }

      externalTransform.__isBuiltIn = isBuiltIn;
      externalTransformMap.set(type, externalTransform);
    }
    function applyDataTransform(rawTransOption, sourceList, infoForPrint) {
      var pipedTransOption = normalizeToArray(rawTransOption);
      var pipeLen = pipedTransOption.length;
      var errMsg = '';

      if (!pipeLen) {
        if ("development" !== 'production') {
          errMsg = 'If `transform` declared, it should at least contain one transform.';
        }

        throwError(errMsg);
      }

      for (var i = 0, len = pipeLen; i < len; i++) {
        var transOption = pipedTransOption[i];
        sourceList = applySingleDataTransform(transOption, sourceList, infoForPrint, pipeLen === 1 ? null : i); // piped transform only support single input, except the fist one.
        // piped transform only support single output, except the last one.

        if (i !== len - 1) {
          sourceList.length = Math.max(sourceList.length, 1);
        }
      }

      return sourceList;
    }

    function applySingleDataTransform(transOption, upSourceList, infoForPrint, // If `pipeIndex` is null/undefined, no piped transform.
    pipeIndex) {
      var errMsg = '';

      if (!upSourceList.length) {
        if ("development" !== 'production') {
          errMsg = 'Must have at least one upstream dataset.';
        }

        throwError(errMsg);
      }

      if (!isObject(transOption)) {
        if ("development" !== 'production') {
          errMsg = 'transform declaration must be an object rather than ' + typeof transOption + '.';
        }

        throwError(errMsg);
      }

      var transType = transOption.type;
      var externalTransform = externalTransformMap.get(transType);

      if (!externalTransform) {
        if ("development" !== 'production') {
          errMsg = 'Can not find transform on type "' + transType + '".';
        }

        throwError(errMsg);
      } // Prepare source


      var extUpSourceList = map(upSourceList, function (upSource) {
        return createExternalSource(upSource, externalTransform);
      });
      var resultList = normalizeToArray(externalTransform.transform({
        upstream: extUpSourceList[0],
        upstreamList: extUpSourceList,
        config: clone(transOption.config)
      }));

      if ("development" !== 'production') {
        if (transOption.print) {
          var printStrArr = map(resultList, function (extSource) {
            var pipeIndexStr = pipeIndex != null ? ' === pipe index: ' + pipeIndex : '';
            return ['=== dataset index: ' + infoForPrint.datasetIndex + pipeIndexStr + ' ===', '- transform result data:', makePrintable(extSource.data), '- transform result dimensions:', makePrintable(extSource.dimensions)].join('\n');
          }).join('\n');
          log(printStrArr);
        }
      }

      return map(resultList, function (result, resultIndex) {
        var errMsg = '';

        if (!isObject(result)) {
          if ("development" !== 'production') {
            errMsg = 'A transform should not return some empty results.';
          }

          throwError(errMsg);
        }

        if (!result.data) {
          if ("development" !== 'production') {
            errMsg = 'Transform result data should be not be null or undefined';
          }

          throwError(errMsg);
        }

        var sourceFormat = detectSourceFormat(result.data);

        if (!isSupportedSourceFormat(sourceFormat)) {
          if ("development" !== 'production') {
            errMsg = 'Transform result data should be array rows or object rows.';
          }

          throwError(errMsg);
        }

        var resultMetaRawOption;
        var firstUpSource = upSourceList[0];
        /**
         * Intuitively, the end users known the content of the original `dataset.source`,
         * calucating the transform result in mind.
         * Suppose the original `dataset.source` is:
         * ```js
         * [
         *     ['product', '2012', '2013', '2014', '2015'],
         *     ['AAA', 41.1, 30.4, 65.1, 53.3],
         *     ['BBB', 86.5, 92.1, 85.7, 83.1],
         *     ['CCC', 24.1, 67.2, 79.5, 86.4]
         * ]
         * ```
         * The dimension info have to be detected from the source data.
         * Some of the transformers (like filter, sort) will follow the dimension info
         * of upstream, while others use new dimensions (like aggregate).
         * Transformer can output a field `dimensions` to define the its own output dimensions.
         * We also allow transformers to ignore the output `dimensions` field, and
         * inherit the upstream dimensions definition. It can reduce the burden of handling
         * dimensions in transformers.
         *
         * See also [DIMENSION_INHERIT_RULE] in `sourceManager.ts`.
         */

        if (firstUpSource && resultIndex === 0 // If transformer returns `dimensions`, it means that the transformer has different
        // dimensions definitions. We do not inherit anything from upstream.
        && !result.dimensions) {
          var startIndex = firstUpSource.startIndex; // We copy the header of upstream to the result, because:
          // (1) The returned data always does not contain header line and can not be used
          // as dimension-detection. In this case we can not use "detected dimensions" of
          // upstream directly, because it might be detected based on different `seriesLayoutBy`.
          // (2) We should support that the series read the upstream source in `seriesLayoutBy: 'row'`.
          // So the original detected header should be add to the result, otherwise they can not be read.

          if (startIndex) {
            result.data = firstUpSource.data.slice(0, startIndex).concat(result.data);
          }

          resultMetaRawOption = {
            seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN,
            sourceHeader: startIndex,
            dimensions: firstUpSource.metaRawOption.dimensions
          };
        } else {
          resultMetaRawOption = {
            seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN,
            sourceHeader: 0,
            dimensions: result.dimensions
          };
        }

        return createSource(result.data, resultMetaRawOption, null);
      });
    }

    function isSupportedSourceFormat(sourceFormat) {
      return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS || sourceFormat === SOURCE_FORMAT_OBJECT_ROWS;
    }

    var UNDEFINED = 'undefined';
    /* global Float64Array, Int32Array, Uint32Array, Uint16Array */
    // Caution: MUST not use `new CtorUint32Array(arr, 0, len)`, because the Ctor of array is
    // different from the Ctor of typed array.

    var CtorUint32Array = typeof Uint32Array === UNDEFINED ? Array : Uint32Array;
    var CtorUint16Array = typeof Uint16Array === UNDEFINED ? Array : Uint16Array;
    var CtorInt32Array = typeof Int32Array === UNDEFINED ? Array : Int32Array;
    var CtorFloat64Array = typeof Float64Array === UNDEFINED ? Array : Float64Array;
    /**
     * Multi dimensional data store
     */

    var dataCtors = {
      'float': CtorFloat64Array,
      'int': CtorInt32Array,
      // Ordinal data type can be string or int
      'ordinal': Array,
      'number': Array,
      'time': CtorFloat64Array
    };
    var defaultDimValueGetters;

    function getIndicesCtor(rawCount) {
      // The possible max value in this._indicies is always this._rawCount despite of filtering.
      return rawCount > 65535 ? CtorUint32Array : CtorUint16Array;
    }

    function getInitialExtent() {
      return [Infinity, -Infinity];
    }

    function cloneChunk(originalChunk) {
      var Ctor = originalChunk.constructor; // Only shallow clone is enough when Array.

      return Ctor === Array ? originalChunk.slice() : new Ctor(originalChunk);
    }

    function prepareStore(store, dimIdx, dimType, end, append) {
      var DataCtor = dataCtors[dimType || 'float'];

      if (append) {
        var oldStore = store[dimIdx];
        var oldLen = oldStore && oldStore.length;

        if (!(oldLen === end)) {
          var newStore = new DataCtor(end); // The cost of the copy is probably inconsiderable
          // within the initial chunkSize.

          for (var j = 0; j < oldLen; j++) {
            newStore[j] = oldStore[j];
          }

          store[dimIdx] = newStore;
        }
      } else {
        store[dimIdx] = new DataCtor(end);
      }
    }
    /**
     * Basically, DataStore API keep immutable.
     */

    var DataStore =
    /** @class */
    function () {
      function DataStore() {
        this._chunks = []; // It will not be calculated util needed.

        this._rawExtent = [];
        this._extent = [];
        this._count = 0;
        this._rawCount = 0;
        this._calcDimNameToIdx = createHashMap();
      }
      /**
       * Initialize from data
       */


      DataStore.prototype.initData = function (provider, inputDimensions, dimValueGetter) {
        if ("development" !== 'production') {
          assert(isFunction(provider.getItem) && isFunction(provider.count), 'Invalid data provider.');
        }

        this._provider = provider; // Clear

        this._chunks = [];
        this._indices = null;
        this.getRawIndex = this._getRawIdxIdentity;
        var source = provider.getSource();
        var defaultGetter = this.defaultDimValueGetter = defaultDimValueGetters[source.sourceFormat]; // Default dim value getter

        this._dimValueGetter = dimValueGetter || defaultGetter; // Reset raw extent.

        this._rawExtent = [];
        var willRetrieveDataByName = shouldRetrieveDataByName(source);
        this._dimensions = map(inputDimensions, function (dim) {
          if ("development" !== 'production') {
            if (willRetrieveDataByName) {
              assert(dim.property != null);
            }
          }

          return {
            // Only pick these two props. Not leak other properties like orderMeta.
            type: dim.type,
            property: dim.property
          };
        });

        this._initDataFromProvider(0, provider.count());
      };

      DataStore.prototype.getProvider = function () {
        return this._provider;
      };
      /**
       * Caution: even when a `source` instance owned by a series, the created data store
       * may still be shared by different sereis (the source hash does not use all `source`
       * props, see `sourceManager`). In this case, the `source` props that are not used in
       * hash (like `source.dimensionDefine`) probably only belongs to a certain series and
       * thus should not be fetch here.
       */


      DataStore.prototype.getSource = function () {
        return this._provider.getSource();
      };
      /**
       * @caution Only used in dataStack.
       */


      DataStore.prototype.ensureCalculationDimension = function (dimName, type) {
        var calcDimNameToIdx = this._calcDimNameToIdx;
        var dimensions = this._dimensions;
        var calcDimIdx = calcDimNameToIdx.get(dimName);

        if (calcDimIdx != null) {
          if (dimensions[calcDimIdx].type === type) {
            return calcDimIdx;
          }
        } else {
          calcDimIdx = dimensions.length;
        }

        dimensions[calcDimIdx] = {
          type: type
        };
        calcDimNameToIdx.set(dimName, calcDimIdx);
        this._chunks[calcDimIdx] = new dataCtors[type || 'float'](this._rawCount);
        this._rawExtent[calcDimIdx] = getInitialExtent();
        return calcDimIdx;
      };

      DataStore.prototype.collectOrdinalMeta = function (dimIdx, ordinalMeta) {
        var chunk = this._chunks[dimIdx];
        var dim = this._dimensions[dimIdx];
        var rawExtents = this._rawExtent;
        var offset = dim.ordinalOffset || 0;
        var len = chunk.length;

        if (offset === 0) {
          // We need to reset the rawExtent if collect is from start.
          // Because this dimension may be guessed as number and calcuating a wrong extent.
          rawExtents[dimIdx] = getInitialExtent();
        }

        var dimRawExtent = rawExtents[dimIdx]; // Parse from previous data offset. len may be changed after appendData

        for (var i = offset; i < len; i++) {
          var val = chunk[i] = ordinalMeta.parseAndCollect(chunk[i]);

          if (!isNaN(val)) {
            dimRawExtent[0] = Math.min(val, dimRawExtent[0]);
            dimRawExtent[1] = Math.max(val, dimRawExtent[1]);
          }
        }

        dim.ordinalMeta = ordinalMeta;
        dim.ordinalOffset = len;
        dim.type = 'ordinal'; // Force to be ordinal
      };

      DataStore.prototype.getOrdinalMeta = function (dimIdx) {
        var dimInfo = this._dimensions[dimIdx];
        var ordinalMeta = dimInfo.ordinalMeta;
        return ordinalMeta;
      };

      DataStore.prototype.getDimensionProperty = function (dimIndex) {
        var item = this._dimensions[dimIndex];
        return item && item.property;
      };
      /**
       * Caution: Can be only called on raw data (before `this._indices` created).
       */


      DataStore.prototype.appendData = function (data) {
        if ("development" !== 'production') {
          assert(!this._indices, 'appendData can only be called on raw data.');
        }

        var provider = this._provider;
        var start = this.count();
        provider.appendData(data);
        var end = provider.count();

        if (!provider.persistent) {
          end += start;
        }

        if (start < end) {
          this._initDataFromProvider(start, end, true);
        }

        return [start, end];
      };

      DataStore.prototype.appendValues = function (values, minFillLen) {
        var chunks = this._chunks;
        var dimensions = this._dimensions;
        var dimLen = dimensions.length;
        var rawExtent = this._rawExtent;
        var start = this.count();
        var end = start + Math.max(values.length, minFillLen || 0);

        for (var i = 0; i < dimLen; i++) {
          var dim = dimensions[i];
          prepareStore(chunks, i, dim.type, end, true);
        }

        var emptyDataItem = [];

        for (var idx = start; idx < end; idx++) {
          var sourceIdx = idx - start; // Store the data by dimensions

          for (var dimIdx = 0; dimIdx < dimLen; dimIdx++) {
            var dim = dimensions[dimIdx];
            var val = defaultDimValueGetters.arrayRows.call(this, values[sourceIdx] || emptyDataItem, dim.property, sourceIdx, dimIdx);
            chunks[dimIdx][idx] = val;
            var dimRawExtent = rawExtent[dimIdx];
            val < dimRawExtent[0] && (dimRawExtent[0] = val);
            val > dimRawExtent[1] && (dimRawExtent[1] = val);
          }
        }

        this._rawCount = this._count = end;
        return {
          start: start,
          end: end
        };
      };

      DataStore.prototype._initDataFromProvider = function (start, end, append) {
        var provider = this._provider;
        var chunks = this._chunks;
        var dimensions = this._dimensions;
        var dimLen = dimensions.length;
        var rawExtent = this._rawExtent;
        var dimNames = map(dimensions, function (dim) {
          return dim.property;
        });

        for (var i = 0; i < dimLen; i++) {
          var dim = dimensions[i];

          if (!rawExtent[i]) {
            rawExtent[i] = getInitialExtent();
          }

          prepareStore(chunks, i, dim.type, end, append);
        }

        if (provider.fillStorage) {
          provider.fillStorage(start, end, chunks, rawExtent);
        } else {
          var dataItem = [];

          for (var idx = start; idx < end; idx++) {
            // NOTICE: Try not to write things into dataItem
            dataItem = provider.getItem(idx, dataItem); // Each data item is value
            // [1, 2]
            // 2
            // Bar chart, line chart which uses category axis
            // only gives the 'y' value. 'x' value is the indices of category
            // Use a tempValue to normalize the value to be a (x, y) value
            // Store the data by dimensions

            for (var dimIdx = 0; dimIdx < dimLen; dimIdx++) {
              var dimStorage = chunks[dimIdx]; // PENDING NULL is empty or zero

              var val = this._dimValueGetter(dataItem, dimNames[dimIdx], idx, dimIdx);

              dimStorage[idx] = val;
              var dimRawExtent = rawExtent[dimIdx];
              val < dimRawExtent[0] && (dimRawExtent[0] = val);
              val > dimRawExtent[1] && (dimRawExtent[1] = val);
            }
          }
        }

        if (!provider.persistent && provider.clean) {
          // Clean unused data if data source is typed array.
          provider.clean();
        }

        this._rawCount = this._count = end; // Reset data extent

        this._extent = [];
      };

      DataStore.prototype.count = function () {
        return this._count;
      };
      /**
       * Get value. Return NaN if idx is out of range.
       */


      DataStore.prototype.get = function (dim, idx) {
        if (!(idx >= 0 && idx < this._count)) {
          return NaN;
        }

        var dimStore = this._chunks[dim];
        return dimStore ? dimStore[this.getRawIndex(idx)] : NaN;
      };

      DataStore.prototype.getValues = function (dimensions, idx) {
        var values = [];
        var dimArr = [];

        if (idx == null) {
          idx = dimensions; // TODO get all from store?

          dimensions = []; // All dimensions

          for (var i = 0; i < this._dimensions.length; i++) {
            dimArr.push(i);
          }
        } else {
          dimArr = dimensions;
        }

        for (var i = 0, len = dimArr.length; i < len; i++) {
          values.push(this.get(dimArr[i], idx));
        }

        return values;
      };
      /**
       * @param dim concrete dim
       */


      DataStore.prototype.getByRawIndex = function (dim, rawIdx) {
        if (!(rawIdx >= 0 && rawIdx < this._rawCount)) {
          return NaN;
        }

        var dimStore = this._chunks[dim];
        return dimStore ? dimStore[rawIdx] : NaN;
      };
      /**
       * Get sum of data in one dimension
       */


      DataStore.prototype.getSum = function (dim) {
        var dimData = this._chunks[dim];
        var sum = 0;

        if (dimData) {
          for (var i = 0, len = this.count(); i < len; i++) {
            var value = this.get(dim, i);

            if (!isNaN(value)) {
              sum += value;
            }
          }
        }

        return sum;
      };
      /**
       * Get median of data in one dimension
       */


      DataStore.prototype.getMedian = function (dim) {
        var dimDataArray = []; // map all data of one dimension

        this.each([dim], function (val) {
          if (!isNaN(val)) {
            dimDataArray.push(val);
          }
        }); // TODO
        // Use quick select?

        var sortedDimDataArray = dimDataArray.sort(function (a, b) {
          return a - b;
        });
        var len = this.count(); // calculate median

        return len === 0 ? 0 : len % 2 === 1 ? sortedDimDataArray[(len - 1) / 2] : (sortedDimDataArray[len / 2] + sortedDimDataArray[len / 2 - 1]) / 2;
      };
      /**
       * Retrieve the index with given raw data index.
       */


      DataStore.prototype.indexOfRawIndex = function (rawIndex) {
        if (rawIndex >= this._rawCount || rawIndex < 0) {
          return -1;
        }

        if (!this._indices) {
          return rawIndex;
        } // Indices are ascending


        var indices = this._indices; // If rawIndex === dataIndex

        var rawDataIndex = indices[rawIndex];

        if (rawDataIndex != null && rawDataIndex < this._count && rawDataIndex === rawIndex) {
          return rawIndex;
        }

        var left = 0;
        var right = this._count - 1;

        while (left <= right) {
          var mid = (left + right) / 2 | 0;

          if (indices[mid] < rawIndex) {
            left = mid + 1;
          } else if (indices[mid] > rawIndex) {
            right = mid - 1;
          } else {
            return mid;
          }
        }

        return -1;
      };
      /**
       * Retrieve the index of nearest value.
       * @param dim
       * @param value
       * @param [maxDistance=Infinity]
       * @return If and only if multiple indices have
       *         the same value, they are put to the result.
       */


      DataStore.prototype.indicesOfNearest = function (dim, value, maxDistance) {
        var chunks = this._chunks;
        var dimData = chunks[dim];
        var nearestIndices = [];

        if (!dimData) {
          return nearestIndices;
        }

        if (maxDistance == null) {
          maxDistance = Infinity;
        }

        var minDist = Infinity;
        var minDiff = -1;
        var nearestIndicesLen = 0; // Check the test case of `test/ut/spec/data/SeriesData.js`.

        for (var i = 0, len = this.count(); i < len; i++) {
          var dataIndex = this.getRawIndex(i);
          var diff = value - dimData[dataIndex];
          var dist = Math.abs(diff);

          if (dist <= maxDistance) {
            // When the `value` is at the middle of `this.get(dim, i)` and `this.get(dim, i+1)`,
            // we'd better not push both of them to `nearestIndices`, otherwise it is easy to
            // get more than one item in `nearestIndices` (more specifically, in `tooltip`).
            // So we chose the one that `diff >= 0` in this csae.
            // But if `this.get(dim, i)` and `this.get(dim, j)` get the same value, both of them
            // should be push to `nearestIndices`.
            if (dist < minDist || dist === minDist && diff >= 0 && minDiff < 0) {
              minDist = dist;
              minDiff = diff;
              nearestIndicesLen = 0;
            }

            if (diff === minDiff) {
              nearestIndices[nearestIndicesLen++] = i;
            }
          }
        }

        nearestIndices.length = nearestIndicesLen;
        return nearestIndices;
      };

      DataStore.prototype.getIndices = function () {
        var newIndices;
        var indices = this._indices;

        if (indices) {
          var Ctor = indices.constructor;
          var thisCount = this._count; // `new Array(a, b, c)` is different from `new Uint32Array(a, b, c)`.

          if (Ctor === Array) {
            newIndices = new Ctor(thisCount);

            for (var i = 0; i < thisCount; i++) {
              newIndices[i] = indices[i];
            }
          } else {
            newIndices = new Ctor(indices.buffer, 0, thisCount);
          }
        } else {
          var Ctor = getIndicesCtor(this._rawCount);
          newIndices = new Ctor(this.count());

          for (var i = 0; i < newIndices.length; i++) {
            newIndices[i] = i;
          }
        }

        return newIndices;
      };
      /**
       * Data filter.
       */


      DataStore.prototype.filter = function (dims, cb) {
        if (!this._count) {
          return this;
        }

        var newStore = this.clone();
        var count = newStore.count();
        var Ctor = getIndicesCtor(newStore._rawCount);
        var newIndices = new Ctor(count);
        var value = [];
        var dimSize = dims.length;
        var offset = 0;
        var dim0 = dims[0];
        var chunks = newStore._chunks;

        for (var i = 0; i < count; i++) {
          var keep = void 0;
          var rawIdx = newStore.getRawIndex(i); // Simple optimization

          if (dimSize === 0) {
            keep = cb(i);
          } else if (dimSize === 1) {
            var val = chunks[dim0][rawIdx];
            keep = cb(val, i);
          } else {
            var k = 0;

            for (; k < dimSize; k++) {
              value[k] = chunks[dims[k]][rawIdx];
            }

            value[k] = i;
            keep = cb.apply(null, value);
          }

          if (keep) {
            newIndices[offset++] = rawIdx;
          }
        } // Set indices after filtered.


        if (offset < count) {
          newStore._indices = newIndices;
        }

        newStore._count = offset; // Reset data extent

        newStore._extent = [];

        newStore._updateGetRawIdx();

        return newStore;
      };
      /**
       * Select data in range. (For optimization of filter)
       * (Manually inline code, support 5 million data filtering in data zoom.)
       */


      DataStore.prototype.selectRange = function (range) {
        var newStore = this.clone();
        var len = newStore._count;

        if (!len) {
          return this;
        }

        var dims = keys(range);
        var dimSize = dims.length;

        if (!dimSize) {
          return this;
        }

        var originalCount = newStore.count();
        var Ctor = getIndicesCtor(newStore._rawCount);
        var newIndices = new Ctor(originalCount);
        var offset = 0;
        var dim0 = dims[0];
        var min = range[dim0][0];
        var max = range[dim0][1];
        var storeArr = newStore._chunks;
        var quickFinished = false;

        if (!newStore._indices) {
          // Extreme optimization for common case. About 2x faster in chrome.
          var idx = 0;

          if (dimSize === 1) {
            var dimStorage = storeArr[dims[0]];

            for (var i = 0; i < len; i++) {
              var val = dimStorage[i]; // NaN will not be filtered. Consider the case, in line chart, empty
              // value indicates the line should be broken. But for the case like
              // scatter plot, a data item with empty value will not be rendered,
              // but the axis extent may be effected if some other dim of the data
              // item has value. Fortunately it is not a significant negative effect.

              if (val >= min && val <= max || isNaN(val)) {
                newIndices[offset++] = idx;
              }

              idx++;
            }

            quickFinished = true;
          } else if (dimSize === 2) {
            var dimStorage = storeArr[dims[0]];
            var dimStorage2 = storeArr[dims[1]];
            var min2 = range[dims[1]][0];
            var max2 = range[dims[1]][1];

            for (var i = 0; i < len; i++) {
              var val = dimStorage[i];
              var val2 = dimStorage2[i]; // Do not filter NaN, see comment above.

              if ((val >= min && val <= max || isNaN(val)) && (val2 >= min2 && val2 <= max2 || isNaN(val2))) {
                newIndices[offset++] = idx;
              }

              idx++;
            }

            quickFinished = true;
          }
        }

        if (!quickFinished) {
          if (dimSize === 1) {
            for (var i = 0; i < originalCount; i++) {
              var rawIndex = newStore.getRawIndex(i);
              var val = storeArr[dims[0]][rawIndex]; // Do not filter NaN, see comment above.

              if (val >= min && val <= max || isNaN(val)) {
                newIndices[offset++] = rawIndex;
              }
            }
          } else {
            for (var i = 0; i < originalCount; i++) {
              var keep = true;
              var rawIndex = newStore.getRawIndex(i);

              for (var k = 0; k < dimSize; k++) {
                var dimk = dims[k];
                var val = storeArr[dimk][rawIndex]; // Do not filter NaN, see comment above.

                if (val < range[dimk][0] || val > range[dimk][1]) {
                  keep = false;
                }
              }

              if (keep) {
                newIndices[offset++] = newStore.getRawIndex(i);
              }
            }
          }
        } // Set indices after filtered.


        if (offset < originalCount) {
          newStore._indices = newIndices;
        }

        newStore._count = offset; // Reset data extent

        newStore._extent = [];

        newStore._updateGetRawIdx();

        return newStore;
      }; // /**
      //  * Data mapping to a plain array
      //  */
      // mapArray(dims: DimensionIndex[], cb: MapArrayCb): any[] {
      //     const result: any[] = [];
      //     this.each(dims, function () {
      //         result.push(cb && (cb as MapArrayCb).apply(null, arguments));
      //     });
      //     return result;
      // }

      /**
       * Data mapping to a new List with given dimensions
       */


      DataStore.prototype.map = function (dims, cb) {
        // TODO only clone picked chunks.
        var target = this.clone(dims);

        this._updateDims(target, dims, cb);

        return target;
      };
      /**
       * @caution Danger!! Only used in dataStack.
       */


      DataStore.prototype.modify = function (dims, cb) {
        this._updateDims(this, dims, cb);
      };

      DataStore.prototype._updateDims = function (target, dims, cb) {
        var targetChunks = target._chunks;
        var tmpRetValue = [];
        var dimSize = dims.length;
        var dataCount = target.count();
        var values = [];
        var rawExtent = target._rawExtent;

        for (var i = 0; i < dims.length; i++) {
          rawExtent[dims[i]] = getInitialExtent();
        }

        for (var dataIndex = 0; dataIndex < dataCount; dataIndex++) {
          var rawIndex = target.getRawIndex(dataIndex);

          for (var k = 0; k < dimSize; k++) {
            values[k] = targetChunks[dims[k]][rawIndex];
          }

          values[dimSize] = dataIndex;
          var retValue = cb && cb.apply(null, values);

          if (retValue != null) {
            // a number or string (in oridinal dimension)?
            if (typeof retValue !== 'object') {
              tmpRetValue[0] = retValue;
              retValue = tmpRetValue;
            }

            for (var i = 0; i < retValue.length; i++) {
              var dim = dims[i];
              var val = retValue[i];
              var rawExtentOnDim = rawExtent[dim];
              var dimStore = targetChunks[dim];

              if (dimStore) {
                dimStore[rawIndex] = val;
              }

              if (val < rawExtentOnDim[0]) {
                rawExtentOnDim[0] = val;
              }

              if (val > rawExtentOnDim[1]) {
                rawExtentOnDim[1] = val;
              }
            }
          }
        }
      };
      /**
       * Large data down sampling using largest-triangle-three-buckets
       * @param {string} valueDimension
       * @param {number} targetCount
       */


      DataStore.prototype.lttbDownSample = function (valueDimension, rate) {
        var target = this.clone([valueDimension], true);
        var targetStorage = target._chunks;
        var dimStore = targetStorage[valueDimension];
        var len = this.count();
        var sampledIndex = 0;
        var frameSize = Math.floor(1 / rate);
        var currentRawIndex = this.getRawIndex(0);
        var maxArea;
        var area;
        var nextRawIndex;
        var newIndices = new (getIndicesCtor(this._rawCount))(Math.min((Math.ceil(len / frameSize) + 2) * 2, len)); // First frame use the first data.

        newIndices[sampledIndex++] = currentRawIndex;

        for (var i = 1; i < len - 1; i += frameSize) {
          var nextFrameStart = Math.min(i + frameSize, len - 1);
          var nextFrameEnd = Math.min(i + frameSize * 2, len);
          var avgX = (nextFrameEnd + nextFrameStart) / 2;
          var avgY = 0;

          for (var idx = nextFrameStart; idx < nextFrameEnd; idx++) {
            var rawIndex = this.getRawIndex(idx);
            var y = dimStore[rawIndex];

            if (isNaN(y)) {
              continue;
            }

            avgY += y;
          }

          avgY /= nextFrameEnd - nextFrameStart;
          var frameStart = i;
          var frameEnd = Math.min(i + frameSize, len);
          var pointAX = i - 1;
          var pointAY = dimStore[currentRawIndex];
          maxArea = -1;
          nextRawIndex = frameStart;
          var firstNaNIndex = -1;
          var countNaN = 0; // Find a point from current frame that construct a triangel with largest area with previous selected point
          // And the average of next frame.

          for (var idx = frameStart; idx < frameEnd; idx++) {
            var rawIndex = this.getRawIndex(idx);
            var y = dimStore[rawIndex];

            if (isNaN(y)) {
              countNaN++;

              if (firstNaNIndex < 0) {
                firstNaNIndex = rawIndex;
              }

              continue;
            } // Calculate triangle area over three buckets


            area = Math.abs((pointAX - avgX) * (y - pointAY) - (pointAX - idx) * (avgY - pointAY));

            if (area > maxArea) {
              maxArea = area;
              nextRawIndex = rawIndex; // Next a is this b
            }
          }

          if (countNaN > 0 && countNaN < frameEnd - frameStart) {
            // Append first NaN point in every bucket.
            // It is necessary to ensure the correct order of indices.
            newIndices[sampledIndex++] = Math.min(firstNaNIndex, nextRawIndex);
            nextRawIndex = Math.max(firstNaNIndex, nextRawIndex);
          }

          newIndices[sampledIndex++] = nextRawIndex;
          currentRawIndex = nextRawIndex; // This a is the next a (chosen b)
        } // First frame use the last data.


        newIndices[sampledIndex++] = this.getRawIndex(len - 1);
        target._count = sampledIndex;
        target._indices = newIndices;
        target.getRawIndex = this._getRawIdx;
        return target;
      };
      /**
       * Large data down sampling on given dimension
       * @param sampleIndex Sample index for name and id
       */


      DataStore.prototype.downSample = function (dimension, rate, sampleValue, sampleIndex) {
        var target = this.clone([dimension], true);
        var targetStorage = target._chunks;
        var frameValues = [];
        var frameSize = Math.floor(1 / rate);
        var dimStore = targetStorage[dimension];
        var len = this.count();
        var rawExtentOnDim = target._rawExtent[dimension] = getInitialExtent();
        var newIndices = new (getIndicesCtor(this._rawCount))(Math.ceil(len / frameSize));
        var offset = 0;

        for (var i = 0; i < len; i += frameSize) {
          // Last frame
          if (frameSize > len - i) {
            frameSize = len - i;
            frameValues.length = frameSize;
          }

          for (var k = 0; k < frameSize; k++) {
            var dataIdx = this.getRawIndex(i + k);
            frameValues[k] = dimStore[dataIdx];
          }

          var value = sampleValue(frameValues);
          var sampleFrameIdx = this.getRawIndex(Math.min(i + sampleIndex(frameValues, value) || 0, len - 1)); // Only write value on the filtered data

          dimStore[sampleFrameIdx] = value;

          if (value < rawExtentOnDim[0]) {
            rawExtentOnDim[0] = value;
          }

          if (value > rawExtentOnDim[1]) {
            rawExtentOnDim[1] = value;
          }

          newIndices[offset++] = sampleFrameIdx;
        }

        target._count = offset;
        target._indices = newIndices;

        target._updateGetRawIdx();

        return target;
      };
      /**
       * Data iteration
       * @param ctx default this
       * @example
       *  list.each('x', function (x, idx) {});
       *  list.each(['x', 'y'], function (x, y, idx) {});
       *  list.each(function (idx) {})
       */


      DataStore.prototype.each = function (dims, cb) {
        if (!this._count) {
          return;
        }

        var dimSize = dims.length;
        var chunks = this._chunks;

        for (var i = 0, len = this.count(); i < len; i++) {
          var rawIdx = this.getRawIndex(i); // Simple optimization

          switch (dimSize) {
            case 0:
              cb(i);
              break;

            case 1:
              cb(chunks[dims[0]][rawIdx], i);
              break;

            case 2:
              cb(chunks[dims[0]][rawIdx], chunks[dims[1]][rawIdx], i);
              break;

            default:
              var k = 0;
              var value = [];

              for (; k < dimSize; k++) {
                value[k] = chunks[dims[k]][rawIdx];
              } // Index


              value[k] = i;
              cb.apply(null, value);
          }
        }
      };
      /**
       * Get extent of data in one dimension
       */


      DataStore.prototype.getDataExtent = function (dim) {
        // Make sure use concrete dim as cache name.
        var dimData = this._chunks[dim];
        var initialExtent = getInitialExtent();

        if (!dimData) {
          return initialExtent;
        } // Make more strict checkings to ensure hitting cache.


        var currEnd = this.count(); // Consider the most cases when using data zoom, `getDataExtent`
        // happened before filtering. We cache raw extent, which is not
        // necessary to be cleared and recalculated when restore data.

        var useRaw = !this._indices;
        var dimExtent;

        if (useRaw) {
          return this._rawExtent[dim].slice();
        }

        dimExtent = this._extent[dim];

        if (dimExtent) {
          return dimExtent.slice();
        }

        dimExtent = initialExtent;
        var min = dimExtent[0];
        var max = dimExtent[1];

        for (var i = 0; i < currEnd; i++) {
          var rawIdx = this.getRawIndex(i);
          var value = dimData[rawIdx];
          value < min && (min = value);
          value > max && (max = value);
        }

        dimExtent = [min, max];
        this._extent[dim] = dimExtent;
        return dimExtent;
      };
      /**
       * Get raw data item
       */


      DataStore.prototype.getRawDataItem = function (idx) {
        var rawIdx = this.getRawIndex(idx);

        if (!this._provider.persistent) {
          var val = [];
          var chunks = this._chunks;

          for (var i = 0; i < chunks.length; i++) {
            val.push(chunks[i][rawIdx]);
          }

          return val;
        } else {
          return this._provider.getItem(rawIdx);
        }
      };
      /**
       * Clone shallow.
       *
       * @param clonedDims Determine which dims to clone. Will share the data if not specified.
       */


      DataStore.prototype.clone = function (clonedDims, ignoreIndices) {
        var target = new DataStore();
        var chunks = this._chunks;
        var clonedDimsMap = clonedDims && reduce(clonedDims, function (obj, dimIdx) {
          obj[dimIdx] = true;
          return obj;
        }, {});

        if (clonedDimsMap) {
          for (var i = 0; i < chunks.length; i++) {
            // Not clone if dim is not picked.
            target._chunks[i] = !clonedDimsMap[i] ? chunks[i] : cloneChunk(chunks[i]);
          }
        } else {
          target._chunks = chunks;
        }

        this._copyCommonProps(target);

        if (!ignoreIndices) {
          target._indices = this._cloneIndices();
        }

        target._updateGetRawIdx();

        return target;
      };

      DataStore.prototype._copyCommonProps = function (target) {
        target._count = this._count;
        target._rawCount = this._rawCount;
        target._provider = this._provider;
        target._dimensions = this._dimensions;
        target._extent = clone(this._extent);
        target._rawExtent = clone(this._rawExtent);
      };

      DataStore.prototype._cloneIndices = function () {
        if (this._indices) {
          var Ctor = this._indices.constructor;
          var indices = void 0;

          if (Ctor === Array) {
            var thisCount = this._indices.length;
            indices = new Ctor(thisCount);

            for (var i = 0; i < thisCount; i++) {
              indices[i] = this._indices[i];
            }
          } else {
            indices = new Ctor(this._indices);
          }

          return indices;
        }

        return null;
      };

      DataStore.prototype._getRawIdxIdentity = function (idx) {
        return idx;
      };

      DataStore.prototype._getRawIdx = function (idx) {
        if (idx < this._count && idx >= 0) {
          return this._indices[idx];
        }

        return -1;
      };

      DataStore.prototype._updateGetRawIdx = function () {
        this.getRawIndex = this._indices ? this._getRawIdx : this._getRawIdxIdentity;
      };

      DataStore.internalField = function () {
        function getDimValueSimply(dataItem, property, dataIndex, dimIndex) {
          return parseDataValue(dataItem[dimIndex], this._dimensions[dimIndex]);
        }

        defaultDimValueGetters = {
          arrayRows: getDimValueSimply,
          objectRows: function (dataItem, property, dataIndex, dimIndex) {
            return parseDataValue(dataItem[property], this._dimensions[dimIndex]);
          },
          keyedColumns: getDimValueSimply,
          original: function (dataItem, property, dataIndex, dimIndex) {
            // Performance sensitive, do not use modelUtil.getDataItemValue.
            // If dataItem is an plain object with no value field, the let `value`
            // will be assigned with the object, but it will be tread correctly
            // in the `convertValue`.
            var value = dataItem && (dataItem.value == null ? dataItem : dataItem.value);
            return parseDataValue(value instanceof Array ? value[dimIndex] // If value is a single number or something else not array.
            : value, this._dimensions[dimIndex]);
          },
          typedArray: function (dataItem, property, dataIndex, dimIndex) {
            return dataItem[dimIndex];
          }
        };
      }();

      return DataStore;
    }();

    /**
     * [REQUIREMENT_MEMO]:
     * (0) `metaRawOption` means `dimensions`/`sourceHeader`/`seriesLayoutBy` in raw option.
     * (1) Keep support the feature: `metaRawOption` can be specified both on `series` and
     * `root-dataset`. Them on `series` has higher priority.
     * (2) Do not support to set `metaRawOption` on a `non-root-dataset`, because it might
     * confuse users: whether those props indicate how to visit the upstream source or visit
     * the transform result source, and some transforms has nothing to do with these props,
     * and some transforms might have multiple upstream.
     * (3) Transforms should specify `metaRawOption` in each output, just like they can be
     * declared in `root-dataset`.
     * (4) At present only support visit source in `SERIES_LAYOUT_BY_COLUMN` in transforms.
     * That is for reducing complexity in transforms.
     * PENDING: Whether to provide transposition transform?
     *
     * [IMPLEMENTAION_MEMO]:
     * "sourceVisitConfig" are calculated from `metaRawOption` and `data`.
     * They will not be calculated until `source` is about to be visited (to prevent from
     * duplicate calcuation). `source` is visited only in series and input to transforms.
     *
     * [DIMENSION_INHERIT_RULE]:
     * By default the dimensions are inherited from ancestors, unless a transform return
     * a new dimensions definition.
     * Consider the case:
     * ```js
     * dataset: [{
     *     source: [ ['Product', 'Sales', 'Prise'], ['Cookies', 321, 44.21], ...]
     * }, {
     *     transform: { type: 'filter', ... }
     * }]
     * dataset: [{
     *     dimension: ['Product', 'Sales', 'Prise'],
     *     source: [ ['Cookies', 321, 44.21], ...]
     * }, {
     *     transform: { type: 'filter', ... }
     * }]
     * ```
     * The two types of option should have the same behavior after transform.
     *
     *
     * [SCENARIO]:
     * (1) Provide source data directly:
     * ```js
     * series: {
     *     encode: {...},
     *     dimensions: [...]
     *     seriesLayoutBy: 'row',
     *     data: [[...]]
     * }
     * ```
     * (2) Series refer to dataset.
     * ```js
     * series: [{
     *     encode: {...}
     *     // Ignore datasetIndex means `datasetIndex: 0`
     *     // and the dimensions defination in dataset is used
     * }, {
     *     encode: {...},
     *     seriesLayoutBy: 'column',
     *     datasetIndex: 1
     * }]
     * ```
     * (3) dataset transform
     * ```js
     * dataset: [{
     *     source: [...]
     * }, {
     *     source: [...]
     * }, {
     *     // By default from 0.
     *     transform: { type: 'filter', config: {...} }
     * }, {
     *     // Piped.
     *     transform: [
     *         { type: 'filter', config: {...} },
     *         { type: 'sort', config: {...} }
     *     ]
     * }, {
     *     id: 'regressionData',
     *     fromDatasetIndex: 1,
     *     // Third-party transform
     *     transform: { type: 'ecStat:regression', config: {...} }
     * }, {
     *     // retrieve the extra result.
     *     id: 'regressionFormula',
     *     fromDatasetId: 'regressionData',
     *     fromTransformResult: 1
     * }]
     * ```
     */

    var SourceManager =
    /** @class */
    function () {
      function SourceManager(sourceHost) {
        // Cached source. Do not repeat calculating if not dirty.
        this._sourceList = [];
        this._storeList = []; // version sign of each upstream source manager.

        this._upstreamSignList = [];
        this._versionSignBase = 0;
        this._dirty = true;
        this._sourceHost = sourceHost;
      }
      /**
       * Mark dirty.
       */


      SourceManager.prototype.dirty = function () {
        this._setLocalSource([], []);

        this._storeList = [];
        this._dirty = true;
      };

      SourceManager.prototype._setLocalSource = function (sourceList, upstreamSignList) {
        this._sourceList = sourceList;
        this._upstreamSignList = upstreamSignList;
        this._versionSignBase++;

        if (this._versionSignBase > 9e10) {
          this._versionSignBase = 0;
        }
      };
      /**
       * For detecting whether the upstream source is dirty, so that
       * the local cached source (in `_sourceList`) should be discarded.
       */


      SourceManager.prototype._getVersionSign = function () {
        return this._sourceHost.uid + '_' + this._versionSignBase;
      };
      /**
       * Always return a source instance. Otherwise throw error.
       */


      SourceManager.prototype.prepareSource = function () {
        // For the case that call `setOption` multiple time but no data changed,
        // cache the result source to prevent from repeating transform.
        if (this._isDirty()) {
          this._createSource();

          this._dirty = false;
        }
      };

      SourceManager.prototype._createSource = function () {
        this._setLocalSource([], []);

        var sourceHost = this._sourceHost;

        var upSourceMgrList = this._getUpstreamSourceManagers();

        var hasUpstream = !!upSourceMgrList.length;
        var resultSourceList;
        var upstreamSignList;

        if (isSeries(sourceHost)) {
          var seriesModel = sourceHost;
          var data = void 0;
          var sourceFormat = void 0;
          var upSource = void 0; // Has upstream dataset

          if (hasUpstream) {
            var upSourceMgr = upSourceMgrList[0];
            upSourceMgr.prepareSource();
            upSource = upSourceMgr.getSource();
            data = upSource.data;
            sourceFormat = upSource.sourceFormat;
            upstreamSignList = [upSourceMgr._getVersionSign()];
          } // Series data is from own.
          else {
              data = seriesModel.get('data', true);
              sourceFormat = isTypedArray(data) ? SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL;
              upstreamSignList = [];
            } // See [REQUIREMENT_MEMO], merge settings on series and parent dataset if it is root.


          var newMetaRawOption = this._getSourceMetaRawOption() || {};
          var upMetaRawOption = upSource && upSource.metaRawOption || {};
          var seriesLayoutBy = retrieve2(newMetaRawOption.seriesLayoutBy, upMetaRawOption.seriesLayoutBy) || null;
          var sourceHeader = retrieve2(newMetaRawOption.sourceHeader, upMetaRawOption.sourceHeader); // Note here we should not use `upSource.dimensionsDefine`. Consider the case:
          // `upSource.dimensionsDefine` is detected by `seriesLayoutBy: 'column'`,
          // but series need `seriesLayoutBy: 'row'`.

          var dimensions = retrieve2(newMetaRawOption.dimensions, upMetaRawOption.dimensions); // We share source with dataset as much as possible
          // to avoid extra memory cost of high dimensional data.

          var needsCreateSource = seriesLayoutBy !== upMetaRawOption.seriesLayoutBy || !!sourceHeader !== !!upMetaRawOption.sourceHeader || dimensions;
          resultSourceList = needsCreateSource ? [createSource(data, {
            seriesLayoutBy: seriesLayoutBy,
            sourceHeader: sourceHeader,
            dimensions: dimensions
          }, sourceFormat)] : [];
        } else {
          var datasetModel = sourceHost; // Has upstream dataset.

          if (hasUpstream) {
            var result = this._applyTransform(upSourceMgrList);

            resultSourceList = result.sourceList;
            upstreamSignList = result.upstreamSignList;
          } // Is root dataset.
          else {
              var sourceData = datasetModel.get('source', true);
              resultSourceList = [createSource(sourceData, this._getSourceMetaRawOption(), null)];
              upstreamSignList = [];
            }
        }

        if ("development" !== 'production') {
          assert(resultSourceList && upstreamSignList);
        }

        this._setLocalSource(resultSourceList, upstreamSignList);
      };

      SourceManager.prototype._applyTransform = function (upMgrList) {
        var datasetModel = this._sourceHost;
        var transformOption = datasetModel.get('transform', true);
        var fromTransformResult = datasetModel.get('fromTransformResult', true);

        if ("development" !== 'production') {
          assert(fromTransformResult != null || transformOption != null);
        }

        if (fromTransformResult != null) {
          var errMsg = '';

          if (upMgrList.length !== 1) {
            if ("development" !== 'production') {
              errMsg = 'When using `fromTransformResult`, there should be only one upstream dataset';
            }

            doThrow(errMsg);
          }
        }

        var sourceList;
        var upSourceList = [];
        var upstreamSignList = [];
        each(upMgrList, function (upMgr) {
          upMgr.prepareSource();
          var upSource = upMgr.getSource(fromTransformResult || 0);
          var errMsg = '';

          if (fromTransformResult != null && !upSource) {
            if ("development" !== 'production') {
              errMsg = 'Can not retrieve result by `fromTransformResult`: ' + fromTransformResult;
            }

            doThrow(errMsg);
          }

          upSourceList.push(upSource);
          upstreamSignList.push(upMgr._getVersionSign());
        });

        if (transformOption) {
          sourceList = applyDataTransform(transformOption, upSourceList, {
            datasetIndex: datasetModel.componentIndex
          });
        } else if (fromTransformResult != null) {
          sourceList = [cloneSourceShallow(upSourceList[0])];
        }

        return {
          sourceList: sourceList,
          upstreamSignList: upstreamSignList
        };
      };

      SourceManager.prototype._isDirty = function () {
        if (this._dirty) {
          return true;
        } // All sourceList is from the some upstream.


        var upSourceMgrList = this._getUpstreamSourceManagers();

        for (var i = 0; i < upSourceMgrList.length; i++) {
          var upSrcMgr = upSourceMgrList[i];

          if ( // Consider the case that there is ancestor diry, call it recursively.
          // The performance is probably not an issue because usually the chain is not long.
          upSrcMgr._isDirty() || this._upstreamSignList[i] !== upSrcMgr._getVersionSign()) {
            return true;
          }
        }
      };
      /**
       * @param sourceIndex By default 0, means "main source".
       *                    In most cases there is only one source.
       */


      SourceManager.prototype.getSource = function (sourceIndex) {
        sourceIndex = sourceIndex || 0;
        var source = this._sourceList[sourceIndex];

        if (!source) {
          // Series may share source instance with dataset.
          var upSourceMgrList = this._getUpstreamSourceManagers();

          return upSourceMgrList[0] && upSourceMgrList[0].getSource(sourceIndex);
        }

        return source;
      };
      /**
       *
       * Get a data store which can be shared across series.
       * Only available for series.
       *
       * @param seriesDimRequest Dimensions that are generated in series.
       *        Should have been sorted by `storeDimIndex` asc.
       */


      SourceManager.prototype.getSharedDataStore = function (seriesDimRequest) {
        if ("development" !== 'production') {
          assert(isSeries(this._sourceHost), 'Can only call getDataStore on series source manager.');
        }

        var schema = seriesDimRequest.makeStoreSchema();
        return this._innerGetDataStore(schema.dimensions, seriesDimRequest.source, schema.hash);
      };

      SourceManager.prototype._innerGetDataStore = function (storeDims, seriesSource, sourceReadKey) {
        // TODO Can use other sourceIndex?
        var sourceIndex = 0;
        var storeList = this._storeList;
        var cachedStoreMap = storeList[sourceIndex];

        if (!cachedStoreMap) {
          cachedStoreMap = storeList[sourceIndex] = {};
        }

        var cachedStore = cachedStoreMap[sourceReadKey];

        if (!cachedStore) {
          var upSourceMgr = this._getUpstreamSourceManagers()[0];

          if (isSeries(this._sourceHost) && upSourceMgr) {
            cachedStore = upSourceMgr._innerGetDataStore(storeDims, seriesSource, sourceReadKey);
          } else {
            cachedStore = new DataStore(); // Always create store from source of series.

            cachedStore.initData(new DefaultDataProvider(seriesSource, storeDims.length), storeDims);
          }

          cachedStoreMap[sourceReadKey] = cachedStore;
        }

        return cachedStore;
      };
      /**
       * PENDING: Is it fast enough?
       * If no upstream, return empty array.
       */


      SourceManager.prototype._getUpstreamSourceManagers = function () {
        // Always get the relationship from the raw option.
        // Do not cache the link of the dependency graph, so that
        // there is no need to update them when change happens.
        var sourceHost = this._sourceHost;

        if (isSeries(sourceHost)) {
          var datasetModel = querySeriesUpstreamDatasetModel(sourceHost);
          return !datasetModel ? [] : [datasetModel.getSourceManager()];
        } else {
          return map(queryDatasetUpstreamDatasetModels(sourceHost), function (datasetModel) {
            return datasetModel.getSourceManager();
          });
        }
      };

      SourceManager.prototype._getSourceMetaRawOption = function () {
        var sourceHost = this._sourceHost;
        var seriesLayoutBy;
        var sourceHeader;
        var dimensions;

        if (isSeries(sourceHost)) {
          seriesLayoutBy = sourceHost.get('seriesLayoutBy', true);
          sourceHeader = sourceHost.get('sourceHeader', true);
          dimensions = sourceHost.get('dimensions', true);
        } // See [REQUIREMENT_MEMO], `non-root-dataset` do not support them.
        else if (!this._getUpstreamSourceManagers().length) {
            var model = sourceHost;
            seriesLayoutBy = model.get('seriesLayoutBy', true);
            sourceHeader = model.get('sourceHeader', true);
            dimensions = model.get('dimensions', true);
          }

        return {
          seriesLayoutBy: seriesLayoutBy,
          sourceHeader: sourceHeader,
          dimensions: dimensions
        };
      };

      return SourceManager;
    }();
    // disable the transform merge, but do not disable transform clone from rawOption.

    function disableTransformOptionMerge(datasetModel) {
      var transformOption = datasetModel.option.transform;
      transformOption && setAsPrimitive(datasetModel.option.transform);
    }

    function isSeries(sourceHost) {
      // Avoid circular dependency with Series.ts
      return sourceHost.mainType === 'series';
    }

    function doThrow(errMsg) {
      throw new Error(errMsg);
    }

    var TOOLTIP_LINE_HEIGHT_CSS = 'line-height:1'; // TODO: more textStyle option

    function getTooltipTextStyle(textStyle, renderMode) {
      var nameFontColor = textStyle.color || '#6e7079';
      var nameFontSize = textStyle.fontSize || 12;
      var nameFontWeight = textStyle.fontWeight || '400';
      var valueFontColor = textStyle.color || '#464646';
      var valueFontSize = textStyle.fontSize || 14;
      var valueFontWeight = textStyle.fontWeight || '900';

      if (renderMode === 'html') {
        // `textStyle` is probably from user input, should be encoded to reduce security risk.
        return {
          // eslint-disable-next-line max-len
          nameStyle: "font-size:" + encodeHTML(nameFontSize + '') + "px;color:" + encodeHTML(nameFontColor) + ";font-weight:" + encodeHTML(nameFontWeight + ''),
          // eslint-disable-next-line max-len
          valueStyle: "font-size:" + encodeHTML(valueFontSize + '') + "px;color:" + encodeHTML(valueFontColor) + ";font-weight:" + encodeHTML(valueFontWeight + '')
        };
      } else {
        return {
          nameStyle: {
            fontSize: nameFontSize,
            fill: nameFontColor,
            fontWeight: nameFontWeight
          },
          valueStyle: {
            fontSize: valueFontSize,
            fill: valueFontColor,
            fontWeight: valueFontWeight
          }
        };
      }
    } // See `TooltipMarkupLayoutIntent['innerGapLevel']`.
    // (value from UI design)


    var HTML_GAPS = [0, 10, 20, 30];
    var RICH_TEXT_GAPS = ['', '\n', '\n\n', '\n\n\n']; // eslint-disable-next-line max-len

    function createTooltipMarkup(type, option) {
      option.type = type;
      return option;
    }

    function isSectionFragment(frag) {
      return frag.type === 'section';
    }

    function getBuilder(frag) {
      return isSectionFragment(frag) ? buildSection : buildNameValue;
    }

    function getBlockGapLevel(frag) {
      if (isSectionFragment(frag)) {
        var gapLevel_1 = 0;
        var subBlockLen = frag.blocks.length;
        var hasInnerGap_1 = subBlockLen > 1 || subBlockLen > 0 && !frag.noHeader;
        each(frag.blocks, function (subBlock) {
          var subGapLevel = getBlockGapLevel(subBlock); // If the some of the sub-blocks have some gaps (like 10px) inside, this block
          // should use a larger gap (like 20px) to distinguish those sub-blocks.

          if (subGapLevel >= gapLevel_1) {
            gapLevel_1 = subGapLevel + +(hasInnerGap_1 && ( // 0 always can not be readable gap level.
            !subGapLevel // If no header, always keep the sub gap level. Otherwise
            // look weird in case `multipleSeries`.
            || isSectionFragment(subBlock) && !subBlock.noHeader));
          }
        });
        return gapLevel_1;
      }

      return 0;
    }

    function buildSection(ctx, fragment, topMarginForOuterGap, toolTipTextStyle) {
      var noHeader = fragment.noHeader;
      var gaps = getGap(getBlockGapLevel(fragment));
      var subMarkupTextList = [];
      var subBlocks = fragment.blocks || [];
      assert(!subBlocks || isArray(subBlocks));
      subBlocks = subBlocks || [];
      var orderMode = ctx.orderMode;

      if (fragment.sortBlocks && orderMode) {
        subBlocks = subBlocks.slice();
        var orderMap = {
          valueAsc: 'asc',
          valueDesc: 'desc'
        };

        if (hasOwn(orderMap, orderMode)) {
          var comparator_1 = new SortOrderComparator(orderMap[orderMode], null);
          subBlocks.sort(function (a, b) {
            return comparator_1.evaluate(a.sortParam, b.sortParam);
          });
        } // FIXME 'seriesDesc' necessary?
        else if (orderMode === 'seriesDesc') {
            subBlocks.reverse();
          }
      }

      each(subBlocks, function (subBlock, idx) {
        var valueFormatter = fragment.valueFormatter;
        var subMarkupText = getBuilder(subBlock)( // Inherit valueFormatter
        valueFormatter ? extend(extend({}, ctx), {
          valueFormatter: valueFormatter
        }) : ctx, subBlock, idx > 0 ? gaps.html : 0, toolTipTextStyle);
        subMarkupText != null && subMarkupTextList.push(subMarkupText);
      });
      var subMarkupText = ctx.renderMode === 'richText' ? subMarkupTextList.join(gaps.richText) : wrapBlockHTML(subMarkupTextList.join(''), noHeader ? topMarginForOuterGap : gaps.html);

      if (noHeader) {
        return subMarkupText;
      }

      var displayableHeader = makeValueReadable(fragment.header, 'ordinal', ctx.useUTC);
      var nameStyle = getTooltipTextStyle(toolTipTextStyle, ctx.renderMode).nameStyle;

      if (ctx.renderMode === 'richText') {
        return wrapInlineNameRichText(ctx, displayableHeader, nameStyle) + gaps.richText + subMarkupText;
      } else {
        return wrapBlockHTML("<div style=\"" + nameStyle + ";" + TOOLTIP_LINE_HEIGHT_CSS + ";\">" + encodeHTML(displayableHeader) + '</div>' + subMarkupText, topMarginForOuterGap);
      }
    }

    function buildNameValue(ctx, fragment, topMarginForOuterGap, toolTipTextStyle) {
      var renderMode = ctx.renderMode;
      var noName = fragment.noName;
      var noValue = fragment.noValue;
      var noMarker = !fragment.markerType;
      var name = fragment.name;
      var useUTC = ctx.useUTC;

      var valueFormatter = fragment.valueFormatter || ctx.valueFormatter || function (value) {
        value = isArray(value) ? value : [value];
        return map(value, function (val, idx) {
          return makeValueReadable(val, isArray(valueTypeOption) ? valueTypeOption[idx] : valueTypeOption, useUTC);
        });
      };

      if (noName && noValue) {
        return;
      }

      var markerStr = noMarker ? '' : ctx.markupStyleCreator.makeTooltipMarker(fragment.markerType, fragment.markerColor || '#333', renderMode);
      var readableName = noName ? '' : makeValueReadable(name, 'ordinal', useUTC);
      var valueTypeOption = fragment.valueType;
      var readableValueList = noValue ? [] : valueFormatter(fragment.value);
      var valueAlignRight = !noMarker || !noName; // It little weird if only value next to marker but far from marker.

      var valueCloseToMarker = !noMarker && noName;

      var _a = getTooltipTextStyle(toolTipTextStyle, renderMode),
          nameStyle = _a.nameStyle,
          valueStyle = _a.valueStyle;

      return renderMode === 'richText' ? (noMarker ? '' : markerStr) + (noName ? '' : wrapInlineNameRichText(ctx, readableName, nameStyle)) // Value has commas inside, so use ' ' as delimiter for multiple values.
      + (noValue ? '' : wrapInlineValueRichText(ctx, readableValueList, valueAlignRight, valueCloseToMarker, valueStyle)) : wrapBlockHTML((noMarker ? '' : markerStr) + (noName ? '' : wrapInlineNameHTML(readableName, !noMarker, nameStyle)) + (noValue ? '' : wrapInlineValueHTML(readableValueList, valueAlignRight, valueCloseToMarker, valueStyle)), topMarginForOuterGap);
    }
    /**
     * @return markupText. null/undefined means no content.
     */


    function buildTooltipMarkup(fragment, markupStyleCreator, renderMode, orderMode, useUTC, toolTipTextStyle) {
      if (!fragment) {
        return;
      }

      var builder = getBuilder(fragment);
      var ctx = {
        useUTC: useUTC,
        renderMode: renderMode,
        orderMode: orderMode,
        markupStyleCreator: markupStyleCreator,
        valueFormatter: fragment.valueFormatter
      };
      return builder(ctx, fragment, 0, toolTipTextStyle);
    }

    function getGap(gapLevel) {
      return {
        html: HTML_GAPS[gapLevel],
        richText: RICH_TEXT_GAPS[gapLevel]
      };
    }

    function wrapBlockHTML(encodedContent, topGap) {
      var clearfix = '<div style="clear:both"></div>';
      var marginCSS = "margin: " + topGap + "px 0 0";
      return "<div style=\"" + marginCSS + ";" + TOOLTIP_LINE_HEIGHT_CSS + ";\">" + encodedContent + clearfix + '</div>';
    }

    function wrapInlineNameHTML(name, leftHasMarker, style) {
      var marginCss = leftHasMarker ? 'margin-left:2px' : '';
      return "<span style=\"" + style + ";" + marginCss + "\">" + encodeHTML(name) + '</span>';
    }

    function wrapInlineValueHTML(valueList, alignRight, valueCloseToMarker, style) {
      // Do not too close to marker, considering there are multiple values separated by spaces.
      var paddingStr = valueCloseToMarker ? '10px' : '20px';
      var alignCSS = alignRight ? "float:right;margin-left:" + paddingStr : '';
      valueList = isArray(valueList) ? valueList : [valueList];
      return "<span style=\"" + alignCSS + ";" + style + "\">" // Value has commas inside, so use '  ' as delimiter for multiple values.
      + map(valueList, function (value) {
        return encodeHTML(value);
      }).join('&nbsp;&nbsp;') + '</span>';
    }

    function wrapInlineNameRichText(ctx, name, style) {
      return ctx.markupStyleCreator.wrapRichTextStyle(name, style);
    }

    function wrapInlineValueRichText(ctx, values, alignRight, valueCloseToMarker, style) {
      var styles = [style];
      var paddingLeft = valueCloseToMarker ? 10 : 20;
      alignRight && styles.push({
        padding: [0, 0, 0, paddingLeft],
        align: 'right'
      }); // Value has commas inside, so use '  ' as delimiter for multiple values.

      return ctx.markupStyleCreator.wrapRichTextStyle(isArray(values) ? values.join('  ') : values, styles);
    }

    function retrieveVisualColorForTooltipMarker(series, dataIndex) {
      var style = series.getData().getItemVisual(dataIndex, 'style');
      var color = style[series.visualDrawType];
      return convertToColorString(color);
    }
    function getPaddingFromTooltipModel(model, renderMode) {
      var padding = model.get('padding');
      return padding != null ? padding // We give slightly different to look pretty.
      : renderMode === 'richText' ? [8, 10] : 10;
    }
    /**
     * The major feature is generate styles for `renderMode: 'richText'`.
     * But it also serves `renderMode: 'html'` to provide
     * "renderMode-independent" API.
     */

    var TooltipMarkupStyleCreator =
    /** @class */
    function () {
      function TooltipMarkupStyleCreator() {
        this.richTextStyles = {}; // Notice that "generate a style name" usuall happens repeatly when mouse moving and
        // displaying a tooltip. So we put the `_nextStyleNameId` as a member of each creator
        // rather than static shared by all creators (which will cause it increase to fast).

        this._nextStyleNameId = getRandomIdBase();
      }

      TooltipMarkupStyleCreator.prototype._generateStyleName = function () {
        return '__EC_aUTo_' + this._nextStyleNameId++;
      };

      TooltipMarkupStyleCreator.prototype.makeTooltipMarker = function (markerType, colorStr, renderMode) {
        var markerId = renderMode === 'richText' ? this._generateStyleName() : null;
        var marker = getTooltipMarker({
          color: colorStr,
          type: markerType,
          renderMode: renderMode,
          markerId: markerId
        });

        if (isString(marker)) {
          return marker;
        } else {
          if ("development" !== 'production') {
            assert(markerId);
          }

          this.richTextStyles[markerId] = marker.style;
          return marker.content;
        }
      };
      /**
       * @usage
       * ```ts
       * const styledText = markupStyleCreator.wrapRichTextStyle([
       *     // The styles will be auto merged.
       *     {
       *         fontSize: 12,
       *         color: 'blue'
       *     },
       *     {
       *         padding: 20
       *     }
       * ]);
       * ```
       */


      TooltipMarkupStyleCreator.prototype.wrapRichTextStyle = function (text, styles) {
        var finalStl = {};

        if (isArray(styles)) {
          each(styles, function (stl) {
            return extend(finalStl, stl);
          });
        } else {
          extend(finalStl, styles);
        }

        var styleName = this._generateStyleName();

        this.richTextStyles[styleName] = finalStl;
        return "{" + styleName + "|" + text + "}";
      };

      return TooltipMarkupStyleCreator;
    }();

    function defaultSeriesFormatTooltip(opt) {
      var series = opt.series;
      var dataIndex = opt.dataIndex;
      var multipleSeries = opt.multipleSeries;
      var data = series.getData();
      var tooltipDims = data.mapDimensionsAll('defaultedTooltip');
      var tooltipDimLen = tooltipDims.length;
      var value = series.getRawValue(dataIndex);
      var isValueArr = isArray(value);
      var markerColor = retrieveVisualColorForTooltipMarker(series, dataIndex); // Complicated rule for pretty tooltip.

      var inlineValue;
      var inlineValueType;
      var subBlocks;
      var sortParam;

      if (tooltipDimLen > 1 || isValueArr && !tooltipDimLen) {
        var formatArrResult = formatTooltipArrayValue(value, series, dataIndex, tooltipDims, markerColor);
        inlineValue = formatArrResult.inlineValues;
        inlineValueType = formatArrResult.inlineValueTypes;
        subBlocks = formatArrResult.blocks; // Only support tooltip sort by the first inline value. It's enough in most cases.

        sortParam = formatArrResult.inlineValues[0];
      } else if (tooltipDimLen) {
        var dimInfo = data.getDimensionInfo(tooltipDims[0]);
        sortParam = inlineValue = retrieveRawValue(data, dataIndex, tooltipDims[0]);
        inlineValueType = dimInfo.type;
      } else {
        sortParam = inlineValue = isValueArr ? value[0] : value;
      } // Do not show generated series name. It might not be readable.


      var seriesNameSpecified = isNameSpecified(series);
      var seriesName = seriesNameSpecified && series.name || '';
      var itemName = data.getName(dataIndex);
      var inlineName = multipleSeries ? seriesName : itemName;
      return createTooltipMarkup('section', {
        header: seriesName,
        // When series name not specified, do not show a header line with only '-'.
        // This case alway happen in tooltip.trigger: 'item'.
        noHeader: multipleSeries || !seriesNameSpecified,
        sortParam: sortParam,
        blocks: [createTooltipMarkup('nameValue', {
          markerType: 'item',
          markerColor: markerColor,
          // Do not mix display seriesName and itemName in one tooltip,
          // which might confuses users.
          name: inlineName,
          // name dimension might be auto assigned, where the name might
          // be not readable. So we check trim here.
          noName: !trim(inlineName),
          value: inlineValue,
          valueType: inlineValueType
        })].concat(subBlocks || [])
      });
    }

    function formatTooltipArrayValue(value, series, dataIndex, tooltipDims, colorStr) {
      // check: category-no-encode-has-axis-data in dataset.html
      var data = series.getData();
      var isValueMultipleLine = reduce(value, function (isValueMultipleLine, val, idx) {
        var dimItem = data.getDimensionInfo(idx);
        return isValueMultipleLine = isValueMultipleLine || dimItem && dimItem.tooltip !== false && dimItem.displayName != null;
      }, false);
      var inlineValues = [];
      var inlineValueTypes = [];
      var blocks = [];
      tooltipDims.length ? each(tooltipDims, function (dim) {
        setEachItem(retrieveRawValue(data, dataIndex, dim), dim);
      }) // By default, all dims is used on tooltip.
      : each(value, setEachItem);

      function setEachItem(val, dim) {
        var dimInfo = data.getDimensionInfo(dim); // If `dimInfo.tooltip` is not set, show tooltip.

        if (!dimInfo || dimInfo.otherDims.tooltip === false) {
          return;
        }

        if (isValueMultipleLine) {
          blocks.push(createTooltipMarkup('nameValue', {
            markerType: 'subItem',
            markerColor: colorStr,
            name: dimInfo.displayName,
            value: val,
            valueType: dimInfo.type
          }));
        } else {
          inlineValues.push(val);
          inlineValueTypes.push(dimInfo.type);
        }
      }

      return {
        inlineValues: inlineValues,
        inlineValueTypes: inlineValueTypes,
        blocks: blocks
      };
    }

    var inner$1 = makeInner();

    function getSelectionKey(data, dataIndex) {
      return data.getName(dataIndex) || data.getId(dataIndex);
    }

    var SERIES_UNIVERSAL_TRANSITION_PROP = '__universalTransitionEnabled';

    var SeriesModel =
    /** @class */
    function (_super) {
      __extends(SeriesModel, _super);

      function SeriesModel() {
        // [Caution]: Because this class or desecendants can be used as `XXX.extend(subProto)`,
        // the class members must not be initialized in constructor or declaration place.
        // Otherwise there is bad case:
        //   class A {xxx = 1;}
        //   enableClassExtend(A);
        //   class B extends A {}
        //   var C = B.extend({xxx: 5});
        //   var c = new C();
        //   console.log(c.xxx); // expect 5 but always 1.
        var _this = _super !== null && _super.apply(this, arguments) || this; // ---------------------------------------
        // Props about data selection
        // ---------------------------------------


        _this._selectedDataIndicesMap = {};
        return _this;
      }

      SeriesModel.prototype.init = function (option, parentModel, ecModel) {
        this.seriesIndex = this.componentIndex;
        this.dataTask = createTask({
          count: dataTaskCount,
          reset: dataTaskReset
        });
        this.dataTask.context = {
          model: this
        };
        this.mergeDefaultAndTheme(option, ecModel);
        var sourceManager = inner$1(this).sourceManager = new SourceManager(this);
        sourceManager.prepareSource();
        var data = this.getInitialData(option, ecModel);
        wrapData(data, this);
        this.dataTask.context.data = data;

        if ("development" !== 'production') {
          assert(data, 'getInitialData returned invalid data.');
        }

        inner$1(this).dataBeforeProcessed = data; // If we reverse the order (make data firstly, and then make
        // dataBeforeProcessed by cloneShallow), cloneShallow will
        // cause data.graph.data !== data when using
        // module:echarts/data/Graph or module:echarts/data/Tree.
        // See module:echarts/data/helper/linkSeriesData
        // Theoretically, it is unreasonable to call `seriesModel.getData()` in the model
        // init or merge stage, because the data can be restored. So we do not `restoreData`
        // and `setData` here, which forbids calling `seriesModel.getData()` in this stage.
        // Call `seriesModel.getRawData()` instead.
        // this.restoreData();

        autoSeriesName(this);

        this._initSelectedMapFromData(data);
      };
      /**
       * Util for merge default and theme to option
       */


      SeriesModel.prototype.mergeDefaultAndTheme = function (option, ecModel) {
        var layoutMode = fetchLayoutMode(this);
        var inputPositionParams = layoutMode ? getLayoutParams(option) : {}; // Backward compat: using subType on theme.
        // But if name duplicate between series subType
        // (for example: parallel) add component mainType,
        // add suffix 'Series'.

        var themeSubType = this.subType;

        if (ComponentModel.hasClass(themeSubType)) {
          themeSubType += 'Series';
        }

        merge(option, ecModel.getTheme().get(this.subType));
        merge(option, this.getDefaultOption()); // Default label emphasis `show`

        defaultEmphasis(option, 'label', ['show']);
        this.fillDataTextStyle(option.data);

        if (layoutMode) {
          mergeLayoutParam(option, inputPositionParams, layoutMode);
        }
      };

      SeriesModel.prototype.mergeOption = function (newSeriesOption, ecModel) {
        // this.settingTask.dirty();
        newSeriesOption = merge(this.option, newSeriesOption, true);
        this.fillDataTextStyle(newSeriesOption.data);
        var layoutMode = fetchLayoutMode(this);

        if (layoutMode) {
          mergeLayoutParam(this.option, newSeriesOption, layoutMode);
        }

        var sourceManager = inner$1(this).sourceManager;
        sourceManager.dirty();
        sourceManager.prepareSource();
        var data = this.getInitialData(newSeriesOption, ecModel);
        wrapData(data, this);
        this.dataTask.dirty();
        this.dataTask.context.data = data;
        inner$1(this).dataBeforeProcessed = data;
        autoSeriesName(this);

        this._initSelectedMapFromData(data);
      };

      SeriesModel.prototype.fillDataTextStyle = function (data) {
        // Default data label emphasis `show`
        // FIXME Tree structure data ?
        // FIXME Performance ?
        if (data && !isTypedArray(data)) {
          var props = ['show'];

          for (var i = 0; i < data.length; i++) {
            if (data[i] && data[i].label) {
              defaultEmphasis(data[i], 'label', props);
            }
          }
        }
      };
      /**
       * Init a data structure from data related option in series
       * Must be overridden.
       */


      SeriesModel.prototype.getInitialData = function (option, ecModel) {
        return;
      };
      /**
       * Append data to list
       */


      SeriesModel.prototype.appendData = function (params) {
        // FIXME ???
        // (1) If data from dataset, forbidden append.
        // (2) support append data of dataset.
        var data = this.getRawData();
        data.appendData(params.data);
      };
      /**
       * Consider some method like `filter`, `map` need make new data,
       * We should make sure that `seriesModel.getData()` get correct
       * data in the stream procedure. So we fetch data from upstream
       * each time `task.perform` called.
       */


      SeriesModel.prototype.getData = function (dataType) {
        var task = getCurrentTask(this);

        if (task) {
          var data = task.context.data;
          return dataType == null ? data : data.getLinkedData(dataType);
        } else {
          // When series is not alive (that may happen when click toolbox
          // restore or setOption with not merge mode), series data may
          // be still need to judge animation or something when graphic
          // elements want to know whether fade out.
          return inner$1(this).data;
        }
      };

      SeriesModel.prototype.getAllData = function () {
        var mainData = this.getData();
        return mainData && mainData.getLinkedDataAll ? mainData.getLinkedDataAll() : [{
          data: mainData
        }];
      };

      SeriesModel.prototype.setData = function (data) {
        var task = getCurrentTask(this);

        if (task) {
          var context = task.context; // Consider case: filter, data sample.
          // FIXME:TS never used, so comment it
          // if (context.data !== data && task.modifyOutputEnd) {
          //     task.setOutputEnd(data.count());
          // }

          context.outputData = data; // Caution: setData should update context.data,
          // Because getData may be called multiply in a
          // single stage and expect to get the data just
          // set. (For example, AxisProxy, x y both call
          // getData and setDate sequentially).
          // So the context.data should be fetched from
          // upstream each time when a stage starts to be
          // performed.

          if (task !== this.dataTask) {
            context.data = data;
          }
        }

        inner$1(this).data = data;
      };

      SeriesModel.prototype.getEncode = function () {
        var encode = this.get('encode', true);

        if (encode) {
          return createHashMap(encode);
        }
      };

      SeriesModel.prototype.getSourceManager = function () {
        return inner$1(this).sourceManager;
      };

      SeriesModel.prototype.getSource = function () {
        return this.getSourceManager().getSource();
      };
      /**
       * Get data before processed
       */


      SeriesModel.prototype.getRawData = function () {
        return inner$1(this).dataBeforeProcessed;
      };

      SeriesModel.prototype.getColorBy = function () {
        var colorBy = this.get('colorBy');
        return colorBy || 'series';
      };

      SeriesModel.prototype.isColorBySeries = function () {
        return this.getColorBy() === 'series';
      };
      /**
       * Get base axis if has coordinate system and has axis.
       * By default use coordSys.getBaseAxis();
       * Can be overridden for some chart.
       * @return {type} description
       */


      SeriesModel.prototype.getBaseAxis = function () {
        var coordSys = this.coordinateSystem; // @ts-ignore

        return coordSys && coordSys.getBaseAxis && coordSys.getBaseAxis();
      };
      /**
       * Default tooltip formatter
       *
       * @param dataIndex
       * @param multipleSeries
       * @param dataType
       * @param renderMode valid values: 'html'(by default) and 'richText'.
       *        'html' is used for rendering tooltip in extra DOM form, and the result
       *        string is used as DOM HTML content.
       *        'richText' is used for rendering tooltip in rich text form, for those where
       *        DOM operation is not supported.
       * @return formatted tooltip with `html` and `markers`
       *        Notice: The override method can also return string
       */


      SeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        return defaultSeriesFormatTooltip({
          series: this,
          dataIndex: dataIndex,
          multipleSeries: multipleSeries
        });
      };

      SeriesModel.prototype.isAnimationEnabled = function () {
        var ecModel = this.ecModel; // Disable animation if using echarts in node but not give ssr flag.
        // In ssr mode, renderToString will generate svg with css animation.

        if (env.node && !(ecModel && ecModel.ssr)) {
          return false;
        }

        var animationEnabled = this.getShallow('animation');

        if (animationEnabled) {
          if (this.getData().count() > this.getShallow('animationThreshold')) {
            animationEnabled = false;
          }
        }

        return !!animationEnabled;
      };

      SeriesModel.prototype.restoreData = function () {
        this.dataTask.dirty();
      };

      SeriesModel.prototype.getColorFromPalette = function (name, scope, requestColorNum) {
        var ecModel = this.ecModel; // PENDING

        var color = PaletteMixin.prototype.getColorFromPalette.call(this, name, scope, requestColorNum);

        if (!color) {
          color = ecModel.getColorFromPalette(name, scope, requestColorNum);
        }

        return color;
      };
      /**
       * Use `data.mapDimensionsAll(coordDim)` instead.
       * @deprecated
       */


      SeriesModel.prototype.coordDimToDataDim = function (coordDim) {
        return this.getRawData().mapDimensionsAll(coordDim);
      };
      /**
       * Get progressive rendering count each step
       */


      SeriesModel.prototype.getProgressive = function () {
        return this.get('progressive');
      };
      /**
       * Get progressive rendering count each step
       */


      SeriesModel.prototype.getProgressiveThreshold = function () {
        return this.get('progressiveThreshold');
      }; // PENGING If selectedMode is null ?


      SeriesModel.prototype.select = function (innerDataIndices, dataType) {
        this._innerSelect(this.getData(dataType), innerDataIndices);
      };

      SeriesModel.prototype.unselect = function (innerDataIndices, dataType) {
        var selectedMap = this.option.selectedMap;

        if (!selectedMap) {
          return;
        }

        var selectedMode = this.option.selectedMode;
        var data = this.getData(dataType);

        if (selectedMode === 'series' || selectedMap === 'all') {
          this.option.selectedMap = {};
          this._selectedDataIndicesMap = {};
          return;
        }

        for (var i = 0; i < innerDataIndices.length; i++) {
          var dataIndex = innerDataIndices[i];
          var nameOrId = getSelectionKey(data, dataIndex);
          selectedMap[nameOrId] = false;
          this._selectedDataIndicesMap[nameOrId] = -1;
        }
      };

      SeriesModel.prototype.toggleSelect = function (innerDataIndices, dataType) {
        var tmpArr = [];

        for (var i = 0; i < innerDataIndices.length; i++) {
          tmpArr[0] = innerDataIndices[i];
          this.isSelected(innerDataIndices[i], dataType) ? this.unselect(tmpArr, dataType) : this.select(tmpArr, dataType);
        }
      };

      SeriesModel.prototype.getSelectedDataIndices = function () {
        if (this.option.selectedMap === 'all') {
          return [].slice.call(this.getData().getIndices());
        }

        var selectedDataIndicesMap = this._selectedDataIndicesMap;
        var nameOrIds = keys(selectedDataIndicesMap);
        var dataIndices = [];

        for (var i = 0; i < nameOrIds.length; i++) {
          var dataIndex = selectedDataIndicesMap[nameOrIds[i]];

          if (dataIndex >= 0) {
            dataIndices.push(dataIndex);
          }
        }

        return dataIndices;
      };

      SeriesModel.prototype.isSelected = function (dataIndex, dataType) {
        var selectedMap = this.option.selectedMap;

        if (!selectedMap) {
          return false;
        }

        var data = this.getData(dataType);
        return (selectedMap === 'all' || selectedMap[getSelectionKey(data, dataIndex)]) && !data.getItemModel(dataIndex).get(['select', 'disabled']);
      };

      SeriesModel.prototype.isUniversalTransitionEnabled = function () {
        if (this[SERIES_UNIVERSAL_TRANSITION_PROP]) {
          return true;
        }

        var universalTransitionOpt = this.option.universalTransition; // Quick reject

        if (!universalTransitionOpt) {
          return false;
        }

        if (universalTransitionOpt === true) {
          return true;
        } // Can be simply 'universalTransition: true'


        return universalTransitionOpt && universalTransitionOpt.enabled;
      };

      SeriesModel.prototype._innerSelect = function (data, innerDataIndices) {
        var _a, _b;

        var option = this.option;
        var selectedMode = option.selectedMode;
        var len = innerDataIndices.length;

        if (!selectedMode || !len) {
          return;
        }

        if (selectedMode === 'series') {
          option.selectedMap = 'all';
        } else if (selectedMode === 'multiple') {
          if (!isObject(option.selectedMap)) {
            option.selectedMap = {};
          }

          var selectedMap = option.selectedMap;

          for (var i = 0; i < len; i++) {
            var dataIndex = innerDataIndices[i]; // TODO different types of data share same object.

            var nameOrId = getSelectionKey(data, dataIndex);
            selectedMap[nameOrId] = true;
            this._selectedDataIndicesMap[nameOrId] = data.getRawIndex(dataIndex);
          }
        } else if (selectedMode === 'single' || selectedMode === true) {
          var lastDataIndex = innerDataIndices[len - 1];
          var nameOrId = getSelectionKey(data, lastDataIndex);
          option.selectedMap = (_a = {}, _a[nameOrId] = true, _a);
          this._selectedDataIndicesMap = (_b = {}, _b[nameOrId] = data.getRawIndex(lastDataIndex), _b);
        }
      };

      SeriesModel.prototype._initSelectedMapFromData = function (data) {
        // Ignore select info in data if selectedMap exists.
        // NOTE It's only for legacy usage. edge data is not supported.
        if (this.option.selectedMap) {
          return;
        }

        var dataIndices = [];

        if (data.hasItemOption) {
          data.each(function (idx) {
            var rawItem = data.getRawDataItem(idx);

            if (rawItem && rawItem.selected) {
              dataIndices.push(idx);
            }
          });
        }

        if (dataIndices.length > 0) {
          this._innerSelect(data, dataIndices);
        }
      }; // /**
      //  * @see {module:echarts/stream/Scheduler}
      //  */
      // abstract pipeTask: null


      SeriesModel.registerClass = function (clz) {
        return ComponentModel.registerClass(clz);
      };

      SeriesModel.protoInitialize = function () {
        var proto = SeriesModel.prototype;
        proto.type = 'series.__base__';
        proto.seriesIndex = 0;
        proto.ignoreStyleOnData = false;
        proto.hasSymbolVisual = false;
        proto.defaultSymbol = 'circle'; // Make sure the values can be accessed!

        proto.visualStyleAccessPath = 'itemStyle';
        proto.visualDrawType = 'fill';
      }();

      return SeriesModel;
    }(ComponentModel);

    mixin(SeriesModel, DataFormatMixin);
    mixin(SeriesModel, PaletteMixin);
    mountExtend(SeriesModel, ComponentModel);
    /**
     * MUST be called after `prepareSource` called
     * Here we need to make auto series, especially for auto legend. But we
     * do not modify series.name in option to avoid side effects.
     */

    function autoSeriesName(seriesModel) {
      // User specified name has higher priority, otherwise it may cause
      // series can not be queried unexpectedly.
      var name = seriesModel.name;

      if (!isNameSpecified(seriesModel)) {
        seriesModel.name = getSeriesAutoName(seriesModel) || name;
      }
    }

    function getSeriesAutoName(seriesModel) {
      var data = seriesModel.getRawData();
      var dataDims = data.mapDimensionsAll('seriesName');
      var nameArr = [];
      each(dataDims, function (dataDim) {
        var dimInfo = data.getDimensionInfo(dataDim);
        dimInfo.displayName && nameArr.push(dimInfo.displayName);
      });
      return nameArr.join(' ');
    }

    function dataTaskCount(context) {
      return context.model.getRawData().count();
    }

    function dataTaskReset(context) {
      var seriesModel = context.model;
      seriesModel.setData(seriesModel.getRawData().cloneShallow());
      return dataTaskProgress;
    }

    function dataTaskProgress(param, context) {
      // Avoid repead cloneShallow when data just created in reset.
      if (context.outputData && param.end > context.outputData.count()) {
        context.model.getRawData().cloneShallow(context.outputData);
      }
    } // TODO refactor


    function wrapData(data, seriesModel) {
      each(concatArray(data.CHANGABLE_METHODS, data.DOWNSAMPLE_METHODS), function (methodName) {
        data.wrapMethod(methodName, curry(onDataChange, seriesModel));
      });
    }

    function onDataChange(seriesModel, newList) {
      var task = getCurrentTask(seriesModel);

      if (task) {
        // Consider case: filter, selectRange
        task.setOutputEnd((newList || this).count());
      }

      return newList;
    }

    function getCurrentTask(seriesModel) {
      var scheduler = (seriesModel.ecModel || {}).scheduler;
      var pipeline = scheduler && scheduler.getPipeline(seriesModel.uid);

      if (pipeline) {
        // When pipline finished, the currrentTask keep the last
        // task (renderTask).
        var task = pipeline.currentTask;

        if (task) {
          var agentStubMap = task.agentStubMap;

          if (agentStubMap) {
            task = agentStubMap.get(seriesModel.uid);
          }
        }

        return task;
      }
    }

    var ComponentView =
    /** @class */
    function () {
      function ComponentView() {
        this.group = new Group();
        this.uid = getUID('viewComponent');
      }

      ComponentView.prototype.init = function (ecModel, api) {};

      ComponentView.prototype.render = function (model, ecModel, api, payload) {};

      ComponentView.prototype.dispose = function (ecModel, api) {};

      ComponentView.prototype.updateView = function (model, ecModel, api, payload) {// Do nothing;
      };

      ComponentView.prototype.updateLayout = function (model, ecModel, api, payload) {// Do nothing;
      };

      ComponentView.prototype.updateVisual = function (model, ecModel, api, payload) {// Do nothing;
      };
      /**
       * Hook for toggle blur target series.
       * Can be used in marker for blur or leave blur the markers
       */


      ComponentView.prototype.toggleBlurSeries = function (seriesModels, isBlur, ecModel) {// Do nothing;
      };
      /**
       * Traverse the new rendered elements.
       *
       * It will traverse the new added element in progressive rendering.
       * And traverse all in normal rendering.
       */


      ComponentView.prototype.eachRendered = function (cb) {
        var group = this.group;

        if (group) {
          group.traverse(cb);
        }
      };

      return ComponentView;
    }();
    enableClassExtend(ComponentView);
    enableClassManagement(ComponentView);

    /**
     * @return {string} If large mode changed, return string 'reset';
     */

    function createRenderPlanner() {
      var inner = makeInner();
      return function (seriesModel) {
        var fields = inner(seriesModel);
        var pipelineContext = seriesModel.pipelineContext;
        var originalLarge = !!fields.large;
        var originalProgressive = !!fields.progressiveRender; // FIXME: if the planner works on a filtered series, `pipelineContext` does not
        // exists. See #11611 . Probably we need to modify this structure, see the comment
        // on `performRawSeries` in `Schedular.js`.

        var large = fields.large = !!(pipelineContext && pipelineContext.large);
        var progressive = fields.progressiveRender = !!(pipelineContext && pipelineContext.progressiveRender);
        return !!(originalLarge !== large || originalProgressive !== progressive) && 'reset';
      };
    }

    var inner$2 = makeInner();
    var renderPlanner = createRenderPlanner();

    var ChartView =
    /** @class */
    function () {
      function ChartView() {
        this.group = new Group();
        this.uid = getUID('viewChart');
        this.renderTask = createTask({
          plan: renderTaskPlan,
          reset: renderTaskReset
        });
        this.renderTask.context = {
          view: this
        };
      }

      ChartView.prototype.init = function (ecModel, api) {};

      ChartView.prototype.render = function (seriesModel, ecModel, api, payload) {
        if ("development" !== 'production') {
          throw new Error('render method must been implemented');
        }
      };
      /**
       * Highlight series or specified data item.
       */


      ChartView.prototype.highlight = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData(payload && payload.dataType);

        if (!data) {
          if ("development" !== 'production') {
            error("Unknown dataType " + payload.dataType);
          }

          return;
        }

        toggleHighlight(data, payload, 'emphasis');
      };
      /**
       * Downplay series or specified data item.
       */


      ChartView.prototype.downplay = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData(payload && payload.dataType);

        if (!data) {
          if ("development" !== 'production') {
            error("Unknown dataType " + payload.dataType);
          }

          return;
        }

        toggleHighlight(data, payload, 'normal');
      };
      /**
       * Remove self.
       */


      ChartView.prototype.remove = function (ecModel, api) {
        this.group.removeAll();
      };
      /**
       * Dispose self.
       */


      ChartView.prototype.dispose = function (ecModel, api) {};

      ChartView.prototype.updateView = function (seriesModel, ecModel, api, payload) {
        this.render(seriesModel, ecModel, api, payload);
      }; // FIXME never used?


      ChartView.prototype.updateLayout = function (seriesModel, ecModel, api, payload) {
        this.render(seriesModel, ecModel, api, payload);
      }; // FIXME never used?


      ChartView.prototype.updateVisual = function (seriesModel, ecModel, api, payload) {
        this.render(seriesModel, ecModel, api, payload);
      };
      /**
       * Traverse the new rendered elements.
       *
       * It will traverse the new added element in progressive rendering.
       * And traverse all in normal rendering.
       */


      ChartView.prototype.eachRendered = function (cb) {
        traverseElements(this.group, cb);
      };

      ChartView.markUpdateMethod = function (payload, methodName) {
        inner$2(payload).updateMethod = methodName;
      };

      ChartView.protoInitialize = function () {
        var proto = ChartView.prototype;
        proto.type = 'chart';
      }();

      return ChartView;
    }();
    /**
     * Set state of single element
     */

    function elSetState(el, state, highlightDigit) {
      if (el && isHighDownDispatcher(el)) {
        (state === 'emphasis' ? enterEmphasis : leaveEmphasis)(el, highlightDigit);
      }
    }

    function toggleHighlight(data, payload, state) {
      var dataIndex = queryDataIndex(data, payload);
      var highlightDigit = payload && payload.highlightKey != null ? getHighlightDigit(payload.highlightKey) : null;

      if (dataIndex != null) {
        each(normalizeToArray(dataIndex), function (dataIdx) {
          elSetState(data.getItemGraphicEl(dataIdx), state, highlightDigit);
        });
      } else {
        data.eachItemGraphicEl(function (el) {
          elSetState(el, state, highlightDigit);
        });
      }
    }

    enableClassExtend(ChartView, ['dispose']);
    enableClassManagement(ChartView);

    function renderTaskPlan(context) {
      return renderPlanner(context.model);
    }

    function renderTaskReset(context) {
      var seriesModel = context.model;
      var ecModel = context.ecModel;
      var api = context.api;
      var payload = context.payload; // FIXME: remove updateView updateVisual

      var progressiveRender = seriesModel.pipelineContext.progressiveRender;
      var view = context.view;
      var updateMethod = payload && inner$2(payload).updateMethod;
      var methodName = progressiveRender ? 'incrementalPrepareRender' : updateMethod && view[updateMethod] ? updateMethod // `appendData` is also supported when data amount
      // is less than progressive threshold.
      : 'render';

      if (methodName !== 'render') {
        view[methodName](seriesModel, ecModel, api, payload);
      }

      return progressMethodMap[methodName];
    }

    var progressMethodMap = {
      incrementalPrepareRender: {
        progress: function (params, context) {
          context.view.incrementalRender(params, context.model, context.ecModel, context.api, context.payload);
        }
      },
      render: {
        // Put view.render in `progress` to support appendData. But in this case
        // view.render should not be called in reset, otherwise it will be called
        // twise. Use `forceFirstProgress` to make sure that view.render is called
        // in any cases.
        forceFirstProgress: true,
        progress: function (params, context) {
          context.view.render(context.model, context.ecModel, context.api, context.payload);
        }
      }
    };

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var ORIGIN_METHOD = '\0__throttleOriginMethod';
    var RATE = '\0__throttleRate';
    var THROTTLE_TYPE = '\0__throttleType';
    /**
     * @public
     * @param {(Function)} fn
     * @param {number} [delay=0] Unit: ms.
     * @param {boolean} [debounce=false]
     *        true: If call interval less than `delay`, only the last call works.
     *        false: If call interval less than `delay, call works on fixed rate.
     * @return {(Function)} throttled fn.
     */

    function throttle(fn, delay, debounce) {
      var currCall;
      var lastCall = 0;
      var lastExec = 0;
      var timer = null;
      var diff;
      var scope;
      var args;
      var debounceNextCall;
      delay = delay || 0;

      function exec() {
        lastExec = new Date().getTime();
        timer = null;
        fn.apply(scope, args || []);
      }

      var cb = function () {
        var cbArgs = [];

        for (var _i = 0; _i < arguments.length; _i++) {
          cbArgs[_i] = arguments[_i];
        }

        currCall = new Date().getTime();
        scope = this;
        args = cbArgs;
        var thisDelay = debounceNextCall || delay;
        var thisDebounce = debounceNextCall || debounce;
        debounceNextCall = null;
        diff = currCall - (thisDebounce ? lastCall : lastExec) - thisDelay;
        clearTimeout(timer); // Here we should make sure that: the `exec` SHOULD NOT be called later
        // than a new call of `cb`, that is, preserving the command order. Consider
        // calculating "scale rate" when roaming as an example. When a call of `cb`
        // happens, either the `exec` is called dierectly, or the call is delayed.
        // But the delayed call should never be later than next call of `cb`. Under
        // this assurance, we can simply update view state each time `dispatchAction`
        // triggered by user roaming, but not need to add extra code to avoid the
        // state being "rolled-back".

        if (thisDebounce) {
          timer = setTimeout(exec, thisDelay);
        } else {
          if (diff >= 0) {
            exec();
          } else {
            timer = setTimeout(exec, -diff);
          }
        }

        lastCall = currCall;
      };
      /**
       * Clear throttle.
       * @public
       */


      cb.clear = function () {
        if (timer) {
          clearTimeout(timer);
          timer = null;
        }
      };
      /**
       * Enable debounce once.
       */


      cb.debounceNextCall = function (debounceDelay) {
        debounceNextCall = debounceDelay;
      };

      return cb;
    }
    /**
     * Create throttle method or update throttle rate.
     *
     * @example
     * ComponentView.prototype.render = function () {
     *     ...
     *     throttle.createOrUpdate(
     *         this,
     *         '_dispatchAction',
     *         this.model.get('throttle'),
     *         'fixRate'
     *     );
     * };
     * ComponentView.prototype.remove = function () {
     *     throttle.clear(this, '_dispatchAction');
     * };
     * ComponentView.prototype.dispose = function () {
     *     throttle.clear(this, '_dispatchAction');
     * };
     *
     */

    function createOrUpdate(obj, fnAttr, rate, throttleType) {
      var fn = obj[fnAttr];

      if (!fn) {
        return;
      }

      var originFn = fn[ORIGIN_METHOD] || fn;
      var lastThrottleType = fn[THROTTLE_TYPE];
      var lastRate = fn[RATE];

      if (lastRate !== rate || lastThrottleType !== throttleType) {
        if (rate == null || !throttleType) {
          return obj[fnAttr] = originFn;
        }

        fn = obj[fnAttr] = throttle(originFn, rate, throttleType === 'debounce');
        fn[ORIGIN_METHOD] = originFn;
        fn[THROTTLE_TYPE] = throttleType;
        fn[RATE] = rate;
      }

      return fn;
    }
    /**
     * Clear throttle. Example see throttle.createOrUpdate.
     */

    function clear(obj, fnAttr) {
      var fn = obj[fnAttr];

      if (fn && fn[ORIGIN_METHOD]) {
        // Clear throttle
        fn.clear && fn.clear();
        obj[fnAttr] = fn[ORIGIN_METHOD];
      }
    }

    var inner$3 = makeInner();
    var defaultStyleMappers = {
      itemStyle: makeStyleMapper(ITEM_STYLE_KEY_MAP, true),
      lineStyle: makeStyleMapper(LINE_STYLE_KEY_MAP, true)
    };
    var defaultColorKey = {
      lineStyle: 'stroke',
      itemStyle: 'fill'
    };

    function getStyleMapper(seriesModel, stylePath) {
      var styleMapper = seriesModel.visualStyleMapper || defaultStyleMappers[stylePath];

      if (!styleMapper) {
        console.warn("Unknown style type '" + stylePath + "'.");
        return defaultStyleMappers.itemStyle;
      }

      return styleMapper;
    }

    function getDefaultColorKey(seriesModel, stylePath) {
      // return defaultColorKey[stylePath] ||
      var colorKey = seriesModel.visualDrawType || defaultColorKey[stylePath];

      if (!colorKey) {
        console.warn("Unknown style type '" + stylePath + "'.");
        return 'fill';
      }

      return colorKey;
    }

    var seriesStyleTask = {
      createOnAllSeries: true,
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        var data = seriesModel.getData();
        var stylePath = seriesModel.visualStyleAccessPath || 'itemStyle'; // Set in itemStyle

        var styleModel = seriesModel.getModel(stylePath);
        var getStyle = getStyleMapper(seriesModel, stylePath);
        var globalStyle = getStyle(styleModel);
        var decalOption = styleModel.getShallow('decal');

        if (decalOption) {
          data.setVisual('decal', decalOption);
          decalOption.dirty = true;
        } // TODO


        var colorKey = getDefaultColorKey(seriesModel, stylePath);
        var color = globalStyle[colorKey]; // TODO style callback

        var colorCallback = isFunction(color) ? color : null;
        var hasAutoColor = globalStyle.fill === 'auto' || globalStyle.stroke === 'auto'; // Get from color palette by default.

        if (!globalStyle[colorKey] || colorCallback || hasAutoColor) {
          // Note: If some series has color specified (e.g., by itemStyle.color), we DO NOT
          // make it effect palette. Because some scenarios users need to make some series
          // transparent or as background, which should better not effect the palette.
          var colorPalette = seriesModel.getColorFromPalette( // TODO series count changed.
          seriesModel.name, null, ecModel.getSeriesCount());

          if (!globalStyle[colorKey]) {
            globalStyle[colorKey] = colorPalette;
            data.setVisual('colorFromPalette', true);
          }

          globalStyle.fill = globalStyle.fill === 'auto' || isFunction(globalStyle.fill) ? colorPalette : globalStyle.fill;
          globalStyle.stroke = globalStyle.stroke === 'auto' || isFunction(globalStyle.stroke) ? colorPalette : globalStyle.stroke;
        }

        data.setVisual('style', globalStyle);
        data.setVisual('drawType', colorKey); // Only visible series has each data be visual encoded

        if (!ecModel.isSeriesFiltered(seriesModel) && colorCallback) {
          data.setVisual('colorFromPalette', false);
          return {
            dataEach: function (data, idx) {
              var dataParams = seriesModel.getDataParams(idx);
              var itemStyle = extend({}, globalStyle);
              itemStyle[colorKey] = colorCallback(dataParams);
              data.setItemVisual(idx, 'style', itemStyle);
            }
          };
        }
      }
    };
    var sharedModel = new Model();
    var dataStyleTask = {
      createOnAllSeries: true,
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        if (seriesModel.ignoreStyleOnData || ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var data = seriesModel.getData();
        var stylePath = seriesModel.visualStyleAccessPath || 'itemStyle'; // Set in itemStyle

        var getStyle = getStyleMapper(seriesModel, stylePath);
        var colorKey = data.getVisual('drawType');
        return {
          dataEach: data.hasItemOption ? function (data, idx) {
            // Not use getItemModel for performance considuration
            var rawItem = data.getRawDataItem(idx);

            if (rawItem && rawItem[stylePath]) {
              sharedModel.option = rawItem[stylePath];
              var style = getStyle(sharedModel);
              var existsStyle = data.ensureUniqueItemVisual(idx, 'style');
              extend(existsStyle, style);

              if (sharedModel.option.decal) {
                data.setItemVisual(idx, 'decal', sharedModel.option.decal);
                sharedModel.option.decal.dirty = true;
              }

              if (colorKey in style) {
                data.setItemVisual(idx, 'colorFromPalette', false);
              }
            }
          } : null
        };
      }
    }; // Pick color from palette for the data which has not been set with color yet.
    // Note: do not support stream rendering. No such cases yet.

    var dataColorPaletteTask = {
      performRawSeries: true,
      overallReset: function (ecModel) {
        // Each type of series uses one scope.
        // Pie and funnel are using different scopes.
        var paletteScopeGroupByType = createHashMap();
        ecModel.eachSeries(function (seriesModel) {
          var colorBy = seriesModel.getColorBy();

          if (seriesModel.isColorBySeries()) {
            return;
          }

          var key = seriesModel.type + '-' + colorBy;
          var colorScope = paletteScopeGroupByType.get(key);

          if (!colorScope) {
            colorScope = {};
            paletteScopeGroupByType.set(key, colorScope);
          }

          inner$3(seriesModel).scope = colorScope;
        });
        ecModel.eachSeries(function (seriesModel) {
          if (seriesModel.isColorBySeries() || ecModel.isSeriesFiltered(seriesModel)) {
            return;
          }

          var dataAll = seriesModel.getRawData();
          var idxMap = {};
          var data = seriesModel.getData();
          var colorScope = inner$3(seriesModel).scope;
          var stylePath = seriesModel.visualStyleAccessPath || 'itemStyle';
          var colorKey = getDefaultColorKey(seriesModel, stylePath);
          data.each(function (idx) {
            var rawIdx = data.getRawIndex(idx);
            idxMap[rawIdx] = idx;
          }); // Iterate on data before filtered. To make sure color from palette can be
          // Consistent when toggling legend.

          dataAll.each(function (rawIdx) {
            var idx = idxMap[rawIdx];
            var fromPalette = data.getItemVisual(idx, 'colorFromPalette'); // Get color from palette for each data only when the color is inherited from series color, which is
            // also picked from color palette. So following situation is not in the case:
            // 1. series.itemStyle.color is set
            // 2. color is encoded by visualMap

            if (fromPalette) {
              var itemStyle = data.ensureUniqueItemVisual(idx, 'style');
              var name_1 = dataAll.getName(rawIdx) || rawIdx + '';
              var dataCount = dataAll.count();
              itemStyle[colorKey] = seriesModel.getColorFromPalette(name_1, colorScope, dataCount);
            }
          });
        });
      }
    };

    var PI$3 = Math.PI;
    /**
     * @param {module:echarts/ExtensionAPI} api
     * @param {Object} [opts]
     * @param {string} [opts.text]
     * @param {string} [opts.color]
     * @param {string} [opts.textColor]
     * @return {module:zrender/Element}
     */

    function defaultLoading(api, opts) {
      opts = opts || {};
      defaults(opts, {
        text: 'loading',
        textColor: '#000',
        fontSize: 12,
        fontWeight: 'normal',
        fontStyle: 'normal',
        fontFamily: 'sans-serif',
        maskColor: 'rgba(255, 255, 255, 0.8)',
        showSpinner: true,
        color: '#5470c6',
        spinnerRadius: 10,
        lineWidth: 5,
        zlevel: 0
      });
      var group = new Group();
      var mask = new Rect({
        style: {
          fill: opts.maskColor
        },
        zlevel: opts.zlevel,
        z: 10000
      });
      group.add(mask);
      var textContent = new ZRText({
        style: {
          text: opts.text,
          fill: opts.textColor,
          fontSize: opts.fontSize,
          fontWeight: opts.fontWeight,
          fontStyle: opts.fontStyle,
          fontFamily: opts.fontFamily
        },
        zlevel: opts.zlevel,
        z: 10001
      });
      var labelRect = new Rect({
        style: {
          fill: 'none'
        },
        textContent: textContent,
        textConfig: {
          position: 'right',
          distance: 10
        },
        zlevel: opts.zlevel,
        z: 10001
      });
      group.add(labelRect);
      var arc;

      if (opts.showSpinner) {
        arc = new Arc({
          shape: {
            startAngle: -PI$3 / 2,
            endAngle: -PI$3 / 2 + 0.1,
            r: opts.spinnerRadius
          },
          style: {
            stroke: opts.color,
            lineCap: 'round',
            lineWidth: opts.lineWidth
          },
          zlevel: opts.zlevel,
          z: 10001
        });
        arc.animateShape(true).when(1000, {
          endAngle: PI$3 * 3 / 2
        }).start('circularInOut');
        arc.animateShape(true).when(1000, {
          startAngle: PI$3 * 3 / 2
        }).delay(300).start('circularInOut');
        group.add(arc);
      } // Inject resize


      group.resize = function () {
        var textWidth = textContent.getBoundingRect().width;
        var r = opts.showSpinner ? opts.spinnerRadius : 0; // cx = (containerWidth - arcDiameter - textDistance - textWidth) / 2
        // textDistance needs to be calculated when both animation and text exist

        var cx = (api.getWidth() - r * 2 - (opts.showSpinner && textWidth ? 10 : 0) - textWidth) / 2 - (opts.showSpinner && textWidth ? 0 : 5 + textWidth / 2) // only show the text
        + (opts.showSpinner ? 0 : textWidth / 2) // only show the spinner
        + (textWidth ? 0 : r);
        var cy = api.getHeight() / 2;
        opts.showSpinner && arc.setShape({
          cx: cx,
          cy: cy
        });
        labelRect.setShape({
          x: cx - r,
          y: cy - r,
          width: r * 2,
          height: r * 2
        });
        mask.setShape({
          x: 0,
          y: 0,
          width: api.getWidth(),
          height: api.getHeight()
        });
      };

      group.resize();
      return group;
    }

    var Scheduler =
    /** @class */
    function () {
      function Scheduler(ecInstance, api, dataProcessorHandlers, visualHandlers) {
        // key: handlerUID
        this._stageTaskMap = createHashMap();
        this.ecInstance = ecInstance;
        this.api = api; // Fix current processors in case that in some rear cases that
        // processors might be registered after echarts instance created.
        // Register processors incrementally for a echarts instance is
        // not supported by this stream architecture.

        dataProcessorHandlers = this._dataProcessorHandlers = dataProcessorHandlers.slice();
        visualHandlers = this._visualHandlers = visualHandlers.slice();
        this._allHandlers = dataProcessorHandlers.concat(visualHandlers);
      }

      Scheduler.prototype.restoreData = function (ecModel, payload) {
        // TODO: Only restore needed series and components, but not all components.
        // Currently `restoreData` of all of the series and component will be called.
        // But some independent components like `title`, `legend`, `graphic`, `toolbox`,
        // `tooltip`, `axisPointer`, etc, do not need series refresh when `setOption`,
        // and some components like coordinate system, axes, dataZoom, visualMap only
        // need their target series refresh.
        // (1) If we are implementing this feature some day, we should consider these cases:
        // if a data processor depends on a component (e.g., dataZoomProcessor depends
        // on the settings of `dataZoom`), it should be re-performed if the component
        // is modified by `setOption`.
        // (2) If a processor depends on sevral series, speicified by its `getTargetSeries`,
        // it should be re-performed when the result array of `getTargetSeries` changed.
        // We use `dependencies` to cover these issues.
        // (3) How to update target series when coordinate system related components modified.
        // TODO: simply the dirty mechanism? Check whether only the case here can set tasks dirty,
        // and this case all of the tasks will be set as dirty.
        ecModel.restoreData(payload); // Theoretically an overall task not only depends on each of its target series, but also
        // depends on all of the series.
        // The overall task is not in pipeline, and `ecModel.restoreData` only set pipeline tasks
        // dirty. If `getTargetSeries` of an overall task returns nothing, we should also ensure
        // that the overall task is set as dirty and to be performed, otherwise it probably cause
        // state chaos. So we have to set dirty of all of the overall tasks manually, otherwise it
        // probably cause state chaos (consider `dataZoomProcessor`).

        this._stageTaskMap.each(function (taskRecord) {
          var overallTask = taskRecord.overallTask;
          overallTask && overallTask.dirty();
        });
      }; // If seriesModel provided, incremental threshold is check by series data.


      Scheduler.prototype.getPerformArgs = function (task, isBlock) {
        // For overall task
        if (!task.__pipeline) {
          return;
        }

        var pipeline = this._pipelineMap.get(task.__pipeline.id);

        var pCtx = pipeline.context;
        var incremental = !isBlock && pipeline.progressiveEnabled && (!pCtx || pCtx.progressiveRender) && task.__idxInPipeline > pipeline.blockIndex;
        var step = incremental ? pipeline.step : null;
        var modDataCount = pCtx && pCtx.modDataCount;
        var modBy = modDataCount != null ? Math.ceil(modDataCount / step) : null;
        return {
          step: step,
          modBy: modBy,
          modDataCount: modDataCount
        };
      };

      Scheduler.prototype.getPipeline = function (pipelineId) {
        return this._pipelineMap.get(pipelineId);
      };
      /**
       * Current, progressive rendering starts from visual and layout.
       * Always detect render mode in the same stage, avoiding that incorrect
       * detection caused by data filtering.
       * Caution:
       * `updateStreamModes` use `seriesModel.getData()`.
       */


      Scheduler.prototype.updateStreamModes = function (seriesModel, view) {
        var pipeline = this._pipelineMap.get(seriesModel.uid);

        var data = seriesModel.getData();
        var dataLen = data.count(); // `progressiveRender` means that can render progressively in each
        // animation frame. Note that some types of series do not provide
        // `view.incrementalPrepareRender` but support `chart.appendData`. We
        // use the term `incremental` but not `progressive` to describe the
        // case that `chart.appendData`.

        var progressiveRender = pipeline.progressiveEnabled && view.incrementalPrepareRender && dataLen >= pipeline.threshold;
        var large = seriesModel.get('large') && dataLen >= seriesModel.get('largeThreshold'); // TODO: modDataCount should not updated if `appendData`, otherwise cause whole repaint.
        // see `test/candlestick-large3.html`

        var modDataCount = seriesModel.get('progressiveChunkMode') === 'mod' ? dataLen : null;
        seriesModel.pipelineContext = pipeline.context = {
          progressiveRender: progressiveRender,
          modDataCount: modDataCount,
          large: large
        };
      };

      Scheduler.prototype.restorePipelines = function (ecModel) {
        var scheduler = this;
        var pipelineMap = scheduler._pipelineMap = createHashMap();
        ecModel.eachSeries(function (seriesModel) {
          var progressive = seriesModel.getProgressive();
          var pipelineId = seriesModel.uid;
          pipelineMap.set(pipelineId, {
            id: pipelineId,
            head: null,
            tail: null,
            threshold: seriesModel.getProgressiveThreshold(),
            progressiveEnabled: progressive && !(seriesModel.preventIncremental && seriesModel.preventIncremental()),
            blockIndex: -1,
            step: Math.round(progressive || 700),
            count: 0
          });

          scheduler._pipe(seriesModel, seriesModel.dataTask);
        });
      };

      Scheduler.prototype.prepareStageTasks = function () {
        var stageTaskMap = this._stageTaskMap;
        var ecModel = this.api.getModel();
        var api = this.api;
        each(this._allHandlers, function (handler) {
          var record = stageTaskMap.get(handler.uid) || stageTaskMap.set(handler.uid, {});
          var errMsg = '';

          if ("development" !== 'production') {
            // Currently do not need to support to sepecify them both.
            errMsg = '"reset" and "overallReset" must not be both specified.';
          }

          assert(!(handler.reset && handler.overallReset), errMsg);
          handler.reset && this._createSeriesStageTask(handler, record, ecModel, api);
          handler.overallReset && this._createOverallStageTask(handler, record, ecModel, api);
        }, this);
      };

      Scheduler.prototype.prepareView = function (view, model, ecModel, api) {
        var renderTask = view.renderTask;
        var context = renderTask.context;
        context.model = model;
        context.ecModel = ecModel;
        context.api = api;
        renderTask.__block = !view.incrementalPrepareRender;

        this._pipe(model, renderTask);
      };

      Scheduler.prototype.performDataProcessorTasks = function (ecModel, payload) {
        // If we do not use `block` here, it should be considered when to update modes.
        this._performStageTasks(this._dataProcessorHandlers, ecModel, payload, {
          block: true
        });
      };

      Scheduler.prototype.performVisualTasks = function (ecModel, payload, opt) {
        this._performStageTasks(this._visualHandlers, ecModel, payload, opt);
      };

      Scheduler.prototype._performStageTasks = function (stageHandlers, ecModel, payload, opt) {
        opt = opt || {};
        var unfinished = false;
        var scheduler = this;
        each(stageHandlers, function (stageHandler, idx) {
          if (opt.visualType && opt.visualType !== stageHandler.visualType) {
            return;
          }

          var stageHandlerRecord = scheduler._stageTaskMap.get(stageHandler.uid);

          var seriesTaskMap = stageHandlerRecord.seriesTaskMap;
          var overallTask = stageHandlerRecord.overallTask;

          if (overallTask) {
            var overallNeedDirty_1;
            var agentStubMap = overallTask.agentStubMap;
            agentStubMap.each(function (stub) {
              if (needSetDirty(opt, stub)) {
                stub.dirty();
                overallNeedDirty_1 = true;
              }
            });
            overallNeedDirty_1 && overallTask.dirty();
            scheduler.updatePayload(overallTask, payload);
            var performArgs_1 = scheduler.getPerformArgs(overallTask, opt.block); // Execute stubs firstly, which may set the overall task dirty,
            // then execute the overall task. And stub will call seriesModel.setData,
            // which ensures that in the overallTask seriesModel.getData() will not
            // return incorrect data.

            agentStubMap.each(function (stub) {
              stub.perform(performArgs_1);
            });

            if (overallTask.perform(performArgs_1)) {
              unfinished = true;
            }
          } else if (seriesTaskMap) {
            seriesTaskMap.each(function (task, pipelineId) {
              if (needSetDirty(opt, task)) {
                task.dirty();
              }

              var performArgs = scheduler.getPerformArgs(task, opt.block); // FIXME
              // if intending to declare `performRawSeries` in handlers, only
              // stream-independent (specifically, data item independent) operations can be
              // performed. Because if a series is filtered, most of the tasks will not
              // be performed. A stream-dependent operation probably cause wrong biz logic.
              // Perhaps we should not provide a separate callback for this case instead
              // of providing the config `performRawSeries`. The stream-dependent operations
              // and stream-independent operations should better not be mixed.

              performArgs.skip = !stageHandler.performRawSeries && ecModel.isSeriesFiltered(task.context.model);
              scheduler.updatePayload(task, payload);

              if (task.perform(performArgs)) {
                unfinished = true;
              }
            });
          }
        });

        function needSetDirty(opt, task) {
          return opt.setDirty && (!opt.dirtyMap || opt.dirtyMap.get(task.__pipeline.id));
        }

        this.unfinished = unfinished || this.unfinished;
      };

      Scheduler.prototype.performSeriesTasks = function (ecModel) {
        var unfinished;
        ecModel.eachSeries(function (seriesModel) {
          // Progress to the end for dataInit and dataRestore.
          unfinished = seriesModel.dataTask.perform() || unfinished;
        });
        this.unfinished = unfinished || this.unfinished;
      };

      Scheduler.prototype.plan = function () {
        // Travel pipelines, check block.
        this._pipelineMap.each(function (pipeline) {
          var task = pipeline.tail;

          do {
            if (task.__block) {
              pipeline.blockIndex = task.__idxInPipeline;
              break;
            }

            task = task.getUpstream();
          } while (task);
        });
      };

      Scheduler.prototype.updatePayload = function (task, payload) {
        payload !== 'remain' && (task.context.payload = payload);
      };

      Scheduler.prototype._createSeriesStageTask = function (stageHandler, stageHandlerRecord, ecModel, api) {
        var scheduler = this;
        var oldSeriesTaskMap = stageHandlerRecord.seriesTaskMap; // The count of stages are totally about only several dozen, so
        // do not need to reuse the map.

        var newSeriesTaskMap = stageHandlerRecord.seriesTaskMap = createHashMap();
        var seriesType = stageHandler.seriesType;
        var getTargetSeries = stageHandler.getTargetSeries; // If a stageHandler should cover all series, `createOnAllSeries` should be declared mandatorily,
        // to avoid some typo or abuse. Otherwise if an extension do not specify a `seriesType`,
        // it works but it may cause other irrelevant charts blocked.

        if (stageHandler.createOnAllSeries) {
          ecModel.eachRawSeries(create);
        } else if (seriesType) {
          ecModel.eachRawSeriesByType(seriesType, create);
        } else if (getTargetSeries) {
          getTargetSeries(ecModel, api).each(create);
        }

        function create(seriesModel) {
          var pipelineId = seriesModel.uid; // Init tasks for each seriesModel only once.
          // Reuse original task instance.

          var task = newSeriesTaskMap.set(pipelineId, oldSeriesTaskMap && oldSeriesTaskMap.get(pipelineId) || createTask({
            plan: seriesTaskPlan,
            reset: seriesTaskReset,
            count: seriesTaskCount
          }));
          task.context = {
            model: seriesModel,
            ecModel: ecModel,
            api: api,
            // PENDING: `useClearVisual` not used?
            useClearVisual: stageHandler.isVisual && !stageHandler.isLayout,
            plan: stageHandler.plan,
            reset: stageHandler.reset,
            scheduler: scheduler
          };

          scheduler._pipe(seriesModel, task);
        }
      };

      Scheduler.prototype._createOverallStageTask = function (stageHandler, stageHandlerRecord, ecModel, api) {
        var scheduler = this;
        var overallTask = stageHandlerRecord.overallTask = stageHandlerRecord.overallTask // For overall task, the function only be called on reset stage.
        || createTask({
          reset: overallTaskReset
        });
        overallTask.context = {
          ecModel: ecModel,
          api: api,
          overallReset: stageHandler.overallReset,
          scheduler: scheduler
        };
        var oldAgentStubMap = overallTask.agentStubMap; // The count of stages are totally about only several dozen, so
        // do not need to reuse the map.

        var newAgentStubMap = overallTask.agentStubMap = createHashMap();
        var seriesType = stageHandler.seriesType;
        var getTargetSeries = stageHandler.getTargetSeries;
        var overallProgress = true;
        var shouldOverallTaskDirty = false; // FIXME:TS never used, so comment it
        // let modifyOutputEnd = stageHandler.modifyOutputEnd;
        // An overall task with seriesType detected or has `getTargetSeries`, we add
        // stub in each pipelines, it will set the overall task dirty when the pipeline
        // progress. Moreover, to avoid call the overall task each frame (too frequent),
        // we set the pipeline block.

        var errMsg = '';

        if ("development" !== 'production') {
          errMsg = '"createOnAllSeries" is not supported for "overallReset", ' + 'because it will block all streams.';
        }

        assert(!stageHandler.createOnAllSeries, errMsg);

        if (seriesType) {
          ecModel.eachRawSeriesByType(seriesType, createStub);
        } else if (getTargetSeries) {
          getTargetSeries(ecModel, api).each(createStub);
        } // Otherwise, (usually it is legacy case), the overall task will only be
        // executed when upstream is dirty. Otherwise the progressive rendering of all
        // pipelines will be disabled unexpectedly. But it still needs stubs to receive
        // dirty info from upstream.
        else {
            overallProgress = false;
            each(ecModel.getSeries(), createStub);
          }

        function createStub(seriesModel) {
          var pipelineId = seriesModel.uid;
          var stub = newAgentStubMap.set(pipelineId, oldAgentStubMap && oldAgentStubMap.get(pipelineId) || ( // When the result of `getTargetSeries` changed, the overallTask
          // should be set as dirty and re-performed.
          shouldOverallTaskDirty = true, createTask({
            reset: stubReset,
            onDirty: stubOnDirty
          })));
          stub.context = {
            model: seriesModel,
            overallProgress: overallProgress // FIXME:TS never used, so comment it
            // modifyOutputEnd: modifyOutputEnd

          };
          stub.agent = overallTask;
          stub.__block = overallProgress;

          scheduler._pipe(seriesModel, stub);
        }

        if (shouldOverallTaskDirty) {
          overallTask.dirty();
        }
      };

      Scheduler.prototype._pipe = function (seriesModel, task) {
        var pipelineId = seriesModel.uid;

        var pipeline = this._pipelineMap.get(pipelineId);

        !pipeline.head && (pipeline.head = task);
        pipeline.tail && pipeline.tail.pipe(task);
        pipeline.tail = task;
        task.__idxInPipeline = pipeline.count++;
        task.__pipeline = pipeline;
      };

      Scheduler.wrapStageHandler = function (stageHandler, visualType) {
        if (isFunction(stageHandler)) {
          stageHandler = {
            overallReset: stageHandler,
            seriesType: detectSeriseType(stageHandler)
          };
        }

        stageHandler.uid = getUID('stageHandler');
        visualType && (stageHandler.visualType = visualType);
        return stageHandler;
      };
      return Scheduler;
    }();

    function overallTaskReset(context) {
      context.overallReset(context.ecModel, context.api, context.payload);
    }

    function stubReset(context) {
      return context.overallProgress && stubProgress;
    }

    function stubProgress() {
      this.agent.dirty();
      this.getDownstream().dirty();
    }

    function stubOnDirty() {
      this.agent && this.agent.dirty();
    }

    function seriesTaskPlan(context) {
      return context.plan ? context.plan(context.model, context.ecModel, context.api, context.payload) : null;
    }

    function seriesTaskReset(context) {
      if (context.useClearVisual) {
        context.data.clearAllVisual();
      }

      var resetDefines = context.resetDefines = normalizeToArray(context.reset(context.model, context.ecModel, context.api, context.payload));
      return resetDefines.length > 1 ? map(resetDefines, function (v, idx) {
        return makeSeriesTaskProgress(idx);
      }) : singleSeriesTaskProgress;
    }

    var singleSeriesTaskProgress = makeSeriesTaskProgress(0);

    function makeSeriesTaskProgress(resetDefineIdx) {
      return function (params, context) {
        var data = context.data;
        var resetDefine = context.resetDefines[resetDefineIdx];

        if (resetDefine && resetDefine.dataEach) {
          for (var i = params.start; i < params.end; i++) {
            resetDefine.dataEach(data, i);
          }
        } else if (resetDefine && resetDefine.progress) {
          resetDefine.progress(params, data);
        }
      };
    }

    function seriesTaskCount(context) {
      return context.data.count();
    }
    /**
     * Only some legacy stage handlers (usually in echarts extensions) are pure function.
     * To ensure that they can work normally, they should work in block mode, that is,
     * they should not be started util the previous tasks finished. So they cause the
     * progressive rendering disabled. We try to detect the series type, to narrow down
     * the block range to only the series type they concern, but not all series.
     */


    function detectSeriseType(legacyFunc) {
      seriesType = null;

      try {
        // Assume there is no async when calling `eachSeriesByType`.
        legacyFunc(ecModelMock, apiMock);
      } catch (e) {}

      return seriesType;
    }

    var ecModelMock = {};
    var apiMock = {};
    var seriesType;
    mockMethods(ecModelMock, GlobalModel);
    mockMethods(apiMock, ExtensionAPI);

    ecModelMock.eachSeriesByType = ecModelMock.eachRawSeriesByType = function (type) {
      seriesType = type;
    };

    ecModelMock.eachComponent = function (cond) {
      if (cond.mainType === 'series' && cond.subType) {
        seriesType = cond.subType;
      }
    };

    function mockMethods(target, Clz) {
      /* eslint-disable */
      for (var name_1 in Clz.prototype) {
        // Do not use hasOwnProperty
        target[name_1] = noop;
      }
      /* eslint-enable */

    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var colorAll = ['#37A2DA', '#32C5E9', '#67E0E3', '#9FE6B8', '#FFDB5C', '#ff9f7f', '#fb7293', '#E062AE', '#E690D1', '#e7bcf3', '#9d96f5', '#8378EA', '#96BFFF'];
    var lightTheme = {
      color: colorAll,
      colorLayer: [['#37A2DA', '#ffd85c', '#fd7b5f'], ['#37A2DA', '#67E0E3', '#FFDB5C', '#ff9f7f', '#E062AE', '#9d96f5'], ['#37A2DA', '#32C5E9', '#9FE6B8', '#FFDB5C', '#ff9f7f', '#fb7293', '#e7bcf3', '#8378EA', '#96BFFF'], colorAll]
    };

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var contrastColor = '#B9B8CE';
    var backgroundColor = '#100C2A';

    var axisCommon = function () {
      return {
        axisLine: {
          lineStyle: {
            color: contrastColor
          }
        },
        splitLine: {
          lineStyle: {
            color: '#484753'
          }
        },
        splitArea: {
          areaStyle: {
            color: ['rgba(255,255,255,0.02)', 'rgba(255,255,255,0.05)']
          }
        },
        minorSplitLine: {
          lineStyle: {
            color: '#20203B'
          }
        }
      };
    };

    var colorPalette = ['#4992ff', '#7cffb2', '#fddd60', '#ff6e76', '#58d9f9', '#05c091', '#ff8a45', '#8d48e3', '#dd79ff'];
    var theme = {
      darkMode: true,
      color: colorPalette,
      backgroundColor: backgroundColor,
      axisPointer: {
        lineStyle: {
          color: '#817f91'
        },
        crossStyle: {
          color: '#817f91'
        },
        label: {
          // TODO Contrast of label backgorundColor
          color: '#fff'
        }
      },
      legend: {
        textStyle: {
          color: contrastColor
        }
      },
      textStyle: {
        color: contrastColor
      },
      title: {
        textStyle: {
          color: '#EEF1FA'
        },
        subtextStyle: {
          color: '#B9B8CE'
        }
      },
      toolbox: {
        iconStyle: {
          borderColor: contrastColor
        }
      },
      dataZoom: {
        borderColor: '#71708A',
        textStyle: {
          color: contrastColor
        },
        brushStyle: {
          color: 'rgba(135,163,206,0.3)'
        },
        handleStyle: {
          color: '#353450',
          borderColor: '#C5CBE3'
        },
        moveHandleStyle: {
          color: '#B0B6C3',
          opacity: 0.3
        },
        fillerColor: 'rgba(135,163,206,0.2)',
        emphasis: {
          handleStyle: {
            borderColor: '#91B7F2',
            color: '#4D587D'
          },
          moveHandleStyle: {
            color: '#636D9A',
            opacity: 0.7
          }
        },
        dataBackground: {
          lineStyle: {
            color: '#71708A',
            width: 1
          },
          areaStyle: {
            color: '#71708A'
          }
        },
        selectedDataBackground: {
          lineStyle: {
            color: '#87A3CE'
          },
          areaStyle: {
            color: '#87A3CE'
          }
        }
      },
      visualMap: {
        textStyle: {
          color: contrastColor
        }
      },
      timeline: {
        lineStyle: {
          color: contrastColor
        },
        label: {
          color: contrastColor
        },
        controlStyle: {
          color: contrastColor,
          borderColor: contrastColor
        }
      },
      calendar: {
        itemStyle: {
          color: backgroundColor
        },
        dayLabel: {
          color: contrastColor
        },
        monthLabel: {
          color: contrastColor
        },
        yearLabel: {
          color: contrastColor
        }
      },
      timeAxis: axisCommon(),
      logAxis: axisCommon(),
      valueAxis: axisCommon(),
      categoryAxis: axisCommon(),
      line: {
        symbol: 'circle'
      },
      graph: {
        color: colorPalette
      },
      gauge: {
        title: {
          color: contrastColor
        },
        axisLine: {
          lineStyle: {
            color: [[1, 'rgba(207,212,219,0.2)']]
          }
        },
        axisLabel: {
          color: contrastColor
        },
        detail: {
          color: '#EEF1FA'
        }
      },
      candlestick: {
        itemStyle: {
          color: '#f64e56',
          color0: '#54ea92',
          borderColor: '#f64e56',
          borderColor0: '#54ea92' // borderColor: '#ca2824',
          // borderColor0: '#09a443'

        }
      }
    };
    theme.categoryAxis.splitLine.show = false;

    /**
     * Usage of query:
     * `chart.on('click', query, handler);`
     * The `query` can be:
     * + The component type query string, only `mainType` or `mainType.subType`,
     *   like: 'xAxis', 'series', 'xAxis.category' or 'series.line'.
     * + The component query object, like:
     *   `{seriesIndex: 2}`, `{seriesName: 'xx'}`, `{seriesId: 'some'}`,
     *   `{xAxisIndex: 2}`, `{xAxisName: 'xx'}`, `{xAxisId: 'some'}`.
     * + The data query object, like:
     *   `{dataIndex: 123}`, `{dataType: 'link'}`, `{name: 'some'}`.
     * + The other query object (cmponent customized query), like:
     *   `{element: 'some'}` (only available in custom series).
     *
     * Caveat: If a prop in the `query` object is `null/undefined`, it is the
     * same as there is no such prop in the `query` object.
     */

    var ECEventProcessor =
    /** @class */
    function () {
      function ECEventProcessor() {}

      ECEventProcessor.prototype.normalizeQuery = function (query) {
        var cptQuery = {};
        var dataQuery = {};
        var otherQuery = {}; // `query` is `mainType` or `mainType.subType` of component.

        if (isString(query)) {
          var condCptType = parseClassType(query); // `.main` and `.sub` may be ''.

          cptQuery.mainType = condCptType.main || null;
          cptQuery.subType = condCptType.sub || null;
        } // `query` is an object, convert to {mainType, index, name, id}.
        else {
            // `xxxIndex`, `xxxName`, `xxxId`, `name`, `dataIndex`, `dataType` is reserved,
            // can not be used in `compomentModel.filterForExposedEvent`.
            var suffixes_1 = ['Index', 'Name', 'Id'];
            var dataKeys_1 = {
              name: 1,
              dataIndex: 1,
              dataType: 1
            };
            each(query, function (val, key) {
              var reserved = false;

              for (var i = 0; i < suffixes_1.length; i++) {
                var propSuffix = suffixes_1[i];
                var suffixPos = key.lastIndexOf(propSuffix);

                if (suffixPos > 0 && suffixPos === key.length - propSuffix.length) {
                  var mainType = key.slice(0, suffixPos); // Consider `dataIndex`.

                  if (mainType !== 'data') {
                    cptQuery.mainType = mainType;
                    cptQuery[propSuffix.toLowerCase()] = val;
                    reserved = true;
                  }
                }
              }

              if (dataKeys_1.hasOwnProperty(key)) {
                dataQuery[key] = val;
                reserved = true;
              }

              if (!reserved) {
                otherQuery[key] = val;
              }
            });
          }

        return {
          cptQuery: cptQuery,
          dataQuery: dataQuery,
          otherQuery: otherQuery
        };
      };

      ECEventProcessor.prototype.filter = function (eventType, query) {
        // They should be assigned before each trigger call.
        var eventInfo = this.eventInfo;

        if (!eventInfo) {
          return true;
        }

        var targetEl = eventInfo.targetEl;
        var packedEvent = eventInfo.packedEvent;
        var model = eventInfo.model;
        var view = eventInfo.view; // For event like 'globalout'.

        if (!model || !view) {
          return true;
        }

        var cptQuery = query.cptQuery;
        var dataQuery = query.dataQuery;
        return check(cptQuery, model, 'mainType') && check(cptQuery, model, 'subType') && check(cptQuery, model, 'index', 'componentIndex') && check(cptQuery, model, 'name') && check(cptQuery, model, 'id') && check(dataQuery, packedEvent, 'name') && check(dataQuery, packedEvent, 'dataIndex') && check(dataQuery, packedEvent, 'dataType') && (!view.filterForExposedEvent || view.filterForExposedEvent(eventType, query.otherQuery, targetEl, packedEvent));

        function check(query, host, prop, propOnHost) {
          return query[prop] == null || host[propOnHost || prop] === query[prop];
        }
      };

      ECEventProcessor.prototype.afterTrigger = function () {
        // Make sure the eventInfo won't be used in next trigger.
        this.eventInfo = null;
      };

      return ECEventProcessor;
    }();

    var SYMBOL_PROPS_WITH_CB = ['symbol', 'symbolSize', 'symbolRotate', 'symbolOffset'];
    var SYMBOL_PROPS = SYMBOL_PROPS_WITH_CB.concat(['symbolKeepAspect']); // Encoding visual for all series include which is filtered for legend drawing

    var seriesSymbolTask = {
      createOnAllSeries: true,
      // For legend.
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        var data = seriesModel.getData();

        if (seriesModel.legendIcon) {
          data.setVisual('legendIcon', seriesModel.legendIcon);
        }

        if (!seriesModel.hasSymbolVisual) {
          return;
        }

        var symbolOptions = {};
        var symbolOptionsCb = {};
        var hasCallback = false;

        for (var i = 0; i < SYMBOL_PROPS_WITH_CB.length; i++) {
          var symbolPropName = SYMBOL_PROPS_WITH_CB[i];
          var val = seriesModel.get(symbolPropName);

          if (isFunction(val)) {
            hasCallback = true;
            symbolOptionsCb[symbolPropName] = val;
          } else {
            symbolOptions[symbolPropName] = val;
          }
        }

        symbolOptions.symbol = symbolOptions.symbol || seriesModel.defaultSymbol;
        data.setVisual(extend({
          legendIcon: seriesModel.legendIcon || symbolOptions.symbol,
          symbolKeepAspect: seriesModel.get('symbolKeepAspect')
        }, symbolOptions)); // Only visible series has each data be visual encoded

        if (ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var symbolPropsCb = keys(symbolOptionsCb);

        function dataEach(data, idx) {
          var rawValue = seriesModel.getRawValue(idx);
          var params = seriesModel.getDataParams(idx);

          for (var i = 0; i < symbolPropsCb.length; i++) {
            var symbolPropName = symbolPropsCb[i];
            data.setItemVisual(idx, symbolPropName, symbolOptionsCb[symbolPropName](rawValue, params));
          }
        }

        return {
          dataEach: hasCallback ? dataEach : null
        };
      }
    };
    var dataSymbolTask = {
      createOnAllSeries: true,
      // For legend.
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        if (!seriesModel.hasSymbolVisual) {
          return;
        } // Only visible series has each data be visual encoded


        if (ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var data = seriesModel.getData();

        function dataEach(data, idx) {
          var itemModel = data.getItemModel(idx);

          for (var i = 0; i < SYMBOL_PROPS.length; i++) {
            var symbolPropName = SYMBOL_PROPS[i];
            var val = itemModel.getShallow(symbolPropName, true);

            if (val != null) {
              data.setItemVisual(idx, symbolPropName, val);
            }
          }
        }

        return {
          dataEach: data.hasItemOption ? dataEach : null
        };
      }
    };

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    function getItemVisualFromData(data, dataIndex, key) {
      switch (key) {
        case 'color':
          var style = data.getItemVisual(dataIndex, 'style');
          return style[data.getVisual('drawType')];

        case 'opacity':
          return data.getItemVisual(dataIndex, 'style').opacity;

        case 'symbol':
        case 'symbolSize':
        case 'liftZ':
          return data.getItemVisual(dataIndex, key);

        default:
          if ("development" !== 'production') {
            console.warn("Unknown visual type " + key);
          }

      }
    }
    function getVisualFromData(data, key) {
      switch (key) {
        case 'color':
          var style = data.getVisual('style');
          return style[data.getVisual('drawType')];

        case 'opacity':
          return data.getVisual('style').opacity;

        case 'symbol':
        case 'symbolSize':
        case 'liftZ':
          return data.getVisual(key);

        default:
          if ("development" !== 'production') {
            console.warn("Unknown visual type " + key);
          }

      }
    }

    // Inlucdes: pieSelect, pieUnSelect, pieToggleSelect, mapSelect, mapUnSelect, mapToggleSelect

    function createLegacyDataSelectAction(seriesType, ecRegisterAction) {
      function getSeriesIndices(ecModel, payload) {
        var seriesIndices = [];
        ecModel.eachComponent({
          mainType: 'series',
          subType: seriesType,
          query: payload
        }, function (seriesModel) {
          seriesIndices.push(seriesModel.seriesIndex);
        });
        return seriesIndices;
      }

      each([[seriesType + 'ToggleSelect', 'toggleSelect'], [seriesType + 'Select', 'select'], [seriesType + 'UnSelect', 'unselect']], function (eventsMap) {
        ecRegisterAction(eventsMap[0], function (payload, ecModel, api) {
          payload = extend({}, payload);

          if ("development" !== 'production') {
            deprecateReplaceLog(payload.type, eventsMap[1]);
          }

          api.dispatchAction(extend(payload, {
            type: eventsMap[1],
            seriesIndex: getSeriesIndices(ecModel, payload)
          }));
        });
      });
    }

    function handleSeriesLegacySelectEvents(type, eventPostfix, ecIns, ecModel, payload) {
      var legacyEventName = type + eventPostfix;

      if (!ecIns.isSilent(legacyEventName)) {
        if ("development" !== 'production') {
          deprecateLog("event " + legacyEventName + " is deprecated.");
        }

        ecModel.eachComponent({
          mainType: 'series',
          subType: 'pie'
        }, function (seriesModel) {
          var seriesIndex = seriesModel.seriesIndex;
          var selectedMap = seriesModel.option.selectedMap;
          var selected = payload.selected;

          for (var i = 0; i < selected.length; i++) {
            if (selected[i].seriesIndex === seriesIndex) {
              var data = seriesModel.getData();
              var dataIndex = queryDataIndex(data, payload.fromActionPayload);
              ecIns.trigger(legacyEventName, {
                type: legacyEventName,
                seriesId: seriesModel.id,
                name: isArray(dataIndex) ? data.getName(dataIndex[0]) : data.getName(dataIndex),
                selected: isString(selectedMap) ? selectedMap : extend({}, selectedMap)
              });
            }
          }
        });
      }
    }

    function handleLegacySelectEvents(messageCenter, ecIns, api) {
      messageCenter.on('selectchanged', function (params) {
        var ecModel = api.getModel();

        if (params.isFromClick) {
          handleSeriesLegacySelectEvents('map', 'selectchanged', ecIns, ecModel, params);
          handleSeriesLegacySelectEvents('pie', 'selectchanged', ecIns, ecModel, params);
        } else if (params.fromAction === 'select') {
          handleSeriesLegacySelectEvents('map', 'selected', ecIns, ecModel, params);
          handleSeriesLegacySelectEvents('pie', 'selected', ecIns, ecModel, params);
        } else if (params.fromAction === 'unselect') {
          handleSeriesLegacySelectEvents('map', 'unselected', ecIns, ecModel, params);
          handleSeriesLegacySelectEvents('pie', 'unselected', ecIns, ecModel, params);
        }
      });
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    function findEventDispatcher(target, det, returnFirstMatch) {
      var found;

      while (target) {
        if (det(target)) {
          found = target;

          if (returnFirstMatch) {
            break;
          }
        }

        target = target.__hostTarget || target.parent;
      }

      return found;
    }

    var wmUniqueIndex = Math.round(Math.random() * 9);
    var supportDefineProperty = typeof Object.defineProperty === 'function';
    var WeakMap = (function () {
        function WeakMap() {
            this._id = '__ec_inner_' + wmUniqueIndex++;
        }
        WeakMap.prototype.get = function (key) {
            return this._guard(key)[this._id];
        };
        WeakMap.prototype.set = function (key, value) {
            var target = this._guard(key);
            if (supportDefineProperty) {
                Object.defineProperty(target, this._id, {
                    value: value,
                    enumerable: false,
                    configurable: true
                });
            }
            else {
                target[this._id] = value;
            }
            return this;
        };
        WeakMap.prototype["delete"] = function (key) {
            if (this.has(key)) {
                delete this._guard(key)[this._id];
                return true;
            }
            return false;
        };
        WeakMap.prototype.has = function (key) {
            return !!this._guard(key)[this._id];
        };
        WeakMap.prototype._guard = function (key) {
            if (key !== Object(key)) {
                throw TypeError('Value of WeakMap is not a non-null object.');
            }
            return key;
        };
        return WeakMap;
    }());

    /**
     * Triangle shape
     * @inner
     */

    var Triangle = Path.extend({
      type: 'triangle',
      shape: {
        cx: 0,
        cy: 0,
        width: 0,
        height: 0
      },
      buildPath: function (path, shape) {
        var cx = shape.cx;
        var cy = shape.cy;
        var width = shape.width / 2;
        var height = shape.height / 2;
        path.moveTo(cx, cy - height);
        path.lineTo(cx + width, cy + height);
        path.lineTo(cx - width, cy + height);
        path.closePath();
      }
    });
    /**
     * Diamond shape
     * @inner
     */

    var Diamond = Path.extend({
      type: 'diamond',
      shape: {
        cx: 0,
        cy: 0,
        width: 0,
        height: 0
      },
      buildPath: function (path, shape) {
        var cx = shape.cx;
        var cy = shape.cy;
        var width = shape.width / 2;
        var height = shape.height / 2;
        path.moveTo(cx, cy - height);
        path.lineTo(cx + width, cy);
        path.lineTo(cx, cy + height);
        path.lineTo(cx - width, cy);
        path.closePath();
      }
    });
    /**
     * Pin shape
     * @inner
     */

    var Pin = Path.extend({
      type: 'pin',
      shape: {
        // x, y on the cusp
        x: 0,
        y: 0,
        width: 0,
        height: 0
      },
      buildPath: function (path, shape) {
        var x = shape.x;
        var y = shape.y;
        var w = shape.width / 5 * 3; // Height must be larger than width

        var h = Math.max(w, shape.height);
        var r = w / 2; // Dist on y with tangent point and circle center

        var dy = r * r / (h - r);
        var cy = y - h + r + dy;
        var angle = Math.asin(dy / r); // Dist on x with tangent point and circle center

        var dx = Math.cos(angle) * r;
        var tanX = Math.sin(angle);
        var tanY = Math.cos(angle);
        var cpLen = r * 0.6;
        var cpLen2 = r * 0.7;
        path.moveTo(x - dx, cy + dy);
        path.arc(x, cy, r, Math.PI - angle, Math.PI * 2 + angle);
        path.bezierCurveTo(x + dx - tanX * cpLen, cy + dy + tanY * cpLen, x, y - cpLen2, x, y);
        path.bezierCurveTo(x, y - cpLen2, x - dx + tanX * cpLen, cy + dy + tanY * cpLen, x - dx, cy + dy);
        path.closePath();
      }
    });
    /**
     * Arrow shape
     * @inner
     */

    var Arrow = Path.extend({
      type: 'arrow',
      shape: {
        x: 0,
        y: 0,
        width: 0,
        height: 0
      },
      buildPath: function (ctx, shape) {
        var height = shape.height;
        var width = shape.width;
        var x = shape.x;
        var y = shape.y;
        var dx = width / 3 * 2;
        ctx.moveTo(x, y);
        ctx.lineTo(x + dx, y + height);
        ctx.lineTo(x, y + height / 4 * 3);
        ctx.lineTo(x - dx, y + height);
        ctx.lineTo(x, y);
        ctx.closePath();
      }
    });
    /**
     * Map of path constructors
     */
    // TODO Use function to build symbol path.

    var symbolCtors = {
      line: Line,
      rect: Rect,
      roundRect: Rect,
      square: Rect,
      circle: Circle,
      diamond: Diamond,
      pin: Pin,
      arrow: Arrow,
      triangle: Triangle
    };
    var symbolShapeMakers = {
      line: function (x, y, w, h, shape) {
        shape.x1 = x;
        shape.y1 = y + h / 2;
        shape.x2 = x + w;
        shape.y2 = y + h / 2;
      },
      rect: function (x, y, w, h, shape) {
        shape.x = x;
        shape.y = y;
        shape.width = w;
        shape.height = h;
      },
      roundRect: function (x, y, w, h, shape) {
        shape.x = x;
        shape.y = y;
        shape.width = w;
        shape.height = h;
        shape.r = Math.min(w, h) / 4;
      },
      square: function (x, y, w, h, shape) {
        var size = Math.min(w, h);
        shape.x = x;
        shape.y = y;
        shape.width = size;
        shape.height = size;
      },
      circle: function (x, y, w, h, shape) {
        // Put circle in the center of square
        shape.cx = x + w / 2;
        shape.cy = y + h / 2;
        shape.r = Math.min(w, h) / 2;
      },
      diamond: function (x, y, w, h, shape) {
        shape.cx = x + w / 2;
        shape.cy = y + h / 2;
        shape.width = w;
        shape.height = h;
      },
      pin: function (x, y, w, h, shape) {
        shape.x = x + w / 2;
        shape.y = y + h / 2;
        shape.width = w;
        shape.height = h;
      },
      arrow: function (x, y, w, h, shape) {
        shape.x = x + w / 2;
        shape.y = y + h / 2;
        shape.width = w;
        shape.height = h;
      },
      triangle: function (x, y, w, h, shape) {
        shape.cx = x + w / 2;
        shape.cy = y + h / 2;
        shape.width = w;
        shape.height = h;
      }
    };
    var symbolBuildProxies = {};
    each(symbolCtors, function (Ctor, name) {
      symbolBuildProxies[name] = new Ctor();
    });
    var SymbolClz = Path.extend({
      type: 'symbol',
      shape: {
        symbolType: '',
        x: 0,
        y: 0,
        width: 0,
        height: 0
      },
      calculateTextPosition: function (out, config, rect) {
        var res = calculateTextPosition(out, config, rect);
        var shape = this.shape;

        if (shape && shape.symbolType === 'pin' && config.position === 'inside') {
          res.y = rect.y + rect.height * 0.4;
        }

        return res;
      },
      buildPath: function (ctx, shape, inBundle) {
        var symbolType = shape.symbolType;

        if (symbolType !== 'none') {
          var proxySymbol = symbolBuildProxies[symbolType];

          if (!proxySymbol) {
            // Default rect
            symbolType = 'rect';
            proxySymbol = symbolBuildProxies[symbolType];
          }

          symbolShapeMakers[symbolType](shape.x, shape.y, shape.width, shape.height, proxySymbol.shape);
          proxySymbol.buildPath(ctx, proxySymbol.shape, inBundle);
        }
      }
    }); // Provide setColor helper method to avoid determine if set the fill or stroke outside

    function symbolPathSetColor(color, innerColor) {
      if (this.type !== 'image') {
        var symbolStyle = this.style;

        if (this.__isEmptyBrush) {
          symbolStyle.stroke = color;
          symbolStyle.fill = innerColor || '#fff'; // TODO Same width with lineStyle in LineView

          symbolStyle.lineWidth = 2;
        } else if (this.shape.symbolType === 'line') {
          symbolStyle.stroke = color;
        } else {
          symbolStyle.fill = color;
        }

        this.markRedraw();
      }
    }
    /**
     * Create a symbol element with given symbol configuration: shape, x, y, width, height, color
     */


    function createSymbol(symbolType, x, y, w, h, color, // whether to keep the ratio of w/h,
    keepAspect) {
      // TODO Support image object, DynamicImage.
      var isEmpty = symbolType.indexOf('empty') === 0;

      if (isEmpty) {
        symbolType = symbolType.substr(5, 1).toLowerCase() + symbolType.substr(6);
      }

      var symbolPath;

      if (symbolType.indexOf('image://') === 0) {
        symbolPath = makeImage(symbolType.slice(8), new BoundingRect(x, y, w, h), keepAspect ? 'center' : 'cover');
      } else if (symbolType.indexOf('path://') === 0) {
        symbolPath = makePath(symbolType.slice(7), {}, new BoundingRect(x, y, w, h), keepAspect ? 'center' : 'cover');
      } else {
        symbolPath = new SymbolClz({
          shape: {
            symbolType: symbolType,
            x: x,
            y: y,
            width: w,
            height: h
          }
        });
      }

      symbolPath.__isEmptyBrush = isEmpty; // TODO Should deprecate setColor

      symbolPath.setColor = symbolPathSetColor;

      if (color) {
        symbolPath.setColor(color);
      }

      return symbolPath;
    }
    function normalizeSymbolSize(symbolSize) {
      if (!isArray(symbolSize)) {
        symbolSize = [+symbolSize, +symbolSize];
      }

      return [symbolSize[0] || 0, symbolSize[1] || 0];
    }
    function normalizeSymbolOffset(symbolOffset, symbolSize) {
      if (symbolOffset == null) {
        return;
      }

      if (!isArray(symbolOffset)) {
        symbolOffset = [symbolOffset, symbolOffset];
      }

      return [parsePercent$1(symbolOffset[0], symbolSize[0]) || 0, parsePercent$1(retrieve2(symbolOffset[1], symbolOffset[0]), symbolSize[1]) || 0];
    }

    function isSafeNum(num) {
        return isFinite(num);
    }
    function createLinearGradient(ctx, obj, rect) {
        var x = obj.x == null ? 0 : obj.x;
        var x2 = obj.x2 == null ? 1 : obj.x2;
        var y = obj.y == null ? 0 : obj.y;
        var y2 = obj.y2 == null ? 0 : obj.y2;
        if (!obj.global) {
            x = x * rect.width + rect.x;
            x2 = x2 * rect.width + rect.x;
            y = y * rect.height + rect.y;
            y2 = y2 * rect.height + rect.y;
        }
        x = isSafeNum(x) ? x : 0;
        x2 = isSafeNum(x2) ? x2 : 1;
        y = isSafeNum(y) ? y : 0;
        y2 = isSafeNum(y2) ? y2 : 0;
        var canvasGradient = ctx.createLinearGradient(x, y, x2, y2);
        return canvasGradient;
    }
    function createRadialGradient(ctx, obj, rect) {
        var width = rect.width;
        var height = rect.height;
        var min = Math.min(width, height);
        var x = obj.x == null ? 0.5 : obj.x;
        var y = obj.y == null ? 0.5 : obj.y;
        var r = obj.r == null ? 0.5 : obj.r;
        if (!obj.global) {
            x = x * width + rect.x;
            y = y * height + rect.y;
            r = r * min;
        }
        x = isSafeNum(x) ? x : 0.5;
        y = isSafeNum(y) ? y : 0.5;
        r = r >= 0 && isSafeNum(r) ? r : 0.5;
        var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);
        return canvasGradient;
    }
    function getCanvasGradient(ctx, obj, rect) {
        var canvasGradient = obj.type === 'radial'
            ? createRadialGradient(ctx, obj, rect)
            : createLinearGradient(ctx, obj, rect);
        var colorStops = obj.colorStops;
        for (var i = 0; i < colorStops.length; i++) {
            canvasGradient.addColorStop(colorStops[i].offset, colorStops[i].color);
        }
        return canvasGradient;
    }
    function isClipPathChanged(clipPaths, prevClipPaths) {
        if (clipPaths === prevClipPaths || (!clipPaths && !prevClipPaths)) {
            return false;
        }
        if (!clipPaths || !prevClipPaths || (clipPaths.length !== prevClipPaths.length)) {
            return true;
        }
        for (var i = 0; i < clipPaths.length; i++) {
            if (clipPaths[i] !== prevClipPaths[i]) {
                return true;
            }
        }
        return false;
    }
    function parseInt10(val) {
        return parseInt(val, 10);
    }
    function getSize(root, whIdx, opts) {
        var wh = ['width', 'height'][whIdx];
        var cwh = ['clientWidth', 'clientHeight'][whIdx];
        var plt = ['paddingLeft', 'paddingTop'][whIdx];
        var prb = ['paddingRight', 'paddingBottom'][whIdx];
        if (opts[wh] != null && opts[wh] !== 'auto') {
            return parseFloat(opts[wh]);
        }
        var stl = document.defaultView.getComputedStyle(root);
        return ((root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh]))
            - (parseInt10(stl[plt]) || 0)
            - (parseInt10(stl[prb]) || 0)) | 0;
    }

    function normalizeLineDash(lineType, lineWidth) {
        if (!lineType || lineType === 'solid' || !(lineWidth > 0)) {
            return null;
        }
        return lineType === 'dashed'
            ? [4 * lineWidth, 2 * lineWidth]
            : lineType === 'dotted'
                ? [lineWidth]
                : isNumber(lineType)
                    ? [lineType] : isArray(lineType) ? lineType : null;
    }
    function getLineDash(el) {
        var style = el.style;
        var lineDash = style.lineDash && style.lineWidth > 0 && normalizeLineDash(style.lineDash, style.lineWidth);
        var lineDashOffset = style.lineDashOffset;
        if (lineDash) {
            var lineScale_1 = (style.strokeNoScale && el.getLineScale) ? el.getLineScale() : 1;
            if (lineScale_1 && lineScale_1 !== 1) {
                lineDash = map(lineDash, function (rawVal) {
                    return rawVal / lineScale_1;
                });
                lineDashOffset /= lineScale_1;
            }
        }
        return [lineDash, lineDashOffset];
    }

    var pathProxyForDraw = new PathProxy(true);
    function styleHasStroke(style) {
        var stroke = style.stroke;
        return !(stroke == null || stroke === 'none' || !(style.lineWidth > 0));
    }
    function isValidStrokeFillStyle(strokeOrFill) {
        return typeof strokeOrFill === 'string' && strokeOrFill !== 'none';
    }
    function styleHasFill(style) {
        var fill = style.fill;
        return fill != null && fill !== 'none';
    }
    function doFillPath(ctx, style) {
        if (style.fillOpacity != null && style.fillOpacity !== 1) {
            var originalGlobalAlpha = ctx.globalAlpha;
            ctx.globalAlpha = style.fillOpacity * style.opacity;
            ctx.fill();
            ctx.globalAlpha = originalGlobalAlpha;
        }
        else {
            ctx.fill();
        }
    }
    function doStrokePath(ctx, style) {
        if (style.strokeOpacity != null && style.strokeOpacity !== 1) {
            var originalGlobalAlpha = ctx.globalAlpha;
            ctx.globalAlpha = style.strokeOpacity * style.opacity;
            ctx.stroke();
            ctx.globalAlpha = originalGlobalAlpha;
        }
        else {
            ctx.stroke();
        }
    }
    function createCanvasPattern(ctx, pattern, el) {
        var image = createOrUpdateImage(pattern.image, pattern.__image, el);
        if (isImageReady(image)) {
            var canvasPattern = ctx.createPattern(image, pattern.repeat || 'repeat');
            if (typeof DOMMatrix === 'function'
                && canvasPattern
                && canvasPattern.setTransform) {
                var matrix = new DOMMatrix();
                matrix.translateSelf((pattern.x || 0), (pattern.y || 0));
                matrix.rotateSelf(0, 0, (pattern.rotation || 0) * RADIAN_TO_DEGREE);
                matrix.scaleSelf((pattern.scaleX || 1), (pattern.scaleY || 1));
                canvasPattern.setTransform(matrix);
            }
            return canvasPattern;
        }
    }
    function brushPath(ctx, el, style, inBatch) {
        var _a;
        var hasStroke = styleHasStroke(style);
        var hasFill = styleHasFill(style);
        var strokePercent = style.strokePercent;
        var strokePart = strokePercent < 1;
        var firstDraw = !el.path;
        if ((!el.silent || strokePart) && firstDraw) {
            el.createPathProxy();
        }
        var path = el.path || pathProxyForDraw;
        var dirtyFlag = el.__dirty;
        if (!inBatch) {
            var fill = style.fill;
            var stroke = style.stroke;
            var hasFillGradient = hasFill && !!fill.colorStops;
            var hasStrokeGradient = hasStroke && !!stroke.colorStops;
            var hasFillPattern = hasFill && !!fill.image;
            var hasStrokePattern = hasStroke && !!stroke.image;
            var fillGradient = void 0;
            var strokeGradient = void 0;
            var fillPattern = void 0;
            var strokePattern = void 0;
            var rect = void 0;
            if (hasFillGradient || hasStrokeGradient) {
                rect = el.getBoundingRect();
            }
            if (hasFillGradient) {
                fillGradient = dirtyFlag
                    ? getCanvasGradient(ctx, fill, rect)
                    : el.__canvasFillGradient;
                el.__canvasFillGradient = fillGradient;
            }
            if (hasStrokeGradient) {
                strokeGradient = dirtyFlag
                    ? getCanvasGradient(ctx, stroke, rect)
                    : el.__canvasStrokeGradient;
                el.__canvasStrokeGradient = strokeGradient;
            }
            if (hasFillPattern) {
                fillPattern = (dirtyFlag || !el.__canvasFillPattern)
                    ? createCanvasPattern(ctx, fill, el)
                    : el.__canvasFillPattern;
                el.__canvasFillPattern = fillPattern;
            }
            if (hasStrokePattern) {
                strokePattern = (dirtyFlag || !el.__canvasStrokePattern)
                    ? createCanvasPattern(ctx, stroke, el)
                    : el.__canvasStrokePattern;
                el.__canvasStrokePattern = fillPattern;
            }
            if (hasFillGradient) {
                ctx.fillStyle = fillGradient;
            }
            else if (hasFillPattern) {
                if (fillPattern) {
                    ctx.fillStyle = fillPattern;
                }
                else {
                    hasFill = false;
                }
            }
            if (hasStrokeGradient) {
                ctx.strokeStyle = strokeGradient;
            }
            else if (hasStrokePattern) {
                if (strokePattern) {
                    ctx.strokeStyle = strokePattern;
                }
                else {
                    hasStroke = false;
                }
            }
        }
        var scale = el.getGlobalScale();
        path.setScale(scale[0], scale[1], el.segmentIgnoreThreshold);
        var lineDash;
        var lineDashOffset;
        if (ctx.setLineDash && style.lineDash) {
            _a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1];
        }
        var needsRebuild = true;
        if (firstDraw || (dirtyFlag & SHAPE_CHANGED_BIT)) {
            path.setDPR(ctx.dpr);
            if (strokePart) {
                path.setContext(null);
            }
            else {
                path.setContext(ctx);
                needsRebuild = false;
            }
            path.reset();
            el.buildPath(path, el.shape, inBatch);
            path.toStatic();
            el.pathUpdated();
        }
        if (needsRebuild) {
            path.rebuildPath(ctx, strokePart ? strokePercent : 1);
        }
        if (lineDash) {
            ctx.setLineDash(lineDash);
            ctx.lineDashOffset = lineDashOffset;
        }
        if (!inBatch) {
            if (style.strokeFirst) {
                if (hasStroke) {
                    doStrokePath(ctx, style);
                }
                if (hasFill) {
                    doFillPath(ctx, style);
                }
            }
            else {
                if (hasFill) {
                    doFillPath(ctx, style);
                }
                if (hasStroke) {
                    doStrokePath(ctx, style);
                }
            }
        }
        if (lineDash) {
            ctx.setLineDash([]);
        }
    }
    function brushImage(ctx, el, style) {
        var image = el.__image = createOrUpdateImage(style.image, el.__image, el, el.onload);
        if (!image || !isImageReady(image)) {
            return;
        }
        var x = style.x || 0;
        var y = style.y || 0;
        var width = el.getWidth();
        var height = el.getHeight();
        var aspect = image.width / image.height;
        if (width == null && height != null) {
            width = height * aspect;
        }
        else if (height == null && width != null) {
            height = width / aspect;
        }
        else if (width == null && height == null) {
            width = image.width;
            height = image.height;
        }
        if (style.sWidth && style.sHeight) {
            var sx = style.sx || 0;
            var sy = style.sy || 0;
            ctx.drawImage(image, sx, sy, style.sWidth, style.sHeight, x, y, width, height);
        }
        else if (style.sx && style.sy) {
            var sx = style.sx;
            var sy = style.sy;
            var sWidth = width - sx;
            var sHeight = height - sy;
            ctx.drawImage(image, sx, sy, sWidth, sHeight, x, y, width, height);
        }
        else {
            ctx.drawImage(image, x, y, width, height);
        }
    }
    function brushText(ctx, el, style) {
        var _a;
        var text = style.text;
        text != null && (text += '');
        if (text) {
            ctx.font = style.font || DEFAULT_FONT;
            ctx.textAlign = style.textAlign;
            ctx.textBaseline = style.textBaseline;
            var lineDash = void 0;
            var lineDashOffset = void 0;
            if (ctx.setLineDash && style.lineDash) {
                _a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1];
            }
            if (lineDash) {
                ctx.setLineDash(lineDash);
                ctx.lineDashOffset = lineDashOffset;
            }
            if (style.strokeFirst) {
                if (styleHasStroke(style)) {
                    ctx.strokeText(text, style.x, style.y);
                }
                if (styleHasFill(style)) {
                    ctx.fillText(text, style.x, style.y);
                }
            }
            else {
                if (styleHasFill(style)) {
                    ctx.fillText(text, style.x, style.y);
                }
                if (styleHasStroke(style)) {
                    ctx.strokeText(text, style.x, style.y);
                }
            }
            if (lineDash) {
                ctx.setLineDash([]);
            }
        }
    }
    var SHADOW_NUMBER_PROPS = ['shadowBlur', 'shadowOffsetX', 'shadowOffsetY'];
    var STROKE_PROPS = [
        ['lineCap', 'butt'], ['lineJoin', 'miter'], ['miterLimit', 10]
    ];
    function bindCommonProps(ctx, style, prevStyle, forceSetAll, scope) {
        var styleChanged = false;
        if (!forceSetAll) {
            prevStyle = prevStyle || {};
            if (style === prevStyle) {
                return false;
            }
        }
        if (forceSetAll || style.opacity !== prevStyle.opacity) {
            flushPathDrawn(ctx, scope);
            styleChanged = true;
            var opacity = Math.max(Math.min(style.opacity, 1), 0);
            ctx.globalAlpha = isNaN(opacity) ? DEFAULT_COMMON_STYLE.opacity : opacity;
        }
        if (forceSetAll || style.blend !== prevStyle.blend) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            ctx.globalCompositeOperation = style.blend || DEFAULT_COMMON_STYLE.blend;
        }
        for (var i = 0; i < SHADOW_NUMBER_PROPS.length; i++) {
            var propName = SHADOW_NUMBER_PROPS[i];
            if (forceSetAll || style[propName] !== prevStyle[propName]) {
                if (!styleChanged) {
                    flushPathDrawn(ctx, scope);
                    styleChanged = true;
                }
                ctx[propName] = ctx.dpr * (style[propName] || 0);
            }
        }
        if (forceSetAll || style.shadowColor !== prevStyle.shadowColor) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            ctx.shadowColor = style.shadowColor || DEFAULT_COMMON_STYLE.shadowColor;
        }
        return styleChanged;
    }
    function bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetAll, scope) {
        var style = getStyle(el, scope.inHover);
        var prevStyle = forceSetAll
            ? null
            : (prevEl && getStyle(prevEl, scope.inHover) || {});
        if (style === prevStyle) {
            return false;
        }
        var styleChanged = bindCommonProps(ctx, style, prevStyle, forceSetAll, scope);
        if (forceSetAll || style.fill !== prevStyle.fill) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            isValidStrokeFillStyle(style.fill) && (ctx.fillStyle = style.fill);
        }
        if (forceSetAll || style.stroke !== prevStyle.stroke) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            isValidStrokeFillStyle(style.stroke) && (ctx.strokeStyle = style.stroke);
        }
        if (forceSetAll || style.opacity !== prevStyle.opacity) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            ctx.globalAlpha = style.opacity == null ? 1 : style.opacity;
        }
        if (el.hasStroke()) {
            var lineWidth = style.lineWidth;
            var newLineWidth = lineWidth / ((style.strokeNoScale && el.getLineScale) ? el.getLineScale() : 1);
            if (ctx.lineWidth !== newLineWidth) {
                if (!styleChanged) {
                    flushPathDrawn(ctx, scope);
                    styleChanged = true;
                }
                ctx.lineWidth = newLineWidth;
            }
        }
        for (var i = 0; i < STROKE_PROPS.length; i++) {
            var prop = STROKE_PROPS[i];
            var propName = prop[0];
            if (forceSetAll || style[propName] !== prevStyle[propName]) {
                if (!styleChanged) {
                    flushPathDrawn(ctx, scope);
                    styleChanged = true;
                }
                ctx[propName] = style[propName] || prop[1];
            }
        }
        return styleChanged;
    }
    function bindImageStyle(ctx, el, prevEl, forceSetAll, scope) {
        return bindCommonProps(ctx, getStyle(el, scope.inHover), prevEl && getStyle(prevEl, scope.inHover), forceSetAll, scope);
    }
    function setContextTransform(ctx, el) {
        var m = el.transform;
        var dpr = ctx.dpr || 1;
        if (m) {
            ctx.setTransform(dpr * m[0], dpr * m[1], dpr * m[2], dpr * m[3], dpr * m[4], dpr * m[5]);
        }
        else {
            ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
        }
    }
    function updateClipStatus(clipPaths, ctx, scope) {
        var allClipped = false;
        for (var i = 0; i < clipPaths.length; i++) {
            var clipPath = clipPaths[i];
            allClipped = allClipped || clipPath.isZeroArea();
            setContextTransform(ctx, clipPath);
            ctx.beginPath();
            clipPath.buildPath(ctx, clipPath.shape);
            ctx.clip();
        }
        scope.allClipped = allClipped;
    }
    function isTransformChanged(m0, m1) {
        if (m0 && m1) {
            return m0[0] !== m1[0]
                || m0[1] !== m1[1]
                || m0[2] !== m1[2]
                || m0[3] !== m1[3]
                || m0[4] !== m1[4]
                || m0[5] !== m1[5];
        }
        else if (!m0 && !m1) {
            return false;
        }
        return true;
    }
    var DRAW_TYPE_PATH = 1;
    var DRAW_TYPE_IMAGE = 2;
    var DRAW_TYPE_TEXT = 3;
    var DRAW_TYPE_INCREMENTAL = 4;
    function canPathBatch(style) {
        var hasFill = styleHasFill(style);
        var hasStroke = styleHasStroke(style);
        return !(style.lineDash
            || !(+hasFill ^ +hasStroke)
            || (hasFill && typeof style.fill !== 'string')
            || (hasStroke && typeof style.stroke !== 'string')
            || style.strokePercent < 1
            || style.strokeOpacity < 1
            || style.fillOpacity < 1);
    }
    function flushPathDrawn(ctx, scope) {
        scope.batchFill && ctx.fill();
        scope.batchStroke && ctx.stroke();
        scope.batchFill = '';
        scope.batchStroke = '';
    }
    function getStyle(el, inHover) {
        return inHover ? (el.__hoverStyle || el.style) : el.style;
    }
    function brushSingle(ctx, el) {
        brush(ctx, el, { inHover: false, viewWidth: 0, viewHeight: 0 }, true);
    }
    function brush(ctx, el, scope, isLast) {
        var m = el.transform;
        if (!el.shouldBePainted(scope.viewWidth, scope.viewHeight, false, false)) {
            el.__dirty &= ~REDRAW_BIT;
            el.__isRendered = false;
            return;
        }
        var clipPaths = el.__clipPaths;
        var prevElClipPaths = scope.prevElClipPaths;
        var forceSetTransform = false;
        var forceSetStyle = false;
        if (!prevElClipPaths || isClipPathChanged(clipPaths, prevElClipPaths)) {
            if (prevElClipPaths && prevElClipPaths.length) {
                flushPathDrawn(ctx, scope);
                ctx.restore();
                forceSetStyle = forceSetTransform = true;
                scope.prevElClipPaths = null;
                scope.allClipped = false;
                scope.prevEl = null;
            }
            if (clipPaths && clipPaths.length) {
                flushPathDrawn(ctx, scope);
                ctx.save();
                updateClipStatus(clipPaths, ctx, scope);
                forceSetTransform = true;
            }
            scope.prevElClipPaths = clipPaths;
        }
        if (scope.allClipped) {
            el.__isRendered = false;
            return;
        }
        el.beforeBrush && el.beforeBrush();
        el.innerBeforeBrush();
        var prevEl = scope.prevEl;
        if (!prevEl) {
            forceSetStyle = forceSetTransform = true;
        }
        var canBatchPath = el instanceof Path
            && el.autoBatch
            && canPathBatch(el.style);
        if (forceSetTransform || isTransformChanged(m, prevEl.transform)) {
            flushPathDrawn(ctx, scope);
            setContextTransform(ctx, el);
        }
        else if (!canBatchPath) {
            flushPathDrawn(ctx, scope);
        }
        var style = getStyle(el, scope.inHover);
        if (el instanceof Path) {
            if (scope.lastDrawType !== DRAW_TYPE_PATH) {
                forceSetStyle = true;
                scope.lastDrawType = DRAW_TYPE_PATH;
            }
            bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetStyle, scope);
            if (!canBatchPath || (!scope.batchFill && !scope.batchStroke)) {
                ctx.beginPath();
            }
            brushPath(ctx, el, style, canBatchPath);
            if (canBatchPath) {
                scope.batchFill = style.fill || '';
                scope.batchStroke = style.stroke || '';
            }
        }
        else {
            if (el instanceof TSpan) {
                if (scope.lastDrawType !== DRAW_TYPE_TEXT) {
                    forceSetStyle = true;
                    scope.lastDrawType = DRAW_TYPE_TEXT;
                }
                bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetStyle, scope);
                brushText(ctx, el, style);
            }
            else if (el instanceof ZRImage) {
                if (scope.lastDrawType !== DRAW_TYPE_IMAGE) {
                    forceSetStyle = true;
                    scope.lastDrawType = DRAW_TYPE_IMAGE;
                }
                bindImageStyle(ctx, el, prevEl, forceSetStyle, scope);
                brushImage(ctx, el, style);
            }
            else if (el.getTemporalDisplayables) {
                if (scope.lastDrawType !== DRAW_TYPE_INCREMENTAL) {
                    forceSetStyle = true;
                    scope.lastDrawType = DRAW_TYPE_INCREMENTAL;
                }
                brushIncremental(ctx, el, scope);
            }
        }
        if (canBatchPath && isLast) {
            flushPathDrawn(ctx, scope);
        }
        el.innerAfterBrush();
        el.afterBrush && el.afterBrush();
        scope.prevEl = el;
        el.__dirty = 0;
        el.__isRendered = true;
    }
    function brushIncremental(ctx, el, scope) {
        var displayables = el.getDisplayables();
        var temporalDisplayables = el.getTemporalDisplayables();
        ctx.save();
        var innerScope = {
            prevElClipPaths: null,
            prevEl: null,
            allClipped: false,
            viewWidth: scope.viewWidth,
            viewHeight: scope.viewHeight,
            inHover: scope.inHover
        };
        var i;
        var len;
        for (i = el.getCursor(), len = displayables.length; i < len; i++) {
            var displayable = displayables[i];
            displayable.beforeBrush && displayable.beforeBrush();
            displayable.innerBeforeBrush();
            brush(ctx, displayable, innerScope, i === len - 1);
            displayable.innerAfterBrush();
            displayable.afterBrush && displayable.afterBrush();
            innerScope.prevEl = displayable;
        }
        for (var i_1 = 0, len_1 = temporalDisplayables.length; i_1 < len_1; i_1++) {
            var displayable = temporalDisplayables[i_1];
            displayable.beforeBrush && displayable.beforeBrush();
            displayable.innerBeforeBrush();
            brush(ctx, displayable, innerScope, i_1 === len_1 - 1);
            displayable.innerAfterBrush();
            displayable.afterBrush && displayable.afterBrush();
            innerScope.prevEl = displayable;
        }
        el.clearTemporalDisplayables();
        el.notClear = true;
        ctx.restore();
    }

    var decalMap = new WeakMap();
    var decalCache = new LRU(100);
    var decalKeys = ['symbol', 'symbolSize', 'symbolKeepAspect', 'color', 'backgroundColor', 'dashArrayX', 'dashArrayY', 'maxTileWidth', 'maxTileHeight'];
    /**
     * Create or update pattern image from decal options
     *
     * @param {InnerDecalObject | 'none'} decalObject decal options, 'none' if no decal
     * @return {Pattern} pattern with generated image, null if no decal
     */

    function createOrUpdatePatternFromDecal(decalObject, api) {
      if (decalObject === 'none') {
        return null;
      }

      var dpr = api.getDevicePixelRatio();
      var zr = api.getZr();
      var isSVG = zr.painter.type === 'svg';

      if (decalObject.dirty) {
        decalMap["delete"](decalObject);
      }

      var oldPattern = decalMap.get(decalObject);

      if (oldPattern) {
        return oldPattern;
      }

      var decalOpt = defaults(decalObject, {
        symbol: 'rect',
        symbolSize: 1,
        symbolKeepAspect: true,
        color: 'rgba(0, 0, 0, 0.2)',
        backgroundColor: null,
        dashArrayX: 5,
        dashArrayY: 5,
        rotation: 0,
        maxTileWidth: 512,
        maxTileHeight: 512
      });

      if (decalOpt.backgroundColor === 'none') {
        decalOpt.backgroundColor = null;
      }

      var pattern = {
        repeat: 'repeat'
      };
      setPatternnSource(pattern);
      pattern.rotation = decalOpt.rotation;
      pattern.scaleX = pattern.scaleY = isSVG ? 1 : 1 / dpr;
      decalMap.set(decalObject, pattern);
      decalObject.dirty = false;
      return pattern;

      function setPatternnSource(pattern) {
        var keys = [dpr];
        var isValidKey = true;

        for (var i = 0; i < decalKeys.length; ++i) {
          var value = decalOpt[decalKeys[i]];

          if (value != null && !isArray(value) && !isString(value) && !isNumber(value) && typeof value !== 'boolean') {
            isValidKey = false;
            break;
          }

          keys.push(value);
        }

        var cacheKey;

        if (isValidKey) {
          cacheKey = keys.join(',') + (isSVG ? '-svg' : '');
          var cache = decalCache.get(cacheKey);

          if (cache) {
            isSVG ? pattern.svgElement = cache : pattern.image = cache;
          }
        }

        var dashArrayX = normalizeDashArrayX(decalOpt.dashArrayX);
        var dashArrayY = normalizeDashArrayY(decalOpt.dashArrayY);
        var symbolArray = normalizeSymbolArray(decalOpt.symbol);
        var lineBlockLengthsX = getLineBlockLengthX(dashArrayX);
        var lineBlockLengthY = getLineBlockLengthY(dashArrayY);
        var canvas = !isSVG && platformApi.createCanvas();
        var svgRoot = isSVG && {
          tag: 'g',
          attrs: {},
          key: 'dcl',
          children: []
        };
        var pSize = getPatternSize();
        var ctx;

        if (canvas) {
          canvas.width = pSize.width * dpr;
          canvas.height = pSize.height * dpr;
          ctx = canvas.getContext('2d');
        }

        brushDecal();

        if (isValidKey) {
          decalCache.put(cacheKey, canvas || svgRoot);
        }

        pattern.image = canvas;
        pattern.svgElement = svgRoot;
        pattern.svgWidth = pSize.width;
        pattern.svgHeight = pSize.height;
        /**
         * Get minimum length that can make a repeatable pattern.
         *
         * @return {Object} pattern width and height
         */

        function getPatternSize() {
          /**
           * For example, if dash is [[3, 2], [2, 1]] for X, it looks like
           * |---  ---  ---  ---  --- ...
           * |-- -- -- -- -- -- -- -- ...
           * |---  ---  ---  ---  --- ...
           * |-- -- -- -- -- -- -- -- ...
           * So the minimum length of X is 15,
           * which is the least common multiple of `3 + 2` and `2 + 1`
           * |---  ---  ---  |---  --- ...
           * |-- -- -- -- -- |-- -- -- ...
           */
          var width = 1;

          for (var i = 0, xlen = lineBlockLengthsX.length; i < xlen; ++i) {
            width = getLeastCommonMultiple(width, lineBlockLengthsX[i]);
          }

          var symbolRepeats = 1;

          for (var i = 0, xlen = symbolArray.length; i < xlen; ++i) {
            symbolRepeats = getLeastCommonMultiple(symbolRepeats, symbolArray[i].length);
          }

          width *= symbolRepeats;
          var height = lineBlockLengthY * lineBlockLengthsX.length * symbolArray.length;

          if ("development" !== 'production') {
            var warn = function (attrName) {
              /* eslint-disable-next-line */
              console.warn("Calculated decal size is greater than " + attrName + " due to decal option settings so " + attrName + " is used for the decal size. Please consider changing the decal option to make a smaller decal or set " + attrName + " to be larger to avoid incontinuity.");
            };

            if (width > decalOpt.maxTileWidth) {
              warn('maxTileWidth');
            }

            if (height > decalOpt.maxTileHeight) {
              warn('maxTileHeight');
            }
          }

          return {
            width: Math.max(1, Math.min(width, decalOpt.maxTileWidth)),
            height: Math.max(1, Math.min(height, decalOpt.maxTileHeight))
          };
        }

        function brushDecal() {
          if (ctx) {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            if (decalOpt.backgroundColor) {
              ctx.fillStyle = decalOpt.backgroundColor;
              ctx.fillRect(0, 0, canvas.width, canvas.height);
            }
          }

          var ySum = 0;

          for (var i = 0; i < dashArrayY.length; ++i) {
            ySum += dashArrayY[i];
          }

          if (ySum <= 0) {
            // dashArrayY is 0, draw nothing
            return;
          }

          var y = -lineBlockLengthY;
          var yId = 0;
          var yIdTotal = 0;
          var xId0 = 0;

          while (y < pSize.height) {
            if (yId % 2 === 0) {
              var symbolYId = yIdTotal / 2 % symbolArray.length;
              var x = 0;
              var xId1 = 0;
              var xId1Total = 0;

              while (x < pSize.width * 2) {
                var xSum = 0;

                for (var i = 0; i < dashArrayX[xId0].length; ++i) {
                  xSum += dashArrayX[xId0][i];
                }

                if (xSum <= 0) {
                  // Skip empty line
                  break;
                } // E.g., [15, 5, 20, 5] draws only for 15 and 20


                if (xId1 % 2 === 0) {
                  var size = (1 - decalOpt.symbolSize) * 0.5;
                  var left = x + dashArrayX[xId0][xId1] * size;
                  var top_1 = y + dashArrayY[yId] * size;
                  var width = dashArrayX[xId0][xId1] * decalOpt.symbolSize;
                  var height = dashArrayY[yId] * decalOpt.symbolSize;
                  var symbolXId = xId1Total / 2 % symbolArray[symbolYId].length;
                  brushSymbol(left, top_1, width, height, symbolArray[symbolYId][symbolXId]);
                }

                x += dashArrayX[xId0][xId1];
                ++xId1Total;
                ++xId1;

                if (xId1 === dashArrayX[xId0].length) {
                  xId1 = 0;
                }
              }

              ++xId0;

              if (xId0 === dashArrayX.length) {
                xId0 = 0;
              }
            }

            y += dashArrayY[yId];
            ++yIdTotal;
            ++yId;

            if (yId === dashArrayY.length) {
              yId = 0;
            }
          }

          function brushSymbol(x, y, width, height, symbolType) {
            var scale = isSVG ? 1 : dpr;
            var symbol = createSymbol(symbolType, x * scale, y * scale, width * scale, height * scale, decalOpt.color, decalOpt.symbolKeepAspect);

            if (isSVG) {
              var symbolVNode = zr.painter.renderOneToVNode(symbol);

              if (symbolVNode) {
                svgRoot.children.push(symbolVNode);
              }
            } else {
              // Paint to canvas for all other renderers.
              brushSingle(ctx, symbol);
            }
          }
        }
      }
    }
    /**
     * Convert symbol array into normalized array
     *
     * @param {string | (string | string[])[]} symbol symbol input
     * @return {string[][]} normolized symbol array
     */

    function normalizeSymbolArray(symbol) {
      if (!symbol || symbol.length === 0) {
        return [['rect']];
      }

      if (isString(symbol)) {
        return [[symbol]];
      }

      var isAllString = true;

      for (var i = 0; i < symbol.length; ++i) {
        if (!isString(symbol[i])) {
          isAllString = false;
          break;
        }
      }

      if (isAllString) {
        return normalizeSymbolArray([symbol]);
      }

      var result = [];

      for (var i = 0; i < symbol.length; ++i) {
        if (isString(symbol[i])) {
          result.push([symbol[i]]);
        } else {
          result.push(symbol[i]);
        }
      }

      return result;
    }
    /**
     * Convert dash input into dashArray
     *
     * @param {DecalDashArrayX} dash dash input
     * @return {number[][]} normolized dash array
     */


    function normalizeDashArrayX(dash) {
      if (!dash || dash.length === 0) {
        return [[0, 0]];
      }

      if (isNumber(dash)) {
        var dashValue = Math.ceil(dash);
        return [[dashValue, dashValue]];
      }
      /**
       * [20, 5] should be normalized into [[20, 5]],
       * while [20, [5, 10]] should be normalized into [[20, 20], [5, 10]]
       */


      var isAllNumber = true;

      for (var i = 0; i < dash.length; ++i) {
        if (!isNumber(dash[i])) {
          isAllNumber = false;
          break;
        }
      }

      if (isAllNumber) {
        return normalizeDashArrayX([dash]);
      }

      var result = [];

      for (var i = 0; i < dash.length; ++i) {
        if (isNumber(dash[i])) {
          var dashValue = Math.ceil(dash[i]);
          result.push([dashValue, dashValue]);
        } else {
          var dashValue = map(dash[i], function (n) {
            return Math.ceil(n);
          });

          if (dashValue.length % 2 === 1) {
            // [4, 2, 1] means |----  -    -- |----  -    -- |
            // so normalize it to be [4, 2, 1, 4, 2, 1]
            result.push(dashValue.concat(dashValue));
          } else {
            result.push(dashValue);
          }
        }
      }

      return result;
    }
    /**
     * Convert dash input into dashArray
     *
     * @param {DecalDashArrayY} dash dash input
     * @return {number[]} normolized dash array
     */


    function normalizeDashArrayY(dash) {
      if (!dash || typeof dash === 'object' && dash.length === 0) {
        return [0, 0];
      }

      if (isNumber(dash)) {
        var dashValue_1 = Math.ceil(dash);
        return [dashValue_1, dashValue_1];
      }

      var dashValue = map(dash, function (n) {
        return Math.ceil(n);
      });
      return dash.length % 2 ? dashValue.concat(dashValue) : dashValue;
    }
    /**
     * Get block length of each line. A block is the length of dash line and space.
     * For example, a line with [4, 1] has a dash line of 4 and a space of 1 after
     * that, so the block length of this line is 5.
     *
     * @param {number[][]} dash dash array of X or Y
     * @return {number[]} block length of each line
     */


    function getLineBlockLengthX(dash) {
      return map(dash, function (line) {
        return getLineBlockLengthY(line);
      });
    }

    function getLineBlockLengthY(dash) {
      var blockLength = 0;

      for (var i = 0; i < dash.length; ++i) {
        blockLength += dash[i];
      }

      if (dash.length % 2 === 1) {
        // [4, 2, 1] means |----  -    -- |----  -    -- |
        // So total length is (4 + 2 + 1) * 2
        return blockLength * 2;
      }

      return blockLength;
    }

    function decalVisual(ecModel, api) {
      ecModel.eachRawSeries(function (seriesModel) {
        if (ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var data = seriesModel.getData();

        if (data.hasItemVisual()) {
          data.each(function (idx) {
            var decal = data.getItemVisual(idx, 'decal');

            if (decal) {
              var itemStyle = data.ensureUniqueItemVisual(idx, 'style');
              itemStyle.decal = createOrUpdatePatternFromDecal(decal, api);
            }
          });
        }

        var decal = data.getVisual('decal');

        if (decal) {
          var style = data.getVisual('style');
          style.decal = createOrUpdatePatternFromDecal(decal, api);
        }
      });
    }

    var lifecycle = new Eventful();

    // The implementations will be registered when installing the component.
    // Avoid these code being bundled to the core module.

    var implsStore = {}; // TODO Type

    function registerImpl(name, impl) {
      if ("development" !== 'production') {
        if (implsStore[name]) {
          error("Already has an implementation of " + name + ".");
        }
      }

      implsStore[name] = impl;
    }
    function getImpl(name) {
      if ("development" !== 'production') {
        if (!implsStore[name]) {
          error("Implementation of " + name + " doesn't exists.");
        }
      }

      return implsStore[name];
    }

    var hasWindow = typeof window !== 'undefined';
    var version$1 = '5.4.0';
    var dependencies = {
      zrender: '5.4.0'
    };
    var TEST_FRAME_REMAIN_TIME = 1;
    var PRIORITY_PROCESSOR_SERIES_FILTER = 800; // Some data processors depends on the stack result dimension (to calculate data extent).
    // So data stack stage should be in front of data processing stage.

    var PRIORITY_PROCESSOR_DATASTACK = 900; // "Data filter" will block the stream, so it should be
    // put at the beginning of data processing.

    var PRIORITY_PROCESSOR_FILTER = 1000;
    var PRIORITY_PROCESSOR_DEFAULT = 2000;
    var PRIORITY_PROCESSOR_STATISTIC = 5000;
    var PRIORITY_VISUAL_LAYOUT = 1000;
    var PRIORITY_VISUAL_PROGRESSIVE_LAYOUT = 1100;
    var PRIORITY_VISUAL_GLOBAL = 2000;
    var PRIORITY_VISUAL_CHART = 3000;
    var PRIORITY_VISUAL_COMPONENT = 4000; // Visual property in data. Greater than `PRIORITY_VISUAL_COMPONENT` to enable to
    // overwrite the viusal result of component (like `visualMap`)
    // using data item specific setting (like itemStyle.xxx on data item)

    var PRIORITY_VISUAL_CHART_DATA_CUSTOM = 4500; // Greater than `PRIORITY_VISUAL_CHART_DATA_CUSTOM` to enable to layout based on
    // visual result like `symbolSize`.

    var PRIORITY_VISUAL_POST_CHART_LAYOUT = 4600;
    var PRIORITY_VISUAL_BRUSH = 5000;
    var PRIORITY_VISUAL_ARIA = 6000;
    var PRIORITY_VISUAL_DECAL = 7000;
    var PRIORITY = {
      PROCESSOR: {
        FILTER: PRIORITY_PROCESSOR_FILTER,
        SERIES_FILTER: PRIORITY_PROCESSOR_SERIES_FILTER,
        STATISTIC: PRIORITY_PROCESSOR_STATISTIC
      },
      VISUAL: {
        LAYOUT: PRIORITY_VISUAL_LAYOUT,
        PROGRESSIVE_LAYOUT: PRIORITY_VISUAL_PROGRESSIVE_LAYOUT,
        GLOBAL: PRIORITY_VISUAL_GLOBAL,
        CHART: PRIORITY_VISUAL_CHART,
        POST_CHART_LAYOUT: PRIORITY_VISUAL_POST_CHART_LAYOUT,
        COMPONENT: PRIORITY_VISUAL_COMPONENT,
        BRUSH: PRIORITY_VISUAL_BRUSH,
        CHART_ITEM: PRIORITY_VISUAL_CHART_DATA_CUSTOM,
        ARIA: PRIORITY_VISUAL_ARIA,
        DECAL: PRIORITY_VISUAL_DECAL
      }
    }; // Main process have three entries: `setOption`, `dispatchAction` and `resize`,
    // where they must not be invoked nestedly, except the only case: invoke
    // dispatchAction with updateMethod "none" in main process.
    // This flag is used to carry out this rule.
    // All events will be triggered out side main process (i.e. when !this[IN_MAIN_PROCESS]).

    var IN_MAIN_PROCESS_KEY = '__flagInMainProcess';
    var PENDING_UPDATE = '__pendingUpdate';
    var STATUS_NEEDS_UPDATE_KEY = '__needsUpdateStatus';
    var ACTION_REG = /^[a-zA-Z0-9_]+$/;
    var CONNECT_STATUS_KEY = '__connectUpdateStatus';
    var CONNECT_STATUS_PENDING = 0;
    var CONNECT_STATUS_UPDATING = 1;
    var CONNECT_STATUS_UPDATED = 2;

    function createRegisterEventWithLowercaseECharts(method) {
      return function () {
        var args = [];

        for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
        }

        if (this.isDisposed()) {
          disposedWarning(this.id);
          return;
        }

        return toLowercaseNameAndCallEventful(this, method, args);
      };
    }

    function createRegisterEventWithLowercaseMessageCenter(method) {
      return function () {
        var args = [];

        for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
        }

        return toLowercaseNameAndCallEventful(this, method, args);
      };
    }

    function toLowercaseNameAndCallEventful(host, method, args) {
      // `args[0]` is event name. Event name is all lowercase.
      args[0] = args[0] && args[0].toLowerCase();
      return Eventful.prototype[method].apply(host, args);
    }

    var MessageCenter =
    /** @class */
    function (_super) {
      __extends(MessageCenter, _super);

      function MessageCenter() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      return MessageCenter;
    }(Eventful);

    var messageCenterProto = MessageCenter.prototype;
    messageCenterProto.on = createRegisterEventWithLowercaseMessageCenter('on');
    messageCenterProto.off = createRegisterEventWithLowercaseMessageCenter('off'); // ---------------------------------------
    // Internal method names for class ECharts
    // ---------------------------------------

    var prepare;
    var prepareView;
    var updateDirectly;
    var updateMethods;
    var doConvertPixel;
    var updateStreamModes;
    var doDispatchAction;
    var flushPendingActions;
    var triggerUpdatedEvent;
    var bindRenderedEvent;
    var bindMouseEvent;
    var render;
    var renderComponents;
    var renderSeries;
    var createExtensionAPI;
    var enableConnect;
    var markStatusToUpdate;
    var applyChangedStates;

    var ECharts =
    /** @class */
    function (_super) {
      __extends(ECharts, _super);

      function ECharts(dom, // Theme name or themeOption.
      theme, opts) {
        var _this = _super.call(this, new ECEventProcessor()) || this;

        _this._chartsViews = [];
        _this._chartsMap = {};
        _this._componentsViews = [];
        _this._componentsMap = {}; // Can't dispatch action during rendering procedure

        _this._pendingActions = [];
        opts = opts || {}; // Get theme by name

        if (isString(theme)) {
          theme = themeStorage[theme];
        }

        _this._dom = dom;
        var defaultRenderer = 'canvas';
        var defaultCoarsePointer = 'auto';
        var defaultUseDirtyRect = false;

        if ("development" !== 'production') {
          var root =
          /* eslint-disable-next-line */
          hasWindow ? window : global;
          defaultRenderer = root.__ECHARTS__DEFAULT__RENDERER__ || defaultRenderer;
          defaultCoarsePointer = retrieve2(root.__ECHARTS__DEFAULT__COARSE_POINTER, defaultCoarsePointer);
          var devUseDirtyRect = root.__ECHARTS__DEFAULT__USE_DIRTY_RECT__;
          defaultUseDirtyRect = devUseDirtyRect == null ? defaultUseDirtyRect : devUseDirtyRect;
        }

        var zr = _this._zr = init(dom, {
          renderer: opts.renderer || defaultRenderer,
          devicePixelRatio: opts.devicePixelRatio,
          width: opts.width,
          height: opts.height,
          ssr: opts.ssr,
          useDirtyRect: retrieve2(opts.useDirtyRect, defaultUseDirtyRect),
          useCoarsePointer: retrieve2(opts.useCoarsePointer, defaultCoarsePointer),
          pointerSize: opts.pointerSize
        });
        _this._ssr = opts.ssr; // Expect 60 fps.

        _this._throttledZrFlush = throttle(bind(zr.flush, zr), 17);
        theme = clone(theme);
        theme && globalBackwardCompat(theme, true);
        _this._theme = theme;
        _this._locale = createLocaleObject(opts.locale || SYSTEM_LANG);
        _this._coordSysMgr = new CoordinateSystemManager();
        var api = _this._api = createExtensionAPI(_this); // Sort on demand

        function prioritySortFunc(a, b) {
          return a.__prio - b.__prio;
        }

        sort(visualFuncs, prioritySortFunc);
        sort(dataProcessorFuncs, prioritySortFunc);
        _this._scheduler = new Scheduler(_this, api, dataProcessorFuncs, visualFuncs);
        _this._messageCenter = new MessageCenter(); // Init mouse events

        _this._initEvents(); // In case some people write `window.onresize = chart.resize`


        _this.resize = bind(_this.resize, _this);
        zr.animation.on('frame', _this._onframe, _this);
        bindRenderedEvent(zr, _this);
        bindMouseEvent(zr, _this); // ECharts instance can be used as value.

        setAsPrimitive(_this);
        return _this;
      }

      ECharts.prototype._onframe = function () {
        if (this._disposed) {
          return;
        }

        applyChangedStates(this);
        var scheduler = this._scheduler; // Lazy update

        if (this[PENDING_UPDATE]) {
          var silent = this[PENDING_UPDATE].silent;
          this[IN_MAIN_PROCESS_KEY] = true;

          try {
            prepare(this);
            updateMethods.update.call(this, null, this[PENDING_UPDATE].updateParams);
          } catch (e) {
            this[IN_MAIN_PROCESS_KEY] = false;
            this[PENDING_UPDATE] = null;
            throw e;
          } // At present, in each frame, zrender performs:
          //   (1) animation step forward.
          //   (2) trigger('frame') (where this `_onframe` is called)
          //   (3) zrender flush (render).
          // If we do nothing here, since we use `setToFinal: true`, the step (3) above
          // will render the final state of the elements before the real animation started.


          this._zr.flush();

          this[IN_MAIN_PROCESS_KEY] = false;
          this[PENDING_UPDATE] = null;
          flushPendingActions.call(this, silent);
          triggerUpdatedEvent.call(this, silent);
        } // Avoid do both lazy update and progress in one frame.
        else if (scheduler.unfinished) {
            // Stream progress.
            var remainTime = TEST_FRAME_REMAIN_TIME;
            var ecModel = this._model;
            var api = this._api;
            scheduler.unfinished = false;

            do {
              var startTime = +new Date();
              scheduler.performSeriesTasks(ecModel); // Currently dataProcessorFuncs do not check threshold.

              scheduler.performDataProcessorTasks(ecModel);
              updateStreamModes(this, ecModel); // Do not update coordinate system here. Because that coord system update in
              // each frame is not a good user experience. So we follow the rule that
              // the extent of the coordinate system is determined in the first frame (the
              // frame is executed immediately after task reset.
              // this._coordSysMgr.update(ecModel, api);
              // console.log('--- ec frame visual ---', remainTime);

              scheduler.performVisualTasks(ecModel);
              renderSeries(this, this._model, api, 'remain', {});
              remainTime -= +new Date() - startTime;
            } while (remainTime > 0 && scheduler.unfinished); // Call flush explicitly for trigger finished event.


            if (!scheduler.unfinished) {
              this._zr.flush();
            } // Else, zr flushing be ensue within the same frame,
            // because zr flushing is after onframe event.

          }
      };

      ECharts.prototype.getDom = function () {
        return this._dom;
      };

      ECharts.prototype.getId = function () {
        return this.id;
      };

      ECharts.prototype.getZr = function () {
        return this._zr;
      };

      ECharts.prototype.isSSR = function () {
        return this._ssr;
      };
      /* eslint-disable-next-line */


      ECharts.prototype.setOption = function (option, notMerge, lazyUpdate) {
        if (this[IN_MAIN_PROCESS_KEY]) {
          if ("development" !== 'production') {
            error('`setOption` should not be called during main process.');
          }

          return;
        }

        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        var silent;
        var replaceMerge;
        var transitionOpt;

        if (isObject(notMerge)) {
          lazyUpdate = notMerge.lazyUpdate;
          silent = notMerge.silent;
          replaceMerge = notMerge.replaceMerge;
          transitionOpt = notMerge.transition;
          notMerge = notMerge.notMerge;
        }

        this[IN_MAIN_PROCESS_KEY] = true;

        if (!this._model || notMerge) {
          var optionManager = new OptionManager(this._api);
          var theme = this._theme;
          var ecModel = this._model = new GlobalModel();
          ecModel.scheduler = this._scheduler;
          ecModel.ssr = this._ssr;
          ecModel.init(null, null, null, theme, this._locale, optionManager);
        }

        this._model.setOption(option, {
          replaceMerge: replaceMerge
        }, optionPreprocessorFuncs);

        var updateParams = {
          seriesTransition: transitionOpt,
          optionChanged: true
        };

        if (lazyUpdate) {
          this[PENDING_UPDATE] = {
            silent: silent,
            updateParams: updateParams
          };
          this[IN_MAIN_PROCESS_KEY] = false; // `setOption(option, {lazyMode: true})` may be called when zrender has been slept.
          // It should wake it up to make sure zrender start to render at the next frame.

          this.getZr().wakeUp();
        } else {
          try {
            prepare(this);
            updateMethods.update.call(this, null, updateParams);
          } catch (e) {
            this[PENDING_UPDATE] = null;
            this[IN_MAIN_PROCESS_KEY] = false;
            throw e;
          } // Ensure zr refresh sychronously, and then pixel in canvas can be
          // fetched after `setOption`.


          if (!this._ssr) {
            // not use flush when using ssr mode.
            this._zr.flush();
          }

          this[PENDING_UPDATE] = null;
          this[IN_MAIN_PROCESS_KEY] = false;
          flushPendingActions.call(this, silent);
          triggerUpdatedEvent.call(this, silent);
        }
      };
      /**
       * @deprecated
       */


      ECharts.prototype.setTheme = function () {
        deprecateLog('ECharts#setTheme() is DEPRECATED in ECharts 3.0');
      }; // We don't want developers to use getModel directly.


      ECharts.prototype.getModel = function () {
        return this._model;
      };

      ECharts.prototype.getOption = function () {
        return this._model && this._model.getOption();
      };

      ECharts.prototype.getWidth = function () {
        return this._zr.getWidth();
      };

      ECharts.prototype.getHeight = function () {
        return this._zr.getHeight();
      };

      ECharts.prototype.getDevicePixelRatio = function () {
        return this._zr.painter.dpr
        /* eslint-disable-next-line */
        || hasWindow && window.devicePixelRatio || 1;
      };
      /**
       * Get canvas which has all thing rendered
       * @deprecated Use renderToCanvas instead.
       */


      ECharts.prototype.getRenderedCanvas = function (opts) {
        if ("development" !== 'production') {
          deprecateReplaceLog('getRenderedCanvas', 'renderToCanvas');
        }

        return this.renderToCanvas(opts);
      };

      ECharts.prototype.renderToCanvas = function (opts) {
        opts = opts || {};
        var painter = this._zr.painter;

        if ("development" !== 'production') {
          if (painter.type !== 'canvas') {
            throw new Error('renderToCanvas can only be used in the canvas renderer.');
          }
        }

        return painter.getRenderedCanvas({
          backgroundColor: opts.backgroundColor || this._model.get('backgroundColor'),
          pixelRatio: opts.pixelRatio || this.getDevicePixelRatio()
        });
      };

      ECharts.prototype.renderToSVGString = function (opts) {
        opts = opts || {};
        var painter = this._zr.painter;

        if ("development" !== 'production') {
          if (painter.type !== 'svg') {
            throw new Error('renderToSVGString can only be used in the svg renderer.');
          }
        }

        return painter.renderToString({
          useViewBox: opts.useViewBox
        });
      };
      /**
       * Get svg data url
       */


      ECharts.prototype.getSvgDataURL = function () {
        if (!env.svgSupported) {
          return;
        }

        var zr = this._zr;
        var list = zr.storage.getDisplayList(); // Stop animations

        each(list, function (el) {
          el.stopAnimation(null, true);
        });
        return zr.painter.toDataURL();
      };

      ECharts.prototype.getDataURL = function (opts) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        opts = opts || {};
        var excludeComponents = opts.excludeComponents;
        var ecModel = this._model;
        var excludesComponentViews = [];
        var self = this;
        each(excludeComponents, function (componentType) {
          ecModel.eachComponent({
            mainType: componentType
          }, function (component) {
            var view = self._componentsMap[component.__viewId];

            if (!view.group.ignore) {
              excludesComponentViews.push(view);
              view.group.ignore = true;
            }
          });
        });
        var url = this._zr.painter.getType() === 'svg' ? this.getSvgDataURL() : this.renderToCanvas(opts).toDataURL('image/' + (opts && opts.type || 'png'));
        each(excludesComponentViews, function (view) {
          view.group.ignore = false;
        });
        return url;
      };

      ECharts.prototype.getConnectedDataURL = function (opts) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        var isSvg = opts.type === 'svg';
        var groupId = this.group;
        var mathMin = Math.min;
        var mathMax = Math.max;
        var MAX_NUMBER = Infinity;

        if (connectedGroups[groupId]) {
          var left_1 = MAX_NUMBER;
          var top_1 = MAX_NUMBER;
          var right_1 = -MAX_NUMBER;
          var bottom_1 = -MAX_NUMBER;
          var canvasList_1 = [];
          var dpr_1 = opts && opts.pixelRatio || this.getDevicePixelRatio();
          each(instances$1, function (chart, id) {
            if (chart.group === groupId) {
              var canvas = isSvg ? chart.getZr().painter.getSvgDom().innerHTML : chart.renderToCanvas(clone(opts));
              var boundingRect = chart.getDom().getBoundingClientRect();
              left_1 = mathMin(boundingRect.left, left_1);
              top_1 = mathMin(boundingRect.top, top_1);
              right_1 = mathMax(boundingRect.right, right_1);
              bottom_1 = mathMax(boundingRect.bottom, bottom_1);
              canvasList_1.push({
                dom: canvas,
                left: boundingRect.left,
                top: boundingRect.top
              });
            }
          });
          left_1 *= dpr_1;
          top_1 *= dpr_1;
          right_1 *= dpr_1;
          bottom_1 *= dpr_1;
          var width = right_1 - left_1;
          var height = bottom_1 - top_1;
          var targetCanvas = platformApi.createCanvas();
          var zr_1 = init(targetCanvas, {
            renderer: isSvg ? 'svg' : 'canvas'
          });
          zr_1.resize({
            width: width,
            height: height
          });

          if (isSvg) {
            var content_1 = '';
            each(canvasList_1, function (item) {
              var x = item.left - left_1;
              var y = item.top - top_1;
              content_1 += '<g transform="translate(' + x + ',' + y + ')">' + item.dom + '</g>';
            });
            zr_1.painter.getSvgRoot().innerHTML = content_1;

            if (opts.connectedBackgroundColor) {
              zr_1.painter.setBackgroundColor(opts.connectedBackgroundColor);
            }

            zr_1.refreshImmediately();
            return zr_1.painter.toDataURL();
          } else {
            // Background between the charts
            if (opts.connectedBackgroundColor) {
              zr_1.add(new Rect({
                shape: {
                  x: 0,
                  y: 0,
                  width: width,
                  height: height
                },
                style: {
                  fill: opts.connectedBackgroundColor
                }
              }));
            }

            each(canvasList_1, function (item) {
              var img = new ZRImage({
                style: {
                  x: item.left * dpr_1 - left_1,
                  y: item.top * dpr_1 - top_1,
                  image: item.dom
                }
              });
              zr_1.add(img);
            });
            zr_1.refreshImmediately();
            return targetCanvas.toDataURL('image/' + (opts && opts.type || 'png'));
          }
        } else {
          return this.getDataURL(opts);
        }
      };

      ECharts.prototype.convertToPixel = function (finder, value) {
        return doConvertPixel(this, 'convertToPixel', finder, value);
      };

      ECharts.prototype.convertFromPixel = function (finder, value) {
        return doConvertPixel(this, 'convertFromPixel', finder, value);
      };
      /**
       * Is the specified coordinate systems or components contain the given pixel point.
       * @param {Array|number} value
       * @return {boolean} result
       */


      ECharts.prototype.containPixel = function (finder, value) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        var ecModel = this._model;
        var result;
        var findResult = parseFinder(ecModel, finder);
        each(findResult, function (models, key) {
          key.indexOf('Models') >= 0 && each(models, function (model) {
            var coordSys = model.coordinateSystem;

            if (coordSys && coordSys.containPoint) {
              result = result || !!coordSys.containPoint(value);
            } else if (key === 'seriesModels') {
              var view = this._chartsMap[model.__viewId];

              if (view && view.containPoint) {
                result = result || view.containPoint(value, model);
              } else {
                if ("development" !== 'production') {
                  console.warn(key + ': ' + (view ? 'The found component do not support containPoint.' : 'No view mapping to the found component.'));
                }
              }
            } else {
              if ("development" !== 'production') {
                console.warn(key + ': containPoint is not supported');
              }
            }
          }, this);
        }, this);
        return !!result;
      };
      /**
       * Get visual from series or data.
       * @param finder
       *        If string, e.g., 'series', means {seriesIndex: 0}.
       *        If Object, could contain some of these properties below:
       *        {
       *            seriesIndex / seriesId / seriesName,
       *            dataIndex / dataIndexInside
       *        }
       *        If dataIndex is not specified, series visual will be fetched,
       *        but not data item visual.
       *        If all of seriesIndex, seriesId, seriesName are not specified,
       *        visual will be fetched from first series.
       * @param visualType 'color', 'symbol', 'symbolSize'
       */


      ECharts.prototype.getVisual = function (finder, visualType) {
        var ecModel = this._model;
        var parsedFinder = parseFinder(ecModel, finder, {
          defaultMainType: 'series'
        });
        var seriesModel = parsedFinder.seriesModel;

        if ("development" !== 'production') {
          if (!seriesModel) {
            console.warn('There is no specified seires model');
          }
        }

        var data = seriesModel.getData();
        var dataIndexInside = parsedFinder.hasOwnProperty('dataIndexInside') ? parsedFinder.dataIndexInside : parsedFinder.hasOwnProperty('dataIndex') ? data.indexOfRawIndex(parsedFinder.dataIndex) : null;
        return dataIndexInside != null ? getItemVisualFromData(data, dataIndexInside, visualType) : getVisualFromData(data, visualType);
      };
      /**
       * Get view of corresponding component model
       */


      ECharts.prototype.getViewOfComponentModel = function (componentModel) {
        return this._componentsMap[componentModel.__viewId];
      };
      /**
       * Get view of corresponding series model
       */


      ECharts.prototype.getViewOfSeriesModel = function (seriesModel) {
        return this._chartsMap[seriesModel.__viewId];
      };

      ECharts.prototype._initEvents = function () {
        var _this = this;

        each(MOUSE_EVENT_NAMES, function (eveName) {
          var handler = function (e) {
            var ecModel = _this.getModel();

            var el = e.target;
            var params;
            var isGlobalOut = eveName === 'globalout'; // no e.target when 'globalout'.

            if (isGlobalOut) {
              params = {};
            } else {
              el && findEventDispatcher(el, function (parent) {
                var ecData = getECData(parent);

                if (ecData && ecData.dataIndex != null) {
                  var dataModel = ecData.dataModel || ecModel.getSeriesByIndex(ecData.seriesIndex);
                  params = dataModel && dataModel.getDataParams(ecData.dataIndex, ecData.dataType) || {};
                  return true;
                } // If element has custom eventData of components
                else if (ecData.eventData) {
                    params = extend({}, ecData.eventData);
                    return true;
                  }
              }, true);
            } // Contract: if params prepared in mouse event,
            // these properties must be specified:
            // {
            //    componentType: string (component main type)
            //    componentIndex: number
            // }
            // Otherwise event query can not work.


            if (params) {
              var componentType = params.componentType;
              var componentIndex = params.componentIndex; // Special handling for historic reason: when trigger by
              // markLine/markPoint/markArea, the componentType is
              // 'markLine'/'markPoint'/'markArea', but we should better
              // enable them to be queried by seriesIndex, since their
              // option is set in each series.

              if (componentType === 'markLine' || componentType === 'markPoint' || componentType === 'markArea') {
                componentType = 'series';
                componentIndex = params.seriesIndex;
              }

              var model = componentType && componentIndex != null && ecModel.getComponent(componentType, componentIndex);
              var view = model && _this[model.mainType === 'series' ? '_chartsMap' : '_componentsMap'][model.__viewId];

              if ("development" !== 'production') {
                // `event.componentType` and `event[componentTpype + 'Index']` must not
                // be missed, otherwise there is no way to distinguish source component.
                // See `dataFormat.getDataParams`.
                if (!isGlobalOut && !(model && view)) {
                  console.warn('model or view can not be found by params');
                }
              }

              params.event = e;
              params.type = eveName;
              _this._$eventProcessor.eventInfo = {
                targetEl: el,
                packedEvent: params,
                model: model,
                view: view
              };

              _this.trigger(eveName, params);
            }
          }; // Consider that some component (like tooltip, brush, ...)
          // register zr event handler, but user event handler might
          // do anything, such as call `setOption` or `dispatchAction`,
          // which probably update any of the content and probably
          // cause problem if it is called previous other inner handlers.


          handler.zrEventfulCallAtLast = true;

          _this._zr.on(eveName, handler, _this);
        });
        each(eventActionMap, function (actionType, eventType) {
          _this._messageCenter.on(eventType, function (event) {
            this.trigger(eventType, event);
          }, _this);
        }); // Extra events
        // TODO register?

        each(['selectchanged'], function (eventType) {
          _this._messageCenter.on(eventType, function (event) {
            this.trigger(eventType, event);
          }, _this);
        });
        handleLegacySelectEvents(this._messageCenter, this, this._api);
      };

      ECharts.prototype.isDisposed = function () {
        return this._disposed;
      };

      ECharts.prototype.clear = function () {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        this.setOption({
          series: []
        }, true);
      };

      ECharts.prototype.dispose = function () {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        this._disposed = true;
        var dom = this.getDom();

        if (dom) {
          setAttribute(this.getDom(), DOM_ATTRIBUTE_KEY, '');
        }

        var chart = this;
        var api = chart._api;
        var ecModel = chart._model;
        each(chart._componentsViews, function (component) {
          component.dispose(ecModel, api);
        });
        each(chart._chartsViews, function (chart) {
          chart.dispose(ecModel, api);
        }); // Dispose after all views disposed

        chart._zr.dispose(); // Set properties to null.
        // To reduce the memory cost in case the top code still holds this instance unexpectedly.


        chart._dom = chart._model = chart._chartsMap = chart._componentsMap = chart._chartsViews = chart._componentsViews = chart._scheduler = chart._api = chart._zr = chart._throttledZrFlush = chart._theme = chart._coordSysMgr = chart._messageCenter = null;
        delete instances$1[chart.id];
      };
      /**
       * Resize the chart
       */


      ECharts.prototype.resize = function (opts) {
        if (this[IN_MAIN_PROCESS_KEY]) {
          if ("development" !== 'production') {
            error('`resize` should not be called during main process.');
          }

          return;
        }

        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        this._zr.resize(opts);

        var ecModel = this._model; // Resize loading effect

        this._loadingFX && this._loadingFX.resize();

        if (!ecModel) {
          return;
        }

        var needPrepare = ecModel.resetOption('media');
        var silent = opts && opts.silent; // There is some real cases that:
        // chart.setOption(option, { lazyUpdate: true });
        // chart.resize();

        if (this[PENDING_UPDATE]) {
          if (silent == null) {
            silent = this[PENDING_UPDATE].silent;
          }

          needPrepare = true;
          this[PENDING_UPDATE] = null;
        }

        this[IN_MAIN_PROCESS_KEY] = true;

        try {
          needPrepare && prepare(this);
          updateMethods.update.call(this, {
            type: 'resize',
            animation: extend({
              // Disable animation
              duration: 0
            }, opts && opts.animation)
          });
        } catch (e) {
          this[IN_MAIN_PROCESS_KEY] = false;
          throw e;
        }

        this[IN_MAIN_PROCESS_KEY] = false;
        flushPendingActions.call(this, silent);
        triggerUpdatedEvent.call(this, silent);
      };

      ECharts.prototype.showLoading = function (name, cfg) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        if (isObject(name)) {
          cfg = name;
          name = '';
        }

        name = name || 'default';
        this.hideLoading();

        if (!loadingEffects[name]) {
          if ("development" !== 'production') {
            console.warn('Loading effects ' + name + ' not exists.');
          }

          return;
        }

        var el = loadingEffects[name](this._api, cfg);
        var zr = this._zr;
        this._loadingFX = el;
        zr.add(el);
      };
      /**
       * Hide loading effect
       */


      ECharts.prototype.hideLoading = function () {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        this._loadingFX && this._zr.remove(this._loadingFX);
        this._loadingFX = null;
      };

      ECharts.prototype.makeActionFromEvent = function (eventObj) {
        var payload = extend({}, eventObj);
        payload.type = eventActionMap[eventObj.type];
        return payload;
      };
      /**
       * @param opt If pass boolean, means opt.silent
       * @param opt.silent Default `false`. Whether trigger events.
       * @param opt.flush Default `undefined`.
       *        true: Flush immediately, and then pixel in canvas can be fetched
       *            immediately. Caution: it might affect performance.
       *        false: Not flush.
       *        undefined: Auto decide whether perform flush.
       */


      ECharts.prototype.dispatchAction = function (payload, opt) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        if (!isObject(opt)) {
          opt = {
            silent: !!opt
          };
        }

        if (!actions[payload.type]) {
          return;
        } // Avoid dispatch action before setOption. Especially in `connect`.


        if (!this._model) {
          return;
        } // May dispatchAction in rendering procedure


        if (this[IN_MAIN_PROCESS_KEY]) {
          this._pendingActions.push(payload);

          return;
        }

        var silent = opt.silent;
        doDispatchAction.call(this, payload, silent);
        var flush = opt.flush;

        if (flush) {
          this._zr.flush();
        } else if (flush !== false && env.browser.weChat) {
          // In WeChat embedded browser, `requestAnimationFrame` and `setInterval`
          // hang when sliding page (on touch event), which cause that zr does not
          // refresh until user interaction finished, which is not expected.
          // But `dispatchAction` may be called too frequently when pan on touch
          // screen, which impacts performance if do not throttle them.
          this._throttledZrFlush();
        }

        flushPendingActions.call(this, silent);
        triggerUpdatedEvent.call(this, silent);
      };

      ECharts.prototype.updateLabelLayout = function () {
        lifecycle.trigger('series:layoutlabels', this._model, this._api, {
          // Not adding series labels.
          // TODO
          updatedSeries: []
        });
      };

      ECharts.prototype.appendData = function (params) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        var seriesIndex = params.seriesIndex;
        var ecModel = this.getModel();
        var seriesModel = ecModel.getSeriesByIndex(seriesIndex);

        if ("development" !== 'production') {
          assert(params.data && seriesModel);
        }

        seriesModel.appendData(params); // Note: `appendData` does not support that update extent of coordinate
        // system, util some scenario require that. In the expected usage of
        // `appendData`, the initial extent of coordinate system should better
        // be fixed by axis `min`/`max` setting or initial data, otherwise if
        // the extent changed while `appendData`, the location of the painted
        // graphic elements have to be changed, which make the usage of
        // `appendData` meaningless.

        this._scheduler.unfinished = true;
        this.getZr().wakeUp();
      }; // A work around for no `internal` modifier in ts yet but
      // need to strictly hide private methods to JS users.


      ECharts.internalField = function () {
        prepare = function (ecIns) {
          var scheduler = ecIns._scheduler;
          scheduler.restorePipelines(ecIns._model);
          scheduler.prepareStageTasks();
          prepareView(ecIns, true);
          prepareView(ecIns, false);
          scheduler.plan();
        };
        /**
         * Prepare view instances of charts and components
         */


        prepareView = function (ecIns, isComponent) {
          var ecModel = ecIns._model;
          var scheduler = ecIns._scheduler;
          var viewList = isComponent ? ecIns._componentsViews : ecIns._chartsViews;
          var viewMap = isComponent ? ecIns._componentsMap : ecIns._chartsMap;
          var zr = ecIns._zr;
          var api = ecIns._api;

          for (var i = 0; i < viewList.length; i++) {
            viewList[i].__alive = false;
          }

          isComponent ? ecModel.eachComponent(function (componentType, model) {
            componentType !== 'series' && doPrepare(model);
          }) : ecModel.eachSeries(doPrepare);

          function doPrepare(model) {
            // By default view will be reused if possible for the case that `setOption` with "notMerge"
            // mode and need to enable transition animation. (Usually, when they have the same id, or
            // especially no id but have the same type & name & index. See the `model.id` generation
            // rule in `makeIdAndName` and `viewId` generation rule here).
            // But in `replaceMerge` mode, this feature should be able to disabled when it is clear that
            // the new model has nothing to do with the old model.
            var requireNewView = model.__requireNewView; // This command should not work twice.

            model.__requireNewView = false; // Consider: id same and type changed.

            var viewId = '_ec_' + model.id + '_' + model.type;
            var view = !requireNewView && viewMap[viewId];

            if (!view) {
              var classType = parseClassType(model.type);
              var Clazz = isComponent ? ComponentView.getClass(classType.main, classType.sub) : // FIXME:TS
              // (ChartView as ChartViewConstructor).getClass('series', classType.sub)
              // For backward compat, still support a chart type declared as only subType
              // like "liquidfill", but recommend "series.liquidfill"
              // But need a base class to make a type series.
              ChartView.getClass(classType.sub);

              if ("development" !== 'production') {
                assert(Clazz, classType.sub + ' does not exist.');
              }

              view = new Clazz();
              view.init(ecModel, api);
              viewMap[viewId] = view;
              viewList.push(view);
              zr.add(view.group);
            }

            model.__viewId = view.__id = viewId;
            view.__alive = true;
            view.__model = model;
            view.group.__ecComponentInfo = {
              mainType: model.mainType,
              index: model.componentIndex
            };
            !isComponent && scheduler.prepareView(view, model, ecModel, api);
          }

          for (var i = 0; i < viewList.length;) {
            var view = viewList[i];

            if (!view.__alive) {
              !isComponent && view.renderTask.dispose();
              zr.remove(view.group);
              view.dispose(ecModel, api);
              viewList.splice(i, 1);

              if (viewMap[view.__id] === view) {
                delete viewMap[view.__id];
              }

              view.__id = view.group.__ecComponentInfo = null;
            } else {
              i++;
            }
          }
        };

        updateDirectly = function (ecIns, method, payload, mainType, subType) {
          var ecModel = ecIns._model;
          ecModel.setUpdatePayload(payload); // broadcast

          if (!mainType) {
            // FIXME
            // Chart will not be update directly here, except set dirty.
            // But there is no such scenario now.
            each([].concat(ecIns._componentsViews).concat(ecIns._chartsViews), callView);
            return;
          }

          var query = {};
          query[mainType + 'Id'] = payload[mainType + 'Id'];
          query[mainType + 'Index'] = payload[mainType + 'Index'];
          query[mainType + 'Name'] = payload[mainType + 'Name'];
          var condition = {
            mainType: mainType,
            query: query
          };
          subType && (condition.subType = subType); // subType may be '' by parseClassType;

          var excludeSeriesId = payload.excludeSeriesId;
          var excludeSeriesIdMap;

          if (excludeSeriesId != null) {
            excludeSeriesIdMap = createHashMap();
            each(normalizeToArray(excludeSeriesId), function (id) {
              var modelId = convertOptionIdName(id, null);

              if (modelId != null) {
                excludeSeriesIdMap.set(modelId, true);
              }
            });
          } // If dispatchAction before setOption, do nothing.


          ecModel && ecModel.eachComponent(condition, function (model) {
            var isExcluded = excludeSeriesIdMap && excludeSeriesIdMap.get(model.id) !== null;

            if (isExcluded) {
              return;
            }

            if (isHighDownPayload(payload)) {
              if (model instanceof SeriesModel) {
                if (payload.type === HIGHLIGHT_ACTION_TYPE && !payload.notBlur && !model.get(['emphasis', 'disabled'])) {
                  blurSeriesFromHighlightPayload(model, payload, ecIns._api);
                }
              } else {
                var _a = findComponentHighDownDispatchers(model.mainType, model.componentIndex, payload.name, ecIns._api),
                    focusSelf = _a.focusSelf,
                    dispatchers = _a.dispatchers;

                if (payload.type === HIGHLIGHT_ACTION_TYPE && focusSelf && !payload.notBlur) {
                  blurComponent(model.mainType, model.componentIndex, ecIns._api);
                } // PENDING:
                // Whether to put this "enter emphasis" code in `ComponentView`,
                // which will be the same as `ChartView` but might be not necessary
                // and will be far from this logic.


                if (dispatchers) {
                  each(dispatchers, function (dispatcher) {
                    payload.type === HIGHLIGHT_ACTION_TYPE ? enterEmphasis(dispatcher) : leaveEmphasis(dispatcher);
                  });
                }
              }
            } else if (isSelectChangePayload(payload)) {
              // TODO geo
              if (model instanceof SeriesModel) {
                toggleSelectionFromPayload(model, payload, ecIns._api);
                updateSeriesElementSelection(model);
                markStatusToUpdate(ecIns);
              }
            }
          }, ecIns);
          ecModel && ecModel.eachComponent(condition, function (model) {
            var isExcluded = excludeSeriesIdMap && excludeSeriesIdMap.get(model.id) !== null;

            if (isExcluded) {
              return;
            }
            callView(ecIns[mainType === 'series' ? '_chartsMap' : '_componentsMap'][model.__viewId]);
          }, ecIns);

          function callView(view) {
            view && view.__alive && view[method] && view[method](view.__model, ecModel, ecIns._api, payload);
          }
        };

        updateMethods = {
          prepareAndUpdate: function (payload) {
            prepare(this);
            updateMethods.update.call(this, payload, {
              // Needs to mark option changed if newOption is given.
              // It's from MagicType.
              // TODO If use a separate flag optionChanged in payload?
              optionChanged: payload.newOption != null
            });
          },
          update: function (payload, updateParams) {
            var ecModel = this._model;
            var api = this._api;
            var zr = this._zr;
            var coordSysMgr = this._coordSysMgr;
            var scheduler = this._scheduler; // update before setOption

            if (!ecModel) {
              return;
            }

            ecModel.setUpdatePayload(payload);
            scheduler.restoreData(ecModel, payload);
            scheduler.performSeriesTasks(ecModel); // TODO
            // Save total ecModel here for undo/redo (after restoring data and before processing data).
            // Undo (restoration of total ecModel) can be carried out in 'action' or outside API call.
            // Create new coordinate system each update
            // In LineView may save the old coordinate system and use it to get the original point.

            coordSysMgr.create(ecModel, api);
            scheduler.performDataProcessorTasks(ecModel, payload); // Current stream render is not supported in data process. So we can update
            // stream modes after data processing, where the filtered data is used to
            // determine whether to use progressive rendering.

            updateStreamModes(this, ecModel); // We update stream modes before coordinate system updated, then the modes info
            // can be fetched when coord sys updating (consider the barGrid extent fix). But
            // the drawback is the full coord info can not be fetched. Fortunately this full
            // coord is not required in stream mode updater currently.

            coordSysMgr.update(ecModel, api);
            clearColorPalette(ecModel);
            scheduler.performVisualTasks(ecModel, payload);
            render(this, ecModel, api, payload, updateParams); // Set background

            var backgroundColor = ecModel.get('backgroundColor') || 'transparent';
            var darkMode = ecModel.get('darkMode');
            zr.setBackgroundColor(backgroundColor); // Force set dark mode.

            if (darkMode != null && darkMode !== 'auto') {
              zr.setDarkMode(darkMode);
            }

            lifecycle.trigger('afterupdate', ecModel, api);
          },
          updateTransform: function (payload) {
            var _this = this;

            var ecModel = this._model;
            var api = this._api; // update before setOption

            if (!ecModel) {
              return;
            }

            ecModel.setUpdatePayload(payload); // ChartView.markUpdateMethod(payload, 'updateTransform');

            var componentDirtyList = [];
            ecModel.eachComponent(function (componentType, componentModel) {
              if (componentType === 'series') {
                return;
              }

              var componentView = _this.getViewOfComponentModel(componentModel);

              if (componentView && componentView.__alive) {
                if (componentView.updateTransform) {
                  var result = componentView.updateTransform(componentModel, ecModel, api, payload);
                  result && result.update && componentDirtyList.push(componentView);
                } else {
                  componentDirtyList.push(componentView);
                }
              }
            });
            var seriesDirtyMap = createHashMap();
            ecModel.eachSeries(function (seriesModel) {
              var chartView = _this._chartsMap[seriesModel.__viewId];

              if (chartView.updateTransform) {
                var result = chartView.updateTransform(seriesModel, ecModel, api, payload);
                result && result.update && seriesDirtyMap.set(seriesModel.uid, 1);
              } else {
                seriesDirtyMap.set(seriesModel.uid, 1);
              }
            });
            clearColorPalette(ecModel); // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
            // this._scheduler.performVisualTasks(ecModel, payload, 'layout', true);

            this._scheduler.performVisualTasks(ecModel, payload, {
              setDirty: true,
              dirtyMap: seriesDirtyMap
            }); // Currently, not call render of components. Geo render cost a lot.
            // renderComponents(ecIns, ecModel, api, payload, componentDirtyList);


            renderSeries(this, ecModel, api, payload, {}, seriesDirtyMap);
            lifecycle.trigger('afterupdate', ecModel, api);
          },
          updateView: function (payload) {
            var ecModel = this._model; // update before setOption

            if (!ecModel) {
              return;
            }

            ecModel.setUpdatePayload(payload);
            ChartView.markUpdateMethod(payload, 'updateView');
            clearColorPalette(ecModel); // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.

            this._scheduler.performVisualTasks(ecModel, payload, {
              setDirty: true
            });

            render(this, ecModel, this._api, payload, {});
            lifecycle.trigger('afterupdate', ecModel, this._api);
          },
          updateVisual: function (payload) {
            // updateMethods.update.call(this, payload);
            var _this = this;

            var ecModel = this._model; // update before setOption

            if (!ecModel) {
              return;
            }

            ecModel.setUpdatePayload(payload); // clear all visual

            ecModel.eachSeries(function (seriesModel) {
              seriesModel.getData().clearAllVisual();
            }); // Perform visual

            ChartView.markUpdateMethod(payload, 'updateVisual');
            clearColorPalette(ecModel); // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.

            this._scheduler.performVisualTasks(ecModel, payload, {
              visualType: 'visual',
              setDirty: true
            });

            ecModel.eachComponent(function (componentType, componentModel) {
              if (componentType !== 'series') {
                var componentView = _this.getViewOfComponentModel(componentModel);

                componentView && componentView.__alive && componentView.updateVisual(componentModel, ecModel, _this._api, payload);
              }
            });
            ecModel.eachSeries(function (seriesModel) {
              var chartView = _this._chartsMap[seriesModel.__viewId];
              chartView.updateVisual(seriesModel, ecModel, _this._api, payload);
            });
            lifecycle.trigger('afterupdate', ecModel, this._api);
          },
          updateLayout: function (payload) {
            updateMethods.update.call(this, payload);
          }
        };

        doConvertPixel = function (ecIns, methodName, finder, value) {
          if (ecIns._disposed) {
            disposedWarning(ecIns.id);
            return;
          }

          var ecModel = ecIns._model;

          var coordSysList = ecIns._coordSysMgr.getCoordinateSystems();

          var result;
          var parsedFinder = parseFinder(ecModel, finder);

          for (var i = 0; i < coordSysList.length; i++) {
            var coordSys = coordSysList[i];

            if (coordSys[methodName] && (result = coordSys[methodName](ecModel, parsedFinder, value)) != null) {
              return result;
            }
          }

          if ("development" !== 'production') {
            console.warn('No coordinate system that supports ' + methodName + ' found by the given finder.');
          }
        };

        updateStreamModes = function (ecIns, ecModel) {
          var chartsMap = ecIns._chartsMap;
          var scheduler = ecIns._scheduler;
          ecModel.eachSeries(function (seriesModel) {
            scheduler.updateStreamModes(seriesModel, chartsMap[seriesModel.__viewId]);
          });
        };

        doDispatchAction = function (payload, silent) {
          var _this = this;

          var ecModel = this.getModel();
          var payloadType = payload.type;
          var escapeConnect = payload.escapeConnect;
          var actionWrap = actions[payloadType];
          var actionInfo = actionWrap.actionInfo;
          var cptTypeTmp = (actionInfo.update || 'update').split(':');
          var updateMethod = cptTypeTmp.pop();
          var cptType = cptTypeTmp[0] != null && parseClassType(cptTypeTmp[0]);
          this[IN_MAIN_PROCESS_KEY] = true;
          var payloads = [payload];
          var batched = false; // Batch action

          if (payload.batch) {
            batched = true;
            payloads = map(payload.batch, function (item) {
              item = defaults(extend({}, item), payload);
              item.batch = null;
              return item;
            });
          }

          var eventObjBatch = [];
          var eventObj;
          var isSelectChange = isSelectChangePayload(payload);
          var isHighDown = isHighDownPayload(payload); // Only leave blur once if there are multiple batches.

          if (isHighDown) {
            allLeaveBlur(this._api);
          }

          each(payloads, function (batchItem) {
            // Action can specify the event by return it.
            eventObj = actionWrap.action(batchItem, _this._model, _this._api); // Emit event outside

            eventObj = eventObj || extend({}, batchItem); // Convert type to eventType

            eventObj.type = actionInfo.event || eventObj.type;
            eventObjBatch.push(eventObj); // light update does not perform data process, layout and visual.

            if (isHighDown) {
              var _a = preParseFinder(payload),
                  queryOptionMap = _a.queryOptionMap,
                  mainTypeSpecified = _a.mainTypeSpecified;

              var componentMainType = mainTypeSpecified ? queryOptionMap.keys()[0] : 'series';
              updateDirectly(_this, updateMethod, batchItem, componentMainType);
              markStatusToUpdate(_this);
            } else if (isSelectChange) {
              // At present `dispatchAction({ type: 'select', ... })` is not supported on components.
              // geo still use 'geoselect'.
              updateDirectly(_this, updateMethod, batchItem, 'series');
              markStatusToUpdate(_this);
            } else if (cptType) {
              updateDirectly(_this, updateMethod, batchItem, cptType.main, cptType.sub);
            }
          });

          if (updateMethod !== 'none' && !isHighDown && !isSelectChange && !cptType) {
            try {
              // Still dirty
              if (this[PENDING_UPDATE]) {
                prepare(this);
                updateMethods.update.call(this, payload);
                this[PENDING_UPDATE] = null;
              } else {
                updateMethods[updateMethod].call(this, payload);
              }
            } catch (e) {
              this[IN_MAIN_PROCESS_KEY] = false;
              throw e;
            }
          } // Follow the rule of action batch


          if (batched) {
            eventObj = {
              type: actionInfo.event || payloadType,
              escapeConnect: escapeConnect,
              batch: eventObjBatch
            };
          } else {
            eventObj = eventObjBatch[0];
          }

          this[IN_MAIN_PROCESS_KEY] = false;

          if (!silent) {
            var messageCenter = this._messageCenter;
            messageCenter.trigger(eventObj.type, eventObj); // Extra triggered 'selectchanged' event

            if (isSelectChange) {
              var newObj = {
                type: 'selectchanged',
                escapeConnect: escapeConnect,
                selected: getAllSelectedIndices(ecModel),
                isFromClick: payload.isFromClick || false,
                fromAction: payload.type,
                fromActionPayload: payload
              };
              messageCenter.trigger(newObj.type, newObj);
            }
          }
        };

        flushPendingActions = function (silent) {
          var pendingActions = this._pendingActions;

          while (pendingActions.length) {
            var payload = pendingActions.shift();
            doDispatchAction.call(this, payload, silent);
          }
        };

        triggerUpdatedEvent = function (silent) {
          !silent && this.trigger('updated');
        };
        /**
         * Event `rendered` is triggered when zr
         * rendered. It is useful for realtime
         * snapshot (reflect animation).
         *
         * Event `finished` is triggered when:
         * (1) zrender rendering finished.
         * (2) initial animation finished.
         * (3) progressive rendering finished.
         * (4) no pending action.
         * (5) no delayed setOption needs to be processed.
         */


        bindRenderedEvent = function (zr, ecIns) {
          zr.on('rendered', function (params) {
            ecIns.trigger('rendered', params); // The `finished` event should not be triggered repeatedly,
            // so it should only be triggered when rendering indeed happens
            // in zrender. (Consider the case that dipatchAction is keep
            // triggering when mouse move).

            if ( // Although zr is dirty if initial animation is not finished
            // and this checking is called on frame, we also check
            // animation finished for robustness.
            zr.animation.isFinished() && !ecIns[PENDING_UPDATE] && !ecIns._scheduler.unfinished && !ecIns._pendingActions.length) {
              ecIns.trigger('finished');
            }
          });
        };

        bindMouseEvent = function (zr, ecIns) {
          zr.on('mouseover', function (e) {
            var el = e.target;
            var dispatcher = findEventDispatcher(el, isHighDownDispatcher);

            if (dispatcher) {
              handleGlobalMouseOverForHighDown(dispatcher, e, ecIns._api);
              markStatusToUpdate(ecIns);
            }
          }).on('mouseout', function (e) {
            var el = e.target;
            var dispatcher = findEventDispatcher(el, isHighDownDispatcher);

            if (dispatcher) {
              handleGlobalMouseOutForHighDown(dispatcher, e, ecIns._api);
              markStatusToUpdate(ecIns);
            }
          }).on('click', function (e) {
            var el = e.target;
            var dispatcher = findEventDispatcher(el, function (target) {
              return getECData(target).dataIndex != null;
            }, true);

            if (dispatcher) {
              var actionType = dispatcher.selected ? 'unselect' : 'select';
              var ecData = getECData(dispatcher);

              ecIns._api.dispatchAction({
                type: actionType,
                dataType: ecData.dataType,
                dataIndexInside: ecData.dataIndex,
                seriesIndex: ecData.seriesIndex,
                isFromClick: true
              });
            }
          });
        };

        function clearColorPalette(ecModel) {
          ecModel.clearColorPalette();
          ecModel.eachSeries(function (seriesModel) {
            seriesModel.clearColorPalette();
          });
        }

        function allocateZlevels(ecModel) {
          var componentZLevels = [];
          var seriesZLevels = [];
          var hasSeperateZLevel = false;
          ecModel.eachComponent(function (componentType, componentModel) {
            var zlevel = componentModel.get('zlevel') || 0;
            var z = componentModel.get('z') || 0;
            var zlevelKey = componentModel.getZLevelKey();
            hasSeperateZLevel = hasSeperateZLevel || !!zlevelKey;
            (componentType === 'series' ? seriesZLevels : componentZLevels).push({
              zlevel: zlevel,
              z: z,
              idx: componentModel.componentIndex,
              type: componentType,
              key: zlevelKey
            });
          });

          if (hasSeperateZLevel) {
            // Series after component
            var zLevels = componentZLevels.concat(seriesZLevels);
            var lastSeriesZLevel_1;
            var lastSeriesKey_1;
            sort(zLevels, function (a, b) {
              if (a.zlevel === b.zlevel) {
                return a.z - b.z;
              }

              return a.zlevel - b.zlevel;
            });
            each(zLevels, function (item) {
              var componentModel = ecModel.getComponent(item.type, item.idx);
              var zlevel = item.zlevel;
              var key = item.key;

              if (lastSeriesZLevel_1 != null) {
                zlevel = Math.max(lastSeriesZLevel_1, zlevel);
              }

              if (key) {
                if (zlevel === lastSeriesZLevel_1 && key !== lastSeriesKey_1) {
                  zlevel++;
                }

                lastSeriesKey_1 = key;
              } else if (lastSeriesKey_1) {
                if (zlevel === lastSeriesZLevel_1) {
                  zlevel++;
                }

                lastSeriesKey_1 = '';
              }

              lastSeriesZLevel_1 = zlevel;
              componentModel.setZLevel(zlevel);
            });
          }
        }

        render = function (ecIns, ecModel, api, payload, updateParams) {
          allocateZlevels(ecModel);
          renderComponents(ecIns, ecModel, api, payload, updateParams);
          each(ecIns._chartsViews, function (chart) {
            chart.__alive = false;
          });
          renderSeries(ecIns, ecModel, api, payload, updateParams); // Remove groups of unrendered charts

          each(ecIns._chartsViews, function (chart) {
            if (!chart.__alive) {
              chart.remove(ecModel, api);
            }
          });
        };

        renderComponents = function (ecIns, ecModel, api, payload, updateParams, dirtyList) {
          each(dirtyList || ecIns._componentsViews, function (componentView) {
            var componentModel = componentView.__model;
            clearStates(componentModel, componentView);
            componentView.render(componentModel, ecModel, api, payload);
            updateZ(componentModel, componentView);
            updateStates(componentModel, componentView);
          });
        };
        /**
         * Render each chart and component
         */


        renderSeries = function (ecIns, ecModel, api, payload, updateParams, dirtyMap) {
          // Render all charts
          var scheduler = ecIns._scheduler;
          updateParams = extend(updateParams || {}, {
            updatedSeries: ecModel.getSeries()
          }); // TODO progressive?

          lifecycle.trigger('series:beforeupdate', ecModel, api, updateParams);
          var unfinished = false;
          ecModel.eachSeries(function (seriesModel) {
            var chartView = ecIns._chartsMap[seriesModel.__viewId];
            chartView.__alive = true;
            var renderTask = chartView.renderTask;
            scheduler.updatePayload(renderTask, payload); // TODO states on marker.

            clearStates(seriesModel, chartView);

            if (dirtyMap && dirtyMap.get(seriesModel.uid)) {
              renderTask.dirty();
            }

            if (renderTask.perform(scheduler.getPerformArgs(renderTask))) {
              unfinished = true;
            }

            chartView.group.silent = !!seriesModel.get('silent'); // Should not call markRedraw on group, because it will disable zrender
            // incremental render (always render from the __startIndex each frame)
            // chartView.group.markRedraw();

            updateBlend(seriesModel, chartView);
            updateSeriesElementSelection(seriesModel);
          });
          scheduler.unfinished = unfinished || scheduler.unfinished;
          lifecycle.trigger('series:layoutlabels', ecModel, api, updateParams); // transition after label is layouted.

          lifecycle.trigger('series:transition', ecModel, api, updateParams);
          ecModel.eachSeries(function (seriesModel) {
            var chartView = ecIns._chartsMap[seriesModel.__viewId]; // Update Z after labels updated. Before applying states.

            updateZ(seriesModel, chartView); // NOTE: Update states after label is updated.
            // label should be in normal status when layouting.

            updateStates(seriesModel, chartView);
          }); // If use hover layer

          updateHoverLayerStatus(ecIns, ecModel);
          lifecycle.trigger('series:afterupdate', ecModel, api, updateParams);
        };

        markStatusToUpdate = function (ecIns) {
          ecIns[STATUS_NEEDS_UPDATE_KEY] = true; // Wake up zrender if it's sleep. Let it update states in the next frame.

          ecIns.getZr().wakeUp();
        };

        applyChangedStates = function (ecIns) {
          if (!ecIns[STATUS_NEEDS_UPDATE_KEY]) {
            return;
          }

          ecIns.getZr().storage.traverse(function (el) {
            // Not applied on removed elements, it may still in fading.
            if (isElementRemoved(el)) {
              return;
            }

            applyElementStates(el);
          });
          ecIns[STATUS_NEEDS_UPDATE_KEY] = false;
        };

        function applyElementStates(el) {
          var newStates = [];
          var oldStates = el.currentStates; // Keep other states.

          for (var i = 0; i < oldStates.length; i++) {
            var stateName = oldStates[i];

            if (!(stateName === 'emphasis' || stateName === 'blur' || stateName === 'select')) {
              newStates.push(stateName);
            }
          } // Only use states when it's exists.


          if (el.selected && el.states.select) {
            newStates.push('select');
          }

          if (el.hoverState === HOVER_STATE_EMPHASIS && el.states.emphasis) {
            newStates.push('emphasis');
          } else if (el.hoverState === HOVER_STATE_BLUR && el.states.blur) {
            newStates.push('blur');
          }

          el.useStates(newStates);
        }

        function updateHoverLayerStatus(ecIns, ecModel) {
          var zr = ecIns._zr;
          var storage = zr.storage;
          var elCount = 0;
          storage.traverse(function (el) {
            if (!el.isGroup) {
              elCount++;
            }
          });

          if (elCount > ecModel.get('hoverLayerThreshold') && !env.node && !env.worker) {
            ecModel.eachSeries(function (seriesModel) {
              if (seriesModel.preventUsingHoverLayer) {
                return;
              }

              var chartView = ecIns._chartsMap[seriesModel.__viewId];

              if (chartView.__alive) {
                chartView.eachRendered(function (el) {
                  if (el.states.emphasis) {
                    el.states.emphasis.hoverLayer = true;
                  }
                });
              }
            });
          }
        }
        /**
         * Update chart and blend.
         */

        function updateBlend(seriesModel, chartView) {
          var blendMode = seriesModel.get('blendMode') || null;
          chartView.eachRendered(function (el) {
            // FIXME marker and other components
            if (!el.isGroup) {
              // DON'T mark the element dirty. In case element is incremental and don't want to rerender.
              el.style.blend = blendMode;
            }
          });
        }

        function updateZ(model, view) {
          if (model.preventAutoZ) {
            return;
          }

          var z = model.get('z') || 0;
          var zlevel = model.get('zlevel') || 0; // Set z and zlevel

          view.eachRendered(function (el) {
            doUpdateZ(el, z, zlevel, -Infinity); // Don't traverse the children because it has been traversed in _updateZ.

            return true;
          });
        }

        function doUpdateZ(el, z, zlevel, maxZ2) {
          // Group may also have textContent
          var label = el.getTextContent();
          var labelLine = el.getTextGuideLine();
          var isGroup = el.isGroup;

          if (isGroup) {
            // set z & zlevel of children elements of Group
            var children = el.childrenRef();

            for (var i = 0; i < children.length; i++) {
              maxZ2 = Math.max(doUpdateZ(children[i], z, zlevel, maxZ2), maxZ2);
            }
          } else {
            // not Group
            el.z = z;
            el.zlevel = zlevel;
            maxZ2 = Math.max(el.z2, maxZ2);
          } // always set z and zlevel if label/labelLine exists


          if (label) {
            label.z = z;
            label.zlevel = zlevel; // lift z2 of text content
            // TODO if el.emphasis.z2 is spcefied, what about textContent.

            isFinite(maxZ2) && (label.z2 = maxZ2 + 2);
          }

          if (labelLine) {
            var textGuideLineConfig = el.textGuideLineConfig;
            labelLine.z = z;
            labelLine.zlevel = zlevel;
            isFinite(maxZ2) && (labelLine.z2 = maxZ2 + (textGuideLineConfig && textGuideLineConfig.showAbove ? 1 : -1));
          }

          return maxZ2;
        } // Clear states without animation.
        // TODO States on component.


        function clearStates(model, view) {
          view.eachRendered(function (el) {
            // Not applied on removed elements, it may still in fading.
            if (isElementRemoved(el)) {
              return;
            }

            var textContent = el.getTextContent();
            var textGuide = el.getTextGuideLine();

            if (el.stateTransition) {
              el.stateTransition = null;
            }

            if (textContent && textContent.stateTransition) {
              textContent.stateTransition = null;
            }

            if (textGuide && textGuide.stateTransition) {
              textGuide.stateTransition = null;
            } // TODO If el is incremental.


            if (el.hasState()) {
              el.prevStates = el.currentStates;
              el.clearStates();
            } else if (el.prevStates) {
              el.prevStates = null;
            }
          });
        }

        function updateStates(model, view) {
          var stateAnimationModel = model.getModel('stateAnimation');
          var enableAnimation = model.isAnimationEnabled();
          var duration = stateAnimationModel.get('duration');
          var stateTransition = duration > 0 ? {
            duration: duration,
            delay: stateAnimationModel.get('delay'),
            easing: stateAnimationModel.get('easing') // additive: stateAnimationModel.get('additive')

          } : null;
          view.eachRendered(function (el) {
            if (el.states && el.states.emphasis) {
              // Not applied on removed elements, it may still in fading.
              if (isElementRemoved(el)) {
                return;
              }

              if (el instanceof Path) {
                savePathStates(el);
              } // Only updated on changed element. In case element is incremental and don't want to rerender.
              // TODO, a more proper way?


              if (el.__dirty) {
                var prevStates = el.prevStates; // Restore states without animation

                if (prevStates) {
                  el.useStates(prevStates);
                }
              } // Update state transition and enable animation again.


              if (enableAnimation) {
                el.stateTransition = stateTransition;
                var textContent = el.getTextContent();
                var textGuide = el.getTextGuideLine(); // TODO Is it necessary to animate label?

                if (textContent) {
                  textContent.stateTransition = stateTransition;
                }

                if (textGuide) {
                  textGuide.stateTransition = stateTransition;
                }
              } // Use highlighted and selected flag to toggle states.


              if (el.__dirty) {
                applyElementStates(el);
              }
            }
          });
        }

        createExtensionAPI = function (ecIns) {
          return new (
          /** @class */
          function (_super) {
            __extends(class_1, _super);

            function class_1() {
              return _super !== null && _super.apply(this, arguments) || this;
            }

            class_1.prototype.getCoordinateSystems = function () {
              return ecIns._coordSysMgr.getCoordinateSystems();
            };

            class_1.prototype.getComponentByElement = function (el) {
              while (el) {
                var modelInfo = el.__ecComponentInfo;

                if (modelInfo != null) {
                  return ecIns._model.getComponent(modelInfo.mainType, modelInfo.index);
                }

                el = el.parent;
              }
            };

            class_1.prototype.enterEmphasis = function (el, highlightDigit) {
              enterEmphasis(el, highlightDigit);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.leaveEmphasis = function (el, highlightDigit) {
              leaveEmphasis(el, highlightDigit);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.enterBlur = function (el) {
              enterBlur(el);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.leaveBlur = function (el) {
              leaveBlur(el);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.enterSelect = function (el) {
              enterSelect(el);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.leaveSelect = function (el) {
              leaveSelect(el);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.getModel = function () {
              return ecIns.getModel();
            };

            class_1.prototype.getViewOfComponentModel = function (componentModel) {
              return ecIns.getViewOfComponentModel(componentModel);
            };

            class_1.prototype.getViewOfSeriesModel = function (seriesModel) {
              return ecIns.getViewOfSeriesModel(seriesModel);
            };

            return class_1;
          }(ExtensionAPI))(ecIns);
        };

        enableConnect = function (chart) {
          function updateConnectedChartsStatus(charts, status) {
            for (var i = 0; i < charts.length; i++) {
              var otherChart = charts[i];
              otherChart[CONNECT_STATUS_KEY] = status;
            }
          }

          each(eventActionMap, function (actionType, eventType) {
            chart._messageCenter.on(eventType, function (event) {
              if (connectedGroups[chart.group] && chart[CONNECT_STATUS_KEY] !== CONNECT_STATUS_PENDING) {
                if (event && event.escapeConnect) {
                  return;
                }

                var action_1 = chart.makeActionFromEvent(event);
                var otherCharts_1 = [];
                each(instances$1, function (otherChart) {
                  if (otherChart !== chart && otherChart.group === chart.group) {
                    otherCharts_1.push(otherChart);
                  }
                });
                updateConnectedChartsStatus(otherCharts_1, CONNECT_STATUS_PENDING);
                each(otherCharts_1, function (otherChart) {
                  if (otherChart[CONNECT_STATUS_KEY] !== CONNECT_STATUS_UPDATING) {
                    otherChart.dispatchAction(action_1);
                  }
                });
                updateConnectedChartsStatus(otherCharts_1, CONNECT_STATUS_UPDATED);
              }
            });
          });
        };
      }();

      return ECharts;
    }(Eventful);

    var echartsProto = ECharts.prototype;
    echartsProto.on = createRegisterEventWithLowercaseECharts('on');
    echartsProto.off = createRegisterEventWithLowercaseECharts('off');
    /**
     * @deprecated
     */
    // @ts-ignore

    echartsProto.one = function (eventName, cb, ctx) {
      var self = this;
      deprecateLog('ECharts#one is deprecated.');

      function wrapped() {
        var args2 = [];

        for (var _i = 0; _i < arguments.length; _i++) {
          args2[_i] = arguments[_i];
        }

        cb && cb.apply && cb.apply(this, args2); // @ts-ignore

        self.off(eventName, wrapped);
      }

      this.on.call(this, eventName, wrapped, ctx);
    };

    var MOUSE_EVENT_NAMES = ['click', 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'mouseup', 'globalout', 'contextmenu'];

    function disposedWarning(id) {
      if ("development" !== 'production') {
        console.warn('Instance ' + id + ' has been disposed');
      }
    }

    var actions = {};
    /**
     * Map eventType to actionType
     */

    var eventActionMap = {};
    var dataProcessorFuncs = [];
    var optionPreprocessorFuncs = [];
    var visualFuncs = [];
    var themeStorage = {};
    var loadingEffects = {};
    var instances$1 = {};
    var connectedGroups = {};
    var idBase = +new Date() - 0;
    var groupIdBase = +new Date() - 0;
    var DOM_ATTRIBUTE_KEY = '_echarts_instance_';
    /**
     * @param opts.devicePixelRatio Use window.devicePixelRatio by default
     * @param opts.renderer Can choose 'canvas' or 'svg' to render the chart.
     * @param opts.width Use clientWidth of the input `dom` by default.
     *        Can be 'auto' (the same as null/undefined)
     * @param opts.height Use clientHeight of the input `dom` by default.
     *        Can be 'auto' (the same as null/undefined)
     * @param opts.locale Specify the locale.
     * @param opts.useDirtyRect Enable dirty rectangle rendering or not.
     */

    function init$1(dom, theme, opts) {
      var isClient = !(opts && opts.ssr);

      if (isClient) {
        if ("development" !== 'production') {
          if (!dom) {
            throw new Error('Initialize failed: invalid dom.');
          }
        }

        var existInstance = getInstanceByDom(dom);

        if (existInstance) {
          if ("development" !== 'production') {
            console.warn('There is a chart instance already initialized on the dom.');
          }

          return existInstance;
        }

        if ("development" !== 'production') {
          if (isDom(dom) && dom.nodeName.toUpperCase() !== 'CANVAS' && (!dom.clientWidth && (!opts || opts.width == null) || !dom.clientHeight && (!opts || opts.height == null))) {
            console.warn('Can\'t get DOM width or height. Please check ' + 'dom.clientWidth and dom.clientHeight. They should not be 0.' + 'For example, you may need to call this in the callback ' + 'of window.onload.');
          }
        }
      }

      var chart = new ECharts(dom, theme, opts);
      chart.id = 'ec_' + idBase++;
      instances$1[chart.id] = chart;
      isClient && setAttribute(dom, DOM_ATTRIBUTE_KEY, chart.id);
      enableConnect(chart);
      lifecycle.trigger('afterinit', chart);
      return chart;
    }
    /**
     * @usage
     * (A)
     * ```js
     * let chart1 = echarts.init(dom1);
     * let chart2 = echarts.init(dom2);
     * chart1.group = 'xxx';
     * chart2.group = 'xxx';
     * echarts.connect('xxx');
     * ```
     * (B)
     * ```js
     * let chart1 = echarts.init(dom1);
     * let chart2 = echarts.init(dom2);
     * echarts.connect('xxx', [chart1, chart2]);
     * ```
     */

    function connect(groupId) {
      // Is array of charts
      if (isArray(groupId)) {
        var charts = groupId;
        groupId = null; // If any chart has group

        each(charts, function (chart) {
          if (chart.group != null) {
            groupId = chart.group;
          }
        });
        groupId = groupId || 'g_' + groupIdBase++;
        each(charts, function (chart) {
          chart.group = groupId;
        });
      }

      connectedGroups[groupId] = true;
      return groupId;
    }
    /**
     * @deprecated
     */

    function disConnect(groupId) {
      connectedGroups[groupId] = false;
    }
    /**
     * Alias and backward compatibility
     */

    var disconnect = disConnect;
    /**
     * Dispose a chart instance
     */

    function dispose$1(chart) {
      if (isString(chart)) {
        chart = instances$1[chart];
      } else if (!(chart instanceof ECharts)) {
        // Try to treat as dom
        chart = getInstanceByDom(chart);
      }

      if (chart instanceof ECharts && !chart.isDisposed()) {
        chart.dispose();
      }
    }
    function getInstanceByDom(dom) {
      return instances$1[getAttribute(dom, DOM_ATTRIBUTE_KEY)];
    }
    function getInstanceById(key) {
      return instances$1[key];
    }
    /**
     * Register theme
     */

    function registerTheme(name, theme) {
      themeStorage[name] = theme;
    }
    /**
     * Register option preprocessor
     */

    function registerPreprocessor(preprocessorFunc) {
      if (indexOf(optionPreprocessorFuncs, preprocessorFunc) < 0) {
        optionPreprocessorFuncs.push(preprocessorFunc);
      }
    }
    function registerProcessor(priority, processor) {
      normalizeRegister(dataProcessorFuncs, priority, processor, PRIORITY_PROCESSOR_DEFAULT);
    }
    /**
     * Register postIniter
     * @param {Function} postInitFunc
     */

    function registerPostInit(postInitFunc) {
      registerUpdateLifecycle('afterinit', postInitFunc);
    }
    /**
     * Register postUpdater
     * @param {Function} postUpdateFunc
     */

    function registerPostUpdate(postUpdateFunc) {
      registerUpdateLifecycle('afterupdate', postUpdateFunc);
    }
    function registerUpdateLifecycle(name, cb) {
      lifecycle.on(name, cb);
    }
    function registerAction(actionInfo, eventName, action) {
      if (isFunction(eventName)) {
        action = eventName;
        eventName = '';
      }

      var actionType = isObject(actionInfo) ? actionInfo.type : [actionInfo, actionInfo = {
        event: eventName
      }][0]; // Event name is all lowercase

      actionInfo.event = (actionInfo.event || actionType).toLowerCase();
      eventName = actionInfo.event;

      if (eventActionMap[eventName]) {
        // Already registered.
        return;
      } // Validate action type and event name.


      assert(ACTION_REG.test(actionType) && ACTION_REG.test(eventName));

      if (!actions[actionType]) {
        actions[actionType] = {
          action: action,
          actionInfo: actionInfo
        };
      }

      eventActionMap[eventName] = actionType;
    }
    function registerCoordinateSystem(type, coordSysCreator) {
      CoordinateSystemManager.register(type, coordSysCreator);
    }
    /**
     * Get dimensions of specified coordinate system.
     * @param {string} type
     * @return {Array.<string|Object>}
     */

    function getCoordinateSystemDimensions(type) {
      var coordSysCreator = CoordinateSystemManager.get(type);

      if (coordSysCreator) {
        return coordSysCreator.getDimensionsInfo ? coordSysCreator.getDimensionsInfo() : coordSysCreator.dimensions.slice();
      }
    }

    function registerLayout(priority, layoutTask) {
      normalizeRegister(visualFuncs, priority, layoutTask, PRIORITY_VISUAL_LAYOUT, 'layout');
    }

    function registerVisual(priority, visualTask) {
      normalizeRegister(visualFuncs, priority, visualTask, PRIORITY_VISUAL_CHART, 'visual');
    }
    var registeredTasks = [];

    function normalizeRegister(targetList, priority, fn, defaultPriority, visualType) {
      if (isFunction(priority) || isObject(priority)) {
        fn = priority;
        priority = defaultPriority;
      }

      if ("development" !== 'production') {
        if (isNaN(priority) || priority == null) {
          throw new Error('Illegal priority');
        } // Check duplicate


        each(targetList, function (wrap) {
          assert(wrap.__raw !== fn);
        });
      } // Already registered


      if (indexOf(registeredTasks, fn) >= 0) {
        return;
      }

      registeredTasks.push(fn);
      var stageHandler = Scheduler.wrapStageHandler(fn, visualType);
      stageHandler.__prio = priority;
      stageHandler.__raw = fn;
      targetList.push(stageHandler);
    }

    function registerLoading(name, loadingFx) {
      loadingEffects[name] = loadingFx;
    }
    /**
     * ZRender need a canvas context to do measureText.
     * But in node environment canvas may be created by node-canvas.
     * So we need to specify how to create a canvas instead of using document.createElement('canvas')
     *
     *
     * @deprecated use setPlatformAPI({ createCanvas }) instead.
     *
     * @example
     *     let Canvas = require('canvas');
     *     let echarts = require('echarts');
     *     echarts.setCanvasCreator(function () {
     *         // Small size is enough.
     *         return new Canvas(32, 32);
     *     });
     */

    function setCanvasCreator(creator) {
      if ("development" !== 'production') {
        deprecateLog('setCanvasCreator is deprecated. Use setPlatformAPI({ createCanvas }) instead.');
      }

      setPlatformAPI({
        createCanvas: creator
      });
    }
    /**
     * The parameters and usage: see `geoSourceManager.registerMap`.
     * Compatible with previous `echarts.registerMap`.
     */

    function registerMap(mapName, geoJson, specialAreas) {
      var registerMap = getImpl('registerMap');
      registerMap && registerMap(mapName, geoJson, specialAreas);
    }
    function getMap(mapName) {
      var getMap = getImpl('getMap');
      return getMap && getMap(mapName);
    }
    var registerTransform = registerExternalTransform;
    /**
     * Globa dispatchAction to a specified chart instance.
     */
    // export function dispatchAction(payload: { chartId: string } & Payload, opt?: Parameters<ECharts['dispatchAction']>[1]) {
    //     if (!payload || !payload.chartId) {
    //         // Must have chartId to find chart
    //         return;
    //     }
    //     const chart = instances[payload.chartId];
    //     if (chart) {
    //         chart.dispatchAction(payload, opt);
    //     }
    // }
    // Builtin global visual

    registerVisual(PRIORITY_VISUAL_GLOBAL, seriesStyleTask);
    registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataStyleTask);
    registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataColorPaletteTask);
    registerVisual(PRIORITY_VISUAL_GLOBAL, seriesSymbolTask);
    registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataSymbolTask);
    registerVisual(PRIORITY_VISUAL_DECAL, decalVisual);
    registerPreprocessor(globalBackwardCompat);
    registerProcessor(PRIORITY_PROCESSOR_DATASTACK, dataStack);
    registerLoading('default', defaultLoading); // Default actions

    registerAction({
      type: HIGHLIGHT_ACTION_TYPE,
      event: HIGHLIGHT_ACTION_TYPE,
      update: HIGHLIGHT_ACTION_TYPE
    }, noop);
    registerAction({
      type: DOWNPLAY_ACTION_TYPE,
      event: DOWNPLAY_ACTION_TYPE,
      update: DOWNPLAY_ACTION_TYPE
    }, noop);
    registerAction({
      type: SELECT_ACTION_TYPE,
      event: SELECT_ACTION_TYPE,
      update: SELECT_ACTION_TYPE
    }, noop);
    registerAction({
      type: UNSELECT_ACTION_TYPE,
      event: UNSELECT_ACTION_TYPE,
      update: UNSELECT_ACTION_TYPE
    }, noop);
    registerAction({
      type: TOGGLE_SELECT_ACTION_TYPE,
      event: TOGGLE_SELECT_ACTION_TYPE,
      update: TOGGLE_SELECT_ACTION_TYPE
    }, noop); // Default theme

    registerTheme('light', lightTheme);
    registerTheme('dark', theme); // For backward compatibility, where the namespace `dataTool` will
    // be mounted on `echarts` is the extension `dataTool` is imported.

    var dataTool = {};

    var extensions = [];
    var extensionRegisters = {
      registerPreprocessor: registerPreprocessor,
      registerProcessor: registerProcessor,
      registerPostInit: registerPostInit,
      registerPostUpdate: registerPostUpdate,
      registerUpdateLifecycle: registerUpdateLifecycle,
      registerAction: registerAction,
      registerCoordinateSystem: registerCoordinateSystem,
      registerLayout: registerLayout,
      registerVisual: registerVisual,
      registerTransform: registerTransform,
      registerLoading: registerLoading,
      registerMap: registerMap,
      registerImpl: registerImpl,
      PRIORITY: PRIORITY,
      ComponentModel: ComponentModel,
      ComponentView: ComponentView,
      SeriesModel: SeriesModel,
      ChartView: ChartView,
      // TODO Use ComponentModel and SeriesModel instead of Constructor
      registerComponentModel: function (ComponentModelClass) {
        ComponentModel.registerClass(ComponentModelClass);
      },
      registerComponentView: function (ComponentViewClass) {
        ComponentView.registerClass(ComponentViewClass);
      },
      registerSeriesModel: function (SeriesModelClass) {
        SeriesModel.registerClass(SeriesModelClass);
      },
      registerChartView: function (ChartViewClass) {
        ChartView.registerClass(ChartViewClass);
      },
      registerSubTypeDefaulter: function (componentType, defaulter) {
        ComponentModel.registerSubTypeDefaulter(componentType, defaulter);
      },
      registerPainter: function (painterType, PainterCtor) {
        registerPainter(painterType, PainterCtor);
      }
    };
    function use(ext) {
      if (isArray(ext)) {
        // use([ChartLine, ChartBar]);
        each(ext, function (singleExt) {
          use(singleExt);
        });
        return;
      }

      if (indexOf(extensions, ext) >= 0) {
        return;
      }

      extensions.push(ext);

      if (isFunction(ext)) {
        ext = {
          install: ext
        };
      }

      ext.install(extensionRegisters);
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    function dataIndexMapValueLength(valNumOrArrLengthMoreThan2) {
      return valNumOrArrLengthMoreThan2 == null ? 0 : valNumOrArrLengthMoreThan2.length || 1;
    }

    function defaultKeyGetter(item) {
      return item;
    }

    var DataDiffer =
    /** @class */
    function () {
      /**
       * @param context Can be visited by this.context in callback.
       */
      function DataDiffer(oldArr, newArr, oldKeyGetter, newKeyGetter, context, // By default: 'oneToOne'.
      diffMode) {
        this._old = oldArr;
        this._new = newArr;
        this._oldKeyGetter = oldKeyGetter || defaultKeyGetter;
        this._newKeyGetter = newKeyGetter || defaultKeyGetter; // Visible in callback via `this.context`;

        this.context = context;
        this._diffModeMultiple = diffMode === 'multiple';
      }
      /**
       * Callback function when add a data
       */


      DataDiffer.prototype.add = function (func) {
        this._add = func;
        return this;
      };
      /**
       * Callback function when update a data
       */


      DataDiffer.prototype.update = function (func) {
        this._update = func;
        return this;
      };
      /**
       * Callback function when update a data and only work in `cbMode: 'byKey'`.
       */


      DataDiffer.prototype.updateManyToOne = function (func) {
        this._updateManyToOne = func;
        return this;
      };
      /**
       * Callback function when update a data and only work in `cbMode: 'byKey'`.
       */


      DataDiffer.prototype.updateOneToMany = function (func) {
        this._updateOneToMany = func;
        return this;
      };
      /**
       * Callback function when update a data and only work in `cbMode: 'byKey'`.
       */


      DataDiffer.prototype.updateManyToMany = function (func) {
        this._updateManyToMany = func;
        return this;
      };
      /**
       * Callback function when remove a data
       */


      DataDiffer.prototype.remove = function (func) {
        this._remove = func;
        return this;
      };

      DataDiffer.prototype.execute = function () {
        this[this._diffModeMultiple ? '_executeMultiple' : '_executeOneToOne']();
      };

      DataDiffer.prototype._executeOneToOne = function () {
        var oldArr = this._old;
        var newArr = this._new;
        var newDataIndexMap = {};
        var oldDataKeyArr = new Array(oldArr.length);
        var newDataKeyArr = new Array(newArr.length);

        this._initIndexMap(oldArr, null, oldDataKeyArr, '_oldKeyGetter');

        this._initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter');

        for (var i = 0; i < oldArr.length; i++) {
          var oldKey = oldDataKeyArr[i];
          var newIdxMapVal = newDataIndexMap[oldKey];
          var newIdxMapValLen = dataIndexMapValueLength(newIdxMapVal); // idx can never be empty array here. see 'set null' logic below.

          if (newIdxMapValLen > 1) {
            // Consider there is duplicate key (for example, use dataItem.name as key).
            // We should make sure every item in newArr and oldArr can be visited.
            var newIdx = newIdxMapVal.shift();

            if (newIdxMapVal.length === 1) {
              newDataIndexMap[oldKey] = newIdxMapVal[0];
            }

            this._update && this._update(newIdx, i);
          } else if (newIdxMapValLen === 1) {
            newDataIndexMap[oldKey] = null;
            this._update && this._update(newIdxMapVal, i);
          } else {
            this._remove && this._remove(i);
          }
        }

        this._performRestAdd(newDataKeyArr, newDataIndexMap);
      };
      /**
       * For example, consider the case:
       * oldData: [o0, o1, o2, o3, o4, o5, o6, o7],
       * newData: [n0, n1, n2, n3, n4, n5, n6, n7, n8],
       * Where:
       *     o0, o1, n0 has key 'a' (many to one)
       *     o5, n4, n5, n6 has key 'b' (one to many)
       *     o2, n1 has key 'c' (one to one)
       *     n2, n3 has key 'd' (add)
       *     o3, o4 has key 'e' (remove)
       *     o6, o7, n7, n8 has key 'f' (many to many, treated as add and remove)
       * Then:
       *     (The order of the following directives are not ensured.)
       *     this._updateManyToOne(n0, [o0, o1]);
       *     this._updateOneToMany([n4, n5, n6], o5);
       *     this._update(n1, o2);
       *     this._remove(o3);
       *     this._remove(o4);
       *     this._remove(o6);
       *     this._remove(o7);
       *     this._add(n2);
       *     this._add(n3);
       *     this._add(n7);
       *     this._add(n8);
       */


      DataDiffer.prototype._executeMultiple = function () {
        var oldArr = this._old;
        var newArr = this._new;
        var oldDataIndexMap = {};
        var newDataIndexMap = {};
        var oldDataKeyArr = [];
        var newDataKeyArr = [];

        this._initIndexMap(oldArr, oldDataIndexMap, oldDataKeyArr, '_oldKeyGetter');

        this._initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter');

        for (var i = 0; i < oldDataKeyArr.length; i++) {
          var oldKey = oldDataKeyArr[i];
          var oldIdxMapVal = oldDataIndexMap[oldKey];
          var newIdxMapVal = newDataIndexMap[oldKey];
          var oldIdxMapValLen = dataIndexMapValueLength(oldIdxMapVal);
          var newIdxMapValLen = dataIndexMapValueLength(newIdxMapVal);

          if (oldIdxMapValLen > 1 && newIdxMapValLen === 1) {
            this._updateManyToOne && this._updateManyToOne(newIdxMapVal, oldIdxMapVal);
            newDataIndexMap[oldKey] = null;
          } else if (oldIdxMapValLen === 1 && newIdxMapValLen > 1) {
            this._updateOneToMany && this._updateOneToMany(newIdxMapVal, oldIdxMapVal);
            newDataIndexMap[oldKey] = null;
          } else if (oldIdxMapValLen === 1 && newIdxMapValLen === 1) {
            this._update && this._update(newIdxMapVal, oldIdxMapVal);
            newDataIndexMap[oldKey] = null;
          } else if (oldIdxMapValLen > 1 && newIdxMapValLen > 1) {
            this._updateManyToMany && this._updateManyToMany(newIdxMapVal, oldIdxMapVal);
            newDataIndexMap[oldKey] = null;
          } else if (oldIdxMapValLen > 1) {
            for (var i_1 = 0; i_1 < oldIdxMapValLen; i_1++) {
              this._remove && this._remove(oldIdxMapVal[i_1]);
            }
          } else {
            this._remove && this._remove(oldIdxMapVal);
          }
        }

        this._performRestAdd(newDataKeyArr, newDataIndexMap);
      };

      DataDiffer.prototype._performRestAdd = function (newDataKeyArr, newDataIndexMap) {
        for (var i = 0; i < newDataKeyArr.length; i++) {
          var newKey = newDataKeyArr[i];
          var newIdxMapVal = newDataIndexMap[newKey];
          var idxMapValLen = dataIndexMapValueLength(newIdxMapVal);

          if (idxMapValLen > 1) {
            for (var j = 0; j < idxMapValLen; j++) {
              this._add && this._add(newIdxMapVal[j]);
            }
          } else if (idxMapValLen === 1) {
            this._add && this._add(newIdxMapVal);
          } // Support both `newDataKeyArr` are duplication removed or not removed.


          newDataIndexMap[newKey] = null;
        }
      };

      DataDiffer.prototype._initIndexMap = function (arr, // Can be null.
      map, // In 'byKey', the output `keyArr` is duplication removed.
      // In 'byIndex', the output `keyArr` is not duplication removed and
      //     its indices are accurately corresponding to `arr`.
      keyArr, keyGetterName) {
        var cbModeMultiple = this._diffModeMultiple;

        for (var i = 0; i < arr.length; i++) {
          // Add prefix to avoid conflict with Object.prototype.
          var key = '_ec_' + this[keyGetterName](arr[i], i);

          if (!cbModeMultiple) {
            keyArr[i] = key;
          }

          if (!map) {
            continue;
          }

          var idxMapVal = map[key];
          var idxMapValLen = dataIndexMapValueLength(idxMapVal);

          if (idxMapValLen === 0) {
            // Simple optimize: in most cases, one index has one key,
            // do not need array.
            map[key] = i;

            if (cbModeMultiple) {
              keyArr.push(key);
            }
          } else if (idxMapValLen === 1) {
            map[key] = [idxMapVal, i];
          } else {
            idxMapVal.push(i);
          }
        }
      };

      return DataDiffer;
    }();

    var DimensionUserOuput =
    /** @class */
    function () {
      function DimensionUserOuput(encode, dimRequest) {
        this._encode = encode;
        this._schema = dimRequest;
      }

      DimensionUserOuput.prototype.get = function () {
        return {
          // Do not generate full dimension name until fist used.
          fullDimensions: this._getFullDimensionNames(),
          encode: this._encode
        };
      };
      /**
       * Get all data store dimension names.
       * Theoretically a series data store is defined both by series and used dataset (if any).
       * If some dimensions are omitted for performance reason in `this.dimensions`,
       * the dimension name may not be auto-generated if user does not specify a dimension name.
       * In this case, the dimension name is `null`/`undefined`.
       */


      DimensionUserOuput.prototype._getFullDimensionNames = function () {
        if (!this._cachedDimNames) {
          this._cachedDimNames = this._schema ? this._schema.makeOutputDimensionNames() : [];
        }

        return this._cachedDimNames;
      };

      return DimensionUserOuput;
    }();
    function summarizeDimensions(data, schema) {
      var summary = {};
      var encode = summary.encode = {};
      var notExtraCoordDimMap = createHashMap();
      var defaultedLabel = [];
      var defaultedTooltip = [];
      var userOutputEncode = {};
      each(data.dimensions, function (dimName) {
        var dimItem = data.getDimensionInfo(dimName);
        var coordDim = dimItem.coordDim;

        if (coordDim) {
          if ("development" !== 'production') {
            assert(VISUAL_DIMENSIONS.get(coordDim) == null);
          }

          var coordDimIndex = dimItem.coordDimIndex;
          getOrCreateEncodeArr(encode, coordDim)[coordDimIndex] = dimName;

          if (!dimItem.isExtraCoord) {
            notExtraCoordDimMap.set(coordDim, 1); // Use the last coord dim (and label friendly) as default label,
            // because when dataset is used, it is hard to guess which dimension
            // can be value dimension. If both show x, y on label is not look good,
            // and conventionally y axis is focused more.

            if (mayLabelDimType(dimItem.type)) {
              defaultedLabel[0] = dimName;
            } // User output encode do not contain generated coords.
            // And it only has index. User can use index to retrieve value from the raw item array.


            getOrCreateEncodeArr(userOutputEncode, coordDim)[coordDimIndex] = data.getDimensionIndex(dimItem.name);
          }

          if (dimItem.defaultTooltip) {
            defaultedTooltip.push(dimName);
          }
        }

        VISUAL_DIMENSIONS.each(function (v, otherDim) {
          var encodeArr = getOrCreateEncodeArr(encode, otherDim);
          var dimIndex = dimItem.otherDims[otherDim];

          if (dimIndex != null && dimIndex !== false) {
            encodeArr[dimIndex] = dimItem.name;
          }
        });
      });
      var dataDimsOnCoord = [];
      var encodeFirstDimNotExtra = {};
      notExtraCoordDimMap.each(function (v, coordDim) {
        var dimArr = encode[coordDim];
        encodeFirstDimNotExtra[coordDim] = dimArr[0]; // Not necessary to remove duplicate, because a data
        // dim canot on more than one coordDim.

        dataDimsOnCoord = dataDimsOnCoord.concat(dimArr);
      });
      summary.dataDimsOnCoord = dataDimsOnCoord;
      summary.dataDimIndicesOnCoord = map(dataDimsOnCoord, function (dimName) {
        return data.getDimensionInfo(dimName).storeDimIndex;
      });
      summary.encodeFirstDimNotExtra = encodeFirstDimNotExtra;
      var encodeLabel = encode.label; // FIXME `encode.label` is not recommended, because formatter cannot be set
      // in this way. Use label.formatter instead. Maybe remove this approach someday.

      if (encodeLabel && encodeLabel.length) {
        defaultedLabel = encodeLabel.slice();
      }

      var encodeTooltip = encode.tooltip;

      if (encodeTooltip && encodeTooltip.length) {
        defaultedTooltip = encodeTooltip.slice();
      } else if (!defaultedTooltip.length) {
        defaultedTooltip = defaultedLabel.slice();
      }

      encode.defaultedLabel = defaultedLabel;
      encode.defaultedTooltip = defaultedTooltip;
      summary.userOutput = new DimensionUserOuput(userOutputEncode, schema);
      return summary;
    }

    function getOrCreateEncodeArr(encode, dim) {
      if (!encode.hasOwnProperty(dim)) {
        encode[dim] = [];
      }

      return encode[dim];
    } // FIXME:TS should be type `AxisType`


    function getDimensionTypeByAxis(axisType) {
      return axisType === 'category' ? 'ordinal' : axisType === 'time' ? 'time' : 'float';
    }

    function mayLabelDimType(dimType) {
      // In most cases, ordinal and time do not suitable for label.
      // Ordinal info can be displayed on axis. Time is too long.
      return !(dimType === 'ordinal' || dimType === 'time');
    } // function findTheLastDimMayLabel(data) {
    //     // Get last value dim
    //     let dimensions = data.dimensions.slice();
    //     let valueType;
    //     let valueDim;
    //     while (dimensions.length && (
    //         valueDim = dimensions.pop(),
    //         valueType = data.getDimensionInfo(valueDim).type,
    //         valueType === 'ordinal' || valueType === 'time'
    //     )) {} // jshint ignore:line
    //     return valueDim;
    // }

    var SeriesDimensionDefine =
    /** @class */
    function () {
      /**
       * @param opt All of the fields will be shallow copied.
       */
      function SeriesDimensionDefine(opt) {
        /**
         * The format of `otherDims` is:
         * ```js
         * {
         *     tooltip?: number
         *     label?: number
         *     itemName?: number
         *     seriesName?: number
         * }
         * ```
         *
         * A `series.encode` can specified these fields:
         * ```js
         * encode: {
         *     // "3, 1, 5" is the index of data dimension.
         *     tooltip: [3, 1, 5],
         *     label: [0, 3],
         *     ...
         * }
         * ```
         * `otherDims` is the parse result of the `series.encode` above, like:
         * ```js
         * // Suppose the index of this data dimension is `3`.
         * this.otherDims = {
         *     // `3` is at the index `0` of the `encode.tooltip`
         *     tooltip: 0,
         *     // `3` is at the index `1` of the `encode.label`
         *     label: 1
         * };
         * ```
         *
         * This prop should never be `null`/`undefined` after initialized.
         */
        this.otherDims = {};

        if (opt != null) {
          extend(this, opt);
        }
      }

      return SeriesDimensionDefine;
    }();

    var inner$4 = makeInner();
    var dimTypeShort = {
      float: 'f',
      int: 'i',
      ordinal: 'o',
      number: 'n',
      time: 't'
    };
    /**
     * Represents the dimension requirement of a series.
     *
     * NOTICE:
     * When there are too many dimensions in dataset and many series, only the used dimensions
     * (i.e., used by coord sys and declared in `series.encode`) are add to `dimensionDefineList`.
     * But users may query data by other unused dimension names.
     * In this case, users can only query data if and only if they have defined dimension names
     * via ec option, so we provide `getDimensionIndexFromSource`, which only query them from
     * `source` dimensions.
     */

    var SeriesDataSchema =
    /** @class */
    function () {
      function SeriesDataSchema(opt) {
        this.dimensions = opt.dimensions;
        this._dimOmitted = opt.dimensionOmitted;
        this.source = opt.source;
        this._fullDimCount = opt.fullDimensionCount;

        this._updateDimOmitted(opt.dimensionOmitted);
      }

      SeriesDataSchema.prototype.isDimensionOmitted = function () {
        return this._dimOmitted;
      };

      SeriesDataSchema.prototype._updateDimOmitted = function (dimensionOmitted) {
        this._dimOmitted = dimensionOmitted;

        if (!dimensionOmitted) {
          return;
        }

        if (!this._dimNameMap) {
          this._dimNameMap = ensureSourceDimNameMap(this.source);
        }
      };
      /**
       * @caution Can only be used when `dimensionOmitted: true`.
       *
       * Get index by user defined dimension name (i.e., not internal generate name).
       * That is, get index from `dimensionsDefine`.
       * If no `dimensionsDefine`, or no name get, return -1.
       */


      SeriesDataSchema.prototype.getSourceDimensionIndex = function (dimName) {
        return retrieve2(this._dimNameMap.get(dimName), -1);
      };
      /**
       * @caution Can only be used when `dimensionOmitted: true`.
       *
       * Notice: may return `null`/`undefined` if user not specify dimension names.
       */


      SeriesDataSchema.prototype.getSourceDimension = function (dimIndex) {
        var dimensionsDefine = this.source.dimensionsDefine;

        if (dimensionsDefine) {
          return dimensionsDefine[dimIndex];
        }
      };

      SeriesDataSchema.prototype.makeStoreSchema = function () {
        var dimCount = this._fullDimCount;
        var willRetrieveDataByName = shouldRetrieveDataByName(this.source);
        var makeHashStrict = !shouldOmitUnusedDimensions(dimCount); // If source don't have dimensions or series don't omit unsed dimensions.
        // Generate from seriesDimList directly

        var dimHash = '';
        var dims = [];

        for (var fullDimIdx = 0, seriesDimIdx = 0; fullDimIdx < dimCount; fullDimIdx++) {
          var property = void 0;
          var type = void 0;
          var ordinalMeta = void 0;
          var seriesDimDef = this.dimensions[seriesDimIdx]; // The list has been sorted by `storeDimIndex` asc.

          if (seriesDimDef && seriesDimDef.storeDimIndex === fullDimIdx) {
            property = willRetrieveDataByName ? seriesDimDef.name : null;
            type = seriesDimDef.type;
            ordinalMeta = seriesDimDef.ordinalMeta;
            seriesDimIdx++;
          } else {
            var sourceDimDef = this.getSourceDimension(fullDimIdx);

            if (sourceDimDef) {
              property = willRetrieveDataByName ? sourceDimDef.name : null;
              type = sourceDimDef.type;
            }
          }

          dims.push({
            property: property,
            type: type,
            ordinalMeta: ordinalMeta
          }); // If retrieving data by index,
          //   use <index, type, ordinalMeta> to determine whether data can be shared.
          //   (Because in this case there might be no dimension name defined in dataset, but indices always exists).
          //   (Indices are always 0, 1, 2, ..., so we can ignore them to shorten the hash).
          // Otherwise if retrieving data by property name (like `data: [{aa: 123, bb: 765}, ...]`),
          //   use <property, type, ordinalMeta> in hash.

          if (willRetrieveDataByName && property != null // For data stack, we have make sure each series has its own dim on this store.
          // So we do not add property to hash to make sure they can share this store.
          && (!seriesDimDef || !seriesDimDef.isCalculationCoord)) {
            dimHash += makeHashStrict // Use escape character '`' in case that property name contains '$'.
            ? property.replace(/\`/g, '`1').replace(/\$/g, '`2') // For better performance, when there are large dimensions, tolerant this defects that hardly meet.
            : property;
          }

          dimHash += '$';
          dimHash += dimTypeShort[type] || 'f';

          if (ordinalMeta) {
            dimHash += ordinalMeta.uid;
          }

          dimHash += '$';
        } // Source from endpoint(usually series) will be read differently
        // when seriesLayoutBy or startIndex(which is affected by sourceHeader) are different.
        // So we use this three props as key.


        var source = this.source;
        var hash = [source.seriesLayoutBy, source.startIndex, dimHash].join('$$');
        return {
          dimensions: dims,
          hash: hash
        };
      };

      SeriesDataSchema.prototype.makeOutputDimensionNames = function () {
        var result = [];

        for (var fullDimIdx = 0, seriesDimIdx = 0; fullDimIdx < this._fullDimCount; fullDimIdx++) {
          var name_1 = void 0;
          var seriesDimDef = this.dimensions[seriesDimIdx]; // The list has been sorted by `storeDimIndex` asc.

          if (seriesDimDef && seriesDimDef.storeDimIndex === fullDimIdx) {
            if (!seriesDimDef.isCalculationCoord) {
              name_1 = seriesDimDef.name;
            }

            seriesDimIdx++;
          } else {
            var sourceDimDef = this.getSourceDimension(fullDimIdx);

            if (sourceDimDef) {
              name_1 = sourceDimDef.name;
            }
          }

          result.push(name_1);
        }

        return result;
      };

      SeriesDataSchema.prototype.appendCalculationDimension = function (dimDef) {
        this.dimensions.push(dimDef);
        dimDef.isCalculationCoord = true;
        this._fullDimCount++; // If append dimension on a data store, consider the store
        // might be shared by different series, series dimensions not
        // really map to store dimensions.

        this._updateDimOmitted(true);
      };

      return SeriesDataSchema;
    }();
    function isSeriesDataSchema(schema) {
      return schema instanceof SeriesDataSchema;
    }
    function createDimNameMap(dimsDef) {
      var dataDimNameMap = createHashMap();

      for (var i = 0; i < (dimsDef || []).length; i++) {
        var dimDefItemRaw = dimsDef[i];
        var userDimName = isObject(dimDefItemRaw) ? dimDefItemRaw.name : dimDefItemRaw;

        if (userDimName != null && dataDimNameMap.get(userDimName) == null) {
          dataDimNameMap.set(userDimName, i);
        }
      }

      return dataDimNameMap;
    }
    function ensureSourceDimNameMap(source) {
      var innerSource = inner$4(source);
      return innerSource.dimNameMap || (innerSource.dimNameMap = createDimNameMap(source.dimensionsDefine));
    }
    function shouldOmitUnusedDimensions(dimCount) {
      return dimCount > 30;
    }

    var isObject$2 = isObject;
    var map$1 = map;
    var CtorInt32Array$1 = typeof Int32Array === 'undefined' ? Array : Int32Array; // Use prefix to avoid index to be the same as otherIdList[idx],
    // which will cause weird update animation.

    var ID_PREFIX = 'e\0\0';
    var INDEX_NOT_FOUND = -1; // type SeriesDimensionIndex = DimensionIndex;

    var TRANSFERABLE_PROPERTIES = ['hasItemOption', '_nameList', '_idList', '_invertedIndicesMap', '_dimSummary', 'userOutput', '_rawData', '_dimValueGetter', '_nameDimIdx', '_idDimIdx', '_nameRepeatCount'];
    var CLONE_PROPERTIES = ['_approximateExtent']; // -----------------------------
    // Internal method declarations:
    // -----------------------------

    var prepareInvertedIndex;
    var getId;
    var getIdNameFromStore;
    var normalizeDimensions;
    var transferProperties;
    var cloneListForMapAndSample;
    var makeIdFromName;

    var SeriesData =
    /** @class */
    function () {
      /**
       * @param dimensionsInput.dimensions
       *        For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...].
       *        Dimensions should be concrete names like x, y, z, lng, lat, angle, radius
       */
      function SeriesData(dimensionsInput, hostModel) {
        this.type = 'list';
        this._dimOmitted = false;
        this._nameList = [];
        this._idList = []; // Models of data option is stored sparse for optimizing memory cost
        // Never used yet (not used yet).
        // private _optionModels: Model[] = [];
        // Global visual properties after visual coding

        this._visual = {}; // Global layout properties.

        this._layout = {}; // Item visual properties after visual coding

        this._itemVisuals = []; // Item layout properties after layout

        this._itemLayouts = []; // Graphic elements

        this._graphicEls = []; // key: dim, value: extent

        this._approximateExtent = {};
        this._calculationInfo = {}; // Having detected that there is data item is non primitive type
        // (in type `OptionDataItemObject`).
        // Like `data: [ { value: xx, itemStyle: {...} }, ...]`
        // At present it only happen in `SOURCE_FORMAT_ORIGINAL`.

        this.hasItemOption = false; // Methods that create a new list based on this list should be listed here.
        // Notice that those method should `RETURN` the new list.

        this.TRANSFERABLE_METHODS = ['cloneShallow', 'downSample', 'lttbDownSample', 'map']; // Methods that change indices of this list should be listed here.

        this.CHANGABLE_METHODS = ['filterSelf', 'selectRange'];
        this.DOWNSAMPLE_METHODS = ['downSample', 'lttbDownSample'];
        var dimensions;
        var assignStoreDimIdx = false;

        if (isSeriesDataSchema(dimensionsInput)) {
          dimensions = dimensionsInput.dimensions;
          this._dimOmitted = dimensionsInput.isDimensionOmitted();
          this._schema = dimensionsInput;
        } else {
          assignStoreDimIdx = true;
          dimensions = dimensionsInput;
        }

        dimensions = dimensions || ['x', 'y'];
        var dimensionInfos = {};
        var dimensionNames = [];
        var invertedIndicesMap = {};
        var needsHasOwn = false;
        var emptyObj = {};

        for (var i = 0; i < dimensions.length; i++) {
          // Use the original dimensions[i], where other flag props may exists.
          var dimInfoInput = dimensions[i];
          var dimensionInfo = isString(dimInfoInput) ? new SeriesDimensionDefine({
            name: dimInfoInput
          }) : !(dimInfoInput instanceof SeriesDimensionDefine) ? new SeriesDimensionDefine(dimInfoInput) : dimInfoInput;
          var dimensionName = dimensionInfo.name;
          dimensionInfo.type = dimensionInfo.type || 'float';

          if (!dimensionInfo.coordDim) {
            dimensionInfo.coordDim = dimensionName;
            dimensionInfo.coordDimIndex = 0;
          }

          var otherDims = dimensionInfo.otherDims = dimensionInfo.otherDims || {};
          dimensionNames.push(dimensionName);
          dimensionInfos[dimensionName] = dimensionInfo;

          if (emptyObj[dimensionName] != null) {
            needsHasOwn = true;
          }

          if (dimensionInfo.createInvertedIndices) {
            invertedIndicesMap[dimensionName] = [];
          }

          if (otherDims.itemName === 0) {
            this._nameDimIdx = i;
          }

          if (otherDims.itemId === 0) {
            this._idDimIdx = i;
          }

          if ("development" !== 'production') {
            assert(assignStoreDimIdx || dimensionInfo.storeDimIndex >= 0);
          }

          if (assignStoreDimIdx) {
            dimensionInfo.storeDimIndex = i;
          }
        }

        this.dimensions = dimensionNames;
        this._dimInfos = dimensionInfos;

        this._initGetDimensionInfo(needsHasOwn);

        this.hostModel = hostModel;
        this._invertedIndicesMap = invertedIndicesMap;

        if (this._dimOmitted) {
          var dimIdxToName_1 = this._dimIdxToName = createHashMap();
          each(dimensionNames, function (dimName) {
            dimIdxToName_1.set(dimensionInfos[dimName].storeDimIndex, dimName);
          });
        }
      }
      /**
       *
       * Get concrete dimension name by dimension name or dimension index.
       * If input a dimension name, do not validate whether the dimension name exits.
       *
       * @caution
       * @param dim Must make sure the dimension is `SeriesDimensionLoose`.
       * Because only those dimensions will have auto-generated dimension names if not
       * have a user-specified name, and other dimensions will get a return of null/undefined.
       *
       * @notice Because of this reason, should better use `getDimensionIndex` instead, for examples:
       * ```js
       * const val = data.getStore().get(data.getDimensionIndex(dim), dataIdx);
       * ```
       *
       * @return Concrete dim name.
       */


      SeriesData.prototype.getDimension = function (dim) {
        var dimIdx = this._recognizeDimIndex(dim);

        if (dimIdx == null) {
          return dim;
        }

        dimIdx = dim;

        if (!this._dimOmitted) {
          return this.dimensions[dimIdx];
        } // Retrieve from series dimension definition because it probably contains
        // generated dimension name (like 'x', 'y').


        var dimName = this._dimIdxToName.get(dimIdx);

        if (dimName != null) {
          return dimName;
        }

        var sourceDimDef = this._schema.getSourceDimension(dimIdx);

        if (sourceDimDef) {
          return sourceDimDef.name;
        }
      };
      /**
       * Get dimension index in data store. Return -1 if not found.
       * Can be used to index value from getRawValue.
       */


      SeriesData.prototype.getDimensionIndex = function (dim) {
        var dimIdx = this._recognizeDimIndex(dim);

        if (dimIdx != null) {
          return dimIdx;
        }

        if (dim == null) {
          return -1;
        }

        var dimInfo = this._getDimInfo(dim);

        return dimInfo ? dimInfo.storeDimIndex : this._dimOmitted ? this._schema.getSourceDimensionIndex(dim) : -1;
      };
      /**
       * The meanings of the input parameter `dim`:
       *
       * + If dim is a number (e.g., `1`), it means the index of the dimension.
       *   For example, `getDimension(0)` will return 'x' or 'lng' or 'radius'.
       * + If dim is a number-like string (e.g., `"1"`):
       *     + If there is the same concrete dim name defined in `series.dimensions` or `dataset.dimensions`,
       *        it means that concrete name.
       *     + If not, it will be converted to a number, which means the index of the dimension.
       *        (why? because of the backward compatibility. We have been tolerating number-like string in
       *        dimension setting, although now it seems that it is not a good idea.)
       *     For example, `visualMap[i].dimension: "1"` is the same meaning as `visualMap[i].dimension: 1`,
       *     if no dimension name is defined as `"1"`.
       * + If dim is a not-number-like string, it means the concrete dim name.
       *   For example, it can be be default name `"x"`, `"y"`, `"z"`, `"lng"`, `"lat"`, `"angle"`, `"radius"`,
       *   or customized in `dimensions` property of option like `"age"`.
       *
       * @return recognized `DimensionIndex`. Otherwise return null/undefined (means that dim is `DimensionName`).
       */


      SeriesData.prototype._recognizeDimIndex = function (dim) {
        if (isNumber(dim) // If being a number-like string but not being defined as a dimension name.
        || dim != null && !isNaN(dim) && !this._getDimInfo(dim) && (!this._dimOmitted || this._schema.getSourceDimensionIndex(dim) < 0)) {
          return +dim;
        }
      };

      SeriesData.prototype._getStoreDimIndex = function (dim) {
        var dimIdx = this.getDimensionIndex(dim);

        if ("development" !== 'production') {
          if (dimIdx == null) {
            throw new Error('Unknown dimension ' + dim);
          }
        }

        return dimIdx;
      };
      /**
       * Get type and calculation info of particular dimension
       * @param dim
       *        Dimension can be concrete names like x, y, z, lng, lat, angle, radius
       *        Or a ordinal number. For example getDimensionInfo(0) will return 'x' or 'lng' or 'radius'
       */


      SeriesData.prototype.getDimensionInfo = function (dim) {
        // Do not clone, because there may be categories in dimInfo.
        return this._getDimInfo(this.getDimension(dim));
      };

      SeriesData.prototype._initGetDimensionInfo = function (needsHasOwn) {
        var dimensionInfos = this._dimInfos;
        this._getDimInfo = needsHasOwn ? function (dimName) {
          return dimensionInfos.hasOwnProperty(dimName) ? dimensionInfos[dimName] : undefined;
        } : function (dimName) {
          return dimensionInfos[dimName];
        };
      };
      /**
       * concrete dimension name list on coord.
       */


      SeriesData.prototype.getDimensionsOnCoord = function () {
        return this._dimSummary.dataDimsOnCoord.slice();
      };

      SeriesData.prototype.mapDimension = function (coordDim, idx) {
        var dimensionsSummary = this._dimSummary;

        if (idx == null) {
          return dimensionsSummary.encodeFirstDimNotExtra[coordDim];
        }

        var dims = dimensionsSummary.encode[coordDim];
        return dims ? dims[idx] : null;
      };

      SeriesData.prototype.mapDimensionsAll = function (coordDim) {
        var dimensionsSummary = this._dimSummary;
        var dims = dimensionsSummary.encode[coordDim];
        return (dims || []).slice();
      };

      SeriesData.prototype.getStore = function () {
        return this._store;
      };
      /**
       * Initialize from data
       * @param data source or data or data store.
       * @param nameList The name of a datum is used on data diff and
       *        default label/tooltip.
       *        A name can be specified in encode.itemName,
       *        or dataItem.name (only for series option data),
       *        or provided in nameList from outside.
       */


      SeriesData.prototype.initData = function (data, nameList, dimValueGetter) {
        var _this = this;

        var store;

        if (data instanceof DataStore) {
          store = data;
        }

        if (!store) {
          var dimensions = this.dimensions;
          var provider = isSourceInstance(data) || isArrayLike(data) ? new DefaultDataProvider(data, dimensions.length) : data;
          store = new DataStore();
          var dimensionInfos = map$1(dimensions, function (dimName) {
            return {
              type: _this._dimInfos[dimName].type,
              property: dimName
            };
          });
          store.initData(provider, dimensionInfos, dimValueGetter);
        }

        this._store = store; // Reset

        this._nameList = (nameList || []).slice();
        this._idList = [];
        this._nameRepeatCount = {};

        this._doInit(0, store.count()); // Cache summary info for fast visit. See "dimensionHelper".
        // Needs to be initialized after store is prepared.


        this._dimSummary = summarizeDimensions(this, this._schema);
        this.userOutput = this._dimSummary.userOutput;
      };
      /**
       * Caution: Can be only called on raw data (before `this._indices` created).
       */


      SeriesData.prototype.appendData = function (data) {
        var range = this._store.appendData(data);

        this._doInit(range[0], range[1]);
      };
      /**
       * Caution: Can be only called on raw data (before `this._indices` created).
       * This method does not modify `rawData` (`dataProvider`), but only
       * add values to store.
       *
       * The final count will be increased by `Math.max(values.length, names.length)`.
       *
       * @param values That is the SourceType: 'arrayRows', like
       *        [
       *            [12, 33, 44],
       *            [NaN, 43, 1],
       *            ['-', 'asdf', 0]
       *        ]
       *        Each item is exactly corresponding to a dimension.
       */


      SeriesData.prototype.appendValues = function (values, names) {
        var _a = this._store.appendValues(values, names.length),
            start = _a.start,
            end = _a.end;

        var shouldMakeIdFromName = this._shouldMakeIdFromName();

        this._updateOrdinalMeta();

        if (names) {
          for (var idx = start; idx < end; idx++) {
            var sourceIdx = idx - start;
            this._nameList[idx] = names[sourceIdx];

            if (shouldMakeIdFromName) {
              makeIdFromName(this, idx);
            }
          }
        }
      };

      SeriesData.prototype._updateOrdinalMeta = function () {
        var store = this._store;
        var dimensions = this.dimensions;

        for (var i = 0; i < dimensions.length; i++) {
          var dimInfo = this._dimInfos[dimensions[i]];

          if (dimInfo.ordinalMeta) {
            store.collectOrdinalMeta(dimInfo.storeDimIndex, dimInfo.ordinalMeta);
          }
        }
      };

      SeriesData.prototype._shouldMakeIdFromName = function () {
        var provider = this._store.getProvider();

        return this._idDimIdx == null && provider.getSource().sourceFormat !== SOURCE_FORMAT_TYPED_ARRAY && !provider.fillStorage;
      };

      SeriesData.prototype._doInit = function (start, end) {
        if (start >= end) {
          return;
        }

        var store = this._store;
        var provider = store.getProvider();

        this._updateOrdinalMeta();

        var nameList = this._nameList;
        var idList = this._idList;
        var sourceFormat = provider.getSource().sourceFormat;
        var isFormatOriginal = sourceFormat === SOURCE_FORMAT_ORIGINAL; // Each data item is value
        // [1, 2]
        // 2
        // Bar chart, line chart which uses category axis
        // only gives the 'y' value. 'x' value is the indices of category
        // Use a tempValue to normalize the value to be a (x, y) value
        // If dataItem is {name: ...} or {id: ...}, it has highest priority.
        // This kind of ids and names are always stored `_nameList` and `_idList`.

        if (isFormatOriginal && !provider.pure) {
          var sharedDataItem = [];

          for (var idx = start; idx < end; idx++) {
            // NOTICE: Try not to write things into dataItem
            var dataItem = provider.getItem(idx, sharedDataItem);

            if (!this.hasItemOption && isDataItemOption(dataItem)) {
              this.hasItemOption = true;
            }

            if (dataItem) {
              var itemName = dataItem.name;

              if (nameList[idx] == null && itemName != null) {
                nameList[idx] = convertOptionIdName(itemName, null);
              }

              var itemId = dataItem.id;

              if (idList[idx] == null && itemId != null) {
                idList[idx] = convertOptionIdName(itemId, null);
              }
            }
          }
        }

        if (this._shouldMakeIdFromName()) {
          for (var idx = start; idx < end; idx++) {
            makeIdFromName(this, idx);
          }
        }

        prepareInvertedIndex(this);
      };
      /**
       * PENDING: In fact currently this function is only used to short-circuit
       * the calling of `scale.unionExtentFromData` when data have been filtered by modules
       * like "dataZoom". `scale.unionExtentFromData` is used to calculate data extent for series on
       * an axis, but if a "axis related data filter module" is used, the extent of the axis have
       * been fixed and no need to calling `scale.unionExtentFromData` actually.
       * But if we add "custom data filter" in future, which is not "axis related", this method may
       * be still needed.
       *
       * Optimize for the scenario that data is filtered by a given extent.
       * Consider that if data amount is more than hundreds of thousand,
       * extent calculation will cost more than 10ms and the cache will
       * be erased because of the filtering.
       */


      SeriesData.prototype.getApproximateExtent = function (dim) {
        return this._approximateExtent[dim] || this._store.getDataExtent(this._getStoreDimIndex(dim));
      };
      /**
       * Calculate extent on a filtered data might be time consuming.
       * Approximate extent is only used for: calculate extent of filtered data outside.
       */


      SeriesData.prototype.setApproximateExtent = function (extent, dim) {
        dim = this.getDimension(dim);
        this._approximateExtent[dim] = extent.slice();
      };

      SeriesData.prototype.getCalculationInfo = function (key) {
        return this._calculationInfo[key];
      };

      SeriesData.prototype.setCalculationInfo = function (key, value) {
        isObject$2(key) ? extend(this._calculationInfo, key) : this._calculationInfo[key] = value;
      };
      /**
       * @return Never be null/undefined. `number` will be converted to string. Because:
       * In most cases, name is used in display, where returning a string is more convenient.
       * In other cases, name is used in query (see `indexOfName`), where we can keep the
       * rule that name `2` equals to name `'2'`.
       */


      SeriesData.prototype.getName = function (idx) {
        var rawIndex = this.getRawIndex(idx);
        var name = this._nameList[rawIndex];

        if (name == null && this._nameDimIdx != null) {
          name = getIdNameFromStore(this, this._nameDimIdx, rawIndex);
        }

        if (name == null) {
          name = '';
        }

        return name;
      };

      SeriesData.prototype._getCategory = function (dimIdx, idx) {
        var ordinal = this._store.get(dimIdx, idx);

        var ordinalMeta = this._store.getOrdinalMeta(dimIdx);

        if (ordinalMeta) {
          return ordinalMeta.categories[ordinal];
        }

        return ordinal;
      };
      /**
       * @return Never null/undefined. `number` will be converted to string. Because:
       * In all cases having encountered at present, id is used in making diff comparison, which
       * are usually based on hash map. We can keep the rule that the internal id are always string
       * (treat `2` is the same as `'2'`) to make the related logic simple.
       */


      SeriesData.prototype.getId = function (idx) {
        return getId(this, this.getRawIndex(idx));
      };

      SeriesData.prototype.count = function () {
        return this._store.count();
      };
      /**
       * Get value. Return NaN if idx is out of range.
       *
       * @notice Should better to use `data.getStore().get(dimIndex, dataIdx)` instead.
       */


      SeriesData.prototype.get = function (dim, idx) {
        var store = this._store;
        var dimInfo = this._dimInfos[dim];

        if (dimInfo) {
          return store.get(dimInfo.storeDimIndex, idx);
        }
      };
      /**
       * @notice Should better to use `data.getStore().getByRawIndex(dimIndex, dataIdx)` instead.
       */


      SeriesData.prototype.getByRawIndex = function (dim, rawIdx) {
        var store = this._store;
        var dimInfo = this._dimInfos[dim];

        if (dimInfo) {
          return store.getByRawIndex(dimInfo.storeDimIndex, rawIdx);
        }
      };

      SeriesData.prototype.getIndices = function () {
        return this._store.getIndices();
      };

      SeriesData.prototype.getDataExtent = function (dim) {
        return this._store.getDataExtent(this._getStoreDimIndex(dim));
      };

      SeriesData.prototype.getSum = function (dim) {
        return this._store.getSum(this._getStoreDimIndex(dim));
      };

      SeriesData.prototype.getMedian = function (dim) {
        return this._store.getMedian(this._getStoreDimIndex(dim));
      };

      SeriesData.prototype.getValues = function (dimensions, idx) {
        var _this = this;

        var store = this._store;
        return isArray(dimensions) ? store.getValues(map$1(dimensions, function (dim) {
          return _this._getStoreDimIndex(dim);
        }), idx) : store.getValues(dimensions);
      };
      /**
       * If value is NaN. Including '-'
       * Only check the coord dimensions.
       */


      SeriesData.prototype.hasValue = function (idx) {
        var dataDimIndicesOnCoord = this._dimSummary.dataDimIndicesOnCoord;

        for (var i = 0, len = dataDimIndicesOnCoord.length; i < len; i++) {
          // Ordinal type originally can be string or number.
          // But when an ordinal type is used on coord, it can
          // not be string but only number. So we can also use isNaN.
          if (isNaN(this._store.get(dataDimIndicesOnCoord[i], idx))) {
            return false;
          }
        }

        return true;
      };
      /**
       * Retrieve the index with given name
       */


      SeriesData.prototype.indexOfName = function (name) {
        for (var i = 0, len = this._store.count(); i < len; i++) {
          if (this.getName(i) === name) {
            return i;
          }
        }

        return -1;
      };

      SeriesData.prototype.getRawIndex = function (idx) {
        return this._store.getRawIndex(idx);
      };

      SeriesData.prototype.indexOfRawIndex = function (rawIndex) {
        return this._store.indexOfRawIndex(rawIndex);
      };
      /**
       * Only support the dimension which inverted index created.
       * Do not support other cases until required.
       * @param dim concrete dim
       * @param value ordinal index
       * @return rawIndex
       */


      SeriesData.prototype.rawIndexOf = function (dim, value) {
        var invertedIndices = dim && this._invertedIndicesMap[dim];

        if ("development" !== 'production') {
          if (!invertedIndices) {
            throw new Error('Do not supported yet');
          }
        }

        var rawIndex = invertedIndices[value];

        if (rawIndex == null || isNaN(rawIndex)) {
          return INDEX_NOT_FOUND;
        }

        return rawIndex;
      };
      /**
       * Retrieve the index of nearest value
       * @param dim
       * @param value
       * @param [maxDistance=Infinity]
       * @return If and only if multiple indices has
       *         the same value, they are put to the result.
       */


      SeriesData.prototype.indicesOfNearest = function (dim, value, maxDistance) {
        return this._store.indicesOfNearest(this._getStoreDimIndex(dim), value, maxDistance);
      };

      SeriesData.prototype.each = function (dims, cb, ctx) {

        if (isFunction(dims)) {
          ctx = cb;
          cb = dims;
          dims = [];
        } // ctxCompat just for compat echarts3


        var fCtx = ctx || this;
        var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this);

        this._store.each(dimIndices, fCtx ? bind(cb, fCtx) : cb);
      };

      SeriesData.prototype.filterSelf = function (dims, cb, ctx) {

        if (isFunction(dims)) {
          ctx = cb;
          cb = dims;
          dims = [];
        } // ctxCompat just for compat echarts3


        var fCtx = ctx || this;
        var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this);
        this._store = this._store.filter(dimIndices, fCtx ? bind(cb, fCtx) : cb);
        return this;
      };
      /**
       * Select data in range. (For optimization of filter)
       * (Manually inline code, support 5 million data filtering in data zoom.)
       */


      SeriesData.prototype.selectRange = function (range) {

        var _this = this;

        var innerRange = {};
        var dims = keys(range);
        each(dims, function (dim) {
          var dimIdx = _this._getStoreDimIndex(dim);

          innerRange[dimIdx] = range[dim];
        });
        this._store = this._store.selectRange(innerRange);
        return this;
      };
      /* eslint-enable max-len */


      SeriesData.prototype.mapArray = function (dims, cb, ctx) {

        if (isFunction(dims)) {
          ctx = cb;
          cb = dims;
          dims = [];
        } // ctxCompat just for compat echarts3


        ctx = ctx || this;
        var result = [];
        this.each(dims, function () {
          result.push(cb && cb.apply(this, arguments));
        }, ctx);
        return result;
      };

      SeriesData.prototype.map = function (dims, cb, ctx, ctxCompat) {

        var fCtx = ctx || ctxCompat || this;
        var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this);
        var list = cloneListForMapAndSample(this);
        list._store = this._store.map(dimIndices, fCtx ? bind(cb, fCtx) : cb);
        return list;
      };

      SeriesData.prototype.modify = function (dims, cb, ctx, ctxCompat) {
        var _this = this; // ctxCompat just for compat echarts3


        var fCtx = ctx || ctxCompat || this;

        if ("development" !== 'production') {
          each(normalizeDimensions(dims), function (dim) {
            var dimInfo = _this.getDimensionInfo(dim);

            if (!dimInfo.isCalculationCoord) {
              console.error('Danger: only stack dimension can be modified');
            }
          });
        }

        var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this); // If do shallow clone here, if there are too many stacked series,
        // it still cost lots of memory, because `_store.dimensions` are not shared.
        // We should consider there probably be shallow clone happen in each series
        // in consequent filter/map.

        this._store.modify(dimIndices, fCtx ? bind(cb, fCtx) : cb);
      };
      /**
       * Large data down sampling on given dimension
       * @param sampleIndex Sample index for name and id
       */


      SeriesData.prototype.downSample = function (dimension, rate, sampleValue, sampleIndex) {
        var list = cloneListForMapAndSample(this);
        list._store = this._store.downSample(this._getStoreDimIndex(dimension), rate, sampleValue, sampleIndex);
        return list;
      };
      /**
       * Large data down sampling using largest-triangle-three-buckets
       * @param {string} valueDimension
       * @param {number} targetCount
       */


      SeriesData.prototype.lttbDownSample = function (valueDimension, rate) {
        var list = cloneListForMapAndSample(this);
        list._store = this._store.lttbDownSample(this._getStoreDimIndex(valueDimension), rate);
        return list;
      };

      SeriesData.prototype.getRawDataItem = function (idx) {
        return this._store.getRawDataItem(idx);
      };
      /**
       * Get model of one data item.
       */
      // TODO: Type of data item


      SeriesData.prototype.getItemModel = function (idx) {
        var hostModel = this.hostModel;
        var dataItem = this.getRawDataItem(idx);
        return new Model(dataItem, hostModel, hostModel && hostModel.ecModel);
      };
      /**
       * Create a data differ
       */


      SeriesData.prototype.diff = function (otherList) {
        var thisList = this;
        return new DataDiffer(otherList ? otherList.getStore().getIndices() : [], this.getStore().getIndices(), function (idx) {
          return getId(otherList, idx);
        }, function (idx) {
          return getId(thisList, idx);
        });
      };
      /**
       * Get visual property.
       */


      SeriesData.prototype.getVisual = function (key) {
        var visual = this._visual;
        return visual && visual[key];
      };

      SeriesData.prototype.setVisual = function (kvObj, val) {
        this._visual = this._visual || {};

        if (isObject$2(kvObj)) {
          extend(this._visual, kvObj);
        } else {
          this._visual[kvObj] = val;
        }
      };
      /**
       * Get visual property of single data item
       */
      // eslint-disable-next-line


      SeriesData.prototype.getItemVisual = function (idx, key) {
        var itemVisual = this._itemVisuals[idx];
        var val = itemVisual && itemVisual[key];

        if (val == null) {
          // Use global visual property
          return this.getVisual(key);
        }

        return val;
      };
      /**
       * If exists visual property of single data item
       */


      SeriesData.prototype.hasItemVisual = function () {
        return this._itemVisuals.length > 0;
      };
      /**
       * Make sure itemVisual property is unique
       */
      // TODO: use key to save visual to reduce memory.


      SeriesData.prototype.ensureUniqueItemVisual = function (idx, key) {
        var itemVisuals = this._itemVisuals;
        var itemVisual = itemVisuals[idx];

        if (!itemVisual) {
          itemVisual = itemVisuals[idx] = {};
        }

        var val = itemVisual[key];

        if (val == null) {
          val = this.getVisual(key); // TODO Performance?

          if (isArray(val)) {
            val = val.slice();
          } else if (isObject$2(val)) {
            val = extend({}, val);
          }

          itemVisual[key] = val;
        }

        return val;
      }; // eslint-disable-next-line


      SeriesData.prototype.setItemVisual = function (idx, key, value) {
        var itemVisual = this._itemVisuals[idx] || {};
        this._itemVisuals[idx] = itemVisual;

        if (isObject$2(key)) {
          extend(itemVisual, key);
        } else {
          itemVisual[key] = value;
        }
      };
      /**
       * Clear itemVisuals and list visual.
       */


      SeriesData.prototype.clearAllVisual = function () {
        this._visual = {};
        this._itemVisuals = [];
      };

      SeriesData.prototype.setLayout = function (key, val) {
        isObject$2(key) ? extend(this._layout, key) : this._layout[key] = val;
      };
      /**
       * Get layout property.
       */


      SeriesData.prototype.getLayout = function (key) {
        return this._layout[key];
      };
      /**
       * Get layout of single data item
       */


      SeriesData.prototype.getItemLayout = function (idx) {
        return this._itemLayouts[idx];
      };
      /**
       * Set layout of single data item
       */


      SeriesData.prototype.setItemLayout = function (idx, layout, merge) {
        this._itemLayouts[idx] = merge ? extend(this._itemLayouts[idx] || {}, layout) : layout;
      };
      /**
       * Clear all layout of single data item
       */


      SeriesData.prototype.clearItemLayouts = function () {
        this._itemLayouts.length = 0;
      };
      /**
       * Set graphic element relative to data. It can be set as null
       */


      SeriesData.prototype.setItemGraphicEl = function (idx, el) {
        var seriesIndex = this.hostModel && this.hostModel.seriesIndex;
        setCommonECData(seriesIndex, this.dataType, idx, el);
        this._graphicEls[idx] = el;
      };

      SeriesData.prototype.getItemGraphicEl = function (idx) {
        return this._graphicEls[idx];
      };

      SeriesData.prototype.eachItemGraphicEl = function (cb, context) {
        each(this._graphicEls, function (el, idx) {
          if (el) {
            cb && cb.call(context, el, idx);
          }
        });
      };
      /**
       * Shallow clone a new list except visual and layout properties, and graph elements.
       * New list only change the indices.
       */


      SeriesData.prototype.cloneShallow = function (list) {
        if (!list) {
          list = new SeriesData(this._schema ? this._schema : map$1(this.dimensions, this._getDimInfo, this), this.hostModel);
        }

        transferProperties(list, this);
        list._store = this._store;
        return list;
      };
      /**
       * Wrap some method to add more feature
       */


      SeriesData.prototype.wrapMethod = function (methodName, injectFunction) {
        var originalMethod = this[methodName];

        if (!isFunction(originalMethod)) {
          return;
        }

        this.__wrappedMethods = this.__wrappedMethods || [];

        this.__wrappedMethods.push(methodName);

        this[methodName] = function () {
          var res = originalMethod.apply(this, arguments);
          return injectFunction.apply(this, [res].concat(slice(arguments)));
        };
      }; // ----------------------------------------------------------
      // A work around for internal method visiting private member.
      // ----------------------------------------------------------


      SeriesData.internalField = function () {
        prepareInvertedIndex = function (data) {
          var invertedIndicesMap = data._invertedIndicesMap;
          each(invertedIndicesMap, function (invertedIndices, dim) {
            var dimInfo = data._dimInfos[dim]; // Currently, only dimensions that has ordinalMeta can create inverted indices.

            var ordinalMeta = dimInfo.ordinalMeta;
            var store = data._store;

            if (ordinalMeta) {
              invertedIndices = invertedIndicesMap[dim] = new CtorInt32Array$1(ordinalMeta.categories.length); // The default value of TypedArray is 0. To avoid miss
              // mapping to 0, we should set it as INDEX_NOT_FOUND.

              for (var i = 0; i < invertedIndices.length; i++) {
                invertedIndices[i] = INDEX_NOT_FOUND;
              }

              for (var i = 0; i < store.count(); i++) {
                // Only support the case that all values are distinct.
                invertedIndices[store.get(dimInfo.storeDimIndex, i)] = i;
              }
            }
          });
        };

        getIdNameFromStore = function (data, dimIdx, idx) {
          return convertOptionIdName(data._getCategory(dimIdx, idx), null);
        };
        /**
         * @see the comment of `List['getId']`.
         */


        getId = function (data, rawIndex) {
          var id = data._idList[rawIndex];

          if (id == null && data._idDimIdx != null) {
            id = getIdNameFromStore(data, data._idDimIdx, rawIndex);
          }

          if (id == null) {
            id = ID_PREFIX + rawIndex;
          }

          return id;
        };

        normalizeDimensions = function (dimensions) {
          if (!isArray(dimensions)) {
            dimensions = dimensions != null ? [dimensions] : [];
          }

          return dimensions;
        };
        /**
         * Data in excludeDimensions is copied, otherwise transferred.
         */


        cloneListForMapAndSample = function (original) {
          var list = new SeriesData(original._schema ? original._schema : map$1(original.dimensions, original._getDimInfo, original), original.hostModel); // FIXME If needs stackedOn, value may already been stacked

          transferProperties(list, original);
          return list;
        };

        transferProperties = function (target, source) {
          each(TRANSFERABLE_PROPERTIES.concat(source.__wrappedMethods || []), function (propName) {
            if (source.hasOwnProperty(propName)) {
              target[propName] = source[propName];
            }
          });
          target.__wrappedMethods = source.__wrappedMethods;
          each(CLONE_PROPERTIES, function (propName) {
            target[propName] = clone(source[propName]);
          });
          target._calculationInfo = extend({}, source._calculationInfo);
        };

        makeIdFromName = function (data, idx) {
          var nameList = data._nameList;
          var idList = data._idList;
          var nameDimIdx = data._nameDimIdx;
          var idDimIdx = data._idDimIdx;
          var name = nameList[idx];
          var id = idList[idx];

          if (name == null && nameDimIdx != null) {
            nameList[idx] = name = getIdNameFromStore(data, nameDimIdx, idx);
          }

          if (id == null && idDimIdx != null) {
            idList[idx] = id = getIdNameFromStore(data, idDimIdx, idx);
          }

          if (id == null && name != null) {
            var nameRepeatCount = data._nameRepeatCount;
            var nmCnt = nameRepeatCount[name] = (nameRepeatCount[name] || 0) + 1;
            id = name;

            if (nmCnt > 1) {
              id += '__ec__' + nmCnt;
            }

            idList[idx] = id;
          }
        };
      }();

      return SeriesData;
    }();

    /**
     * For outside usage compat (like echarts-gl are using it).
     */

    function createDimensions(source, opt) {
      return prepareSeriesDataSchema(source, opt).dimensions;
    }
    /**
     * This method builds the relationship between:
     * + "what the coord sys or series requires (see `coordDimensions`)",
     * + "what the user defines (in `encode` and `dimensions`, see `opt.dimensionsDefine` and `opt.encodeDefine`)"
     * + "what the data source provids (see `source`)".
     *
     * Some guess strategy will be adapted if user does not define something.
     * If no 'value' dimension specified, the first no-named dimension will be
     * named as 'value'.
     *
     * @return The results are always sorted by `storeDimIndex` asc.
     */

    function prepareSeriesDataSchema( // TODO: TYPE completeDimensions type
    source, opt) {
      if (!isSourceInstance(source)) {
        source = createSourceFromSeriesDataOption(source);
      }

      opt = opt || {};
      var sysDims = opt.coordDimensions || [];
      var dimsDef = opt.dimensionsDefine || source.dimensionsDefine || [];
      var coordDimNameMap = createHashMap();
      var resultList = [];
      var dimCount = getDimCount(source, sysDims, dimsDef, opt.dimensionsCount); // Try to ignore unused dimensions if sharing a high dimension datastore
      // 30 is an experience value.

      var omitUnusedDimensions = opt.canOmitUnusedDimensions && shouldOmitUnusedDimensions(dimCount);
      var isUsingSourceDimensionsDef = dimsDef === source.dimensionsDefine;
      var dataDimNameMap = isUsingSourceDimensionsDef ? ensureSourceDimNameMap(source) : createDimNameMap(dimsDef);
      var encodeDef = opt.encodeDefine;

      if (!encodeDef && opt.encodeDefaulter) {
        encodeDef = opt.encodeDefaulter(source, dimCount);
      }

      var encodeDefMap = createHashMap(encodeDef);
      var indicesMap = new CtorInt32Array(dimCount);

      for (var i = 0; i < indicesMap.length; i++) {
        indicesMap[i] = -1;
      }

      function getResultItem(dimIdx) {
        var idx = indicesMap[dimIdx];

        if (idx < 0) {
          var dimDefItemRaw = dimsDef[dimIdx];
          var dimDefItem = isObject(dimDefItemRaw) ? dimDefItemRaw : {
            name: dimDefItemRaw
          };
          var resultItem = new SeriesDimensionDefine();
          var userDimName = dimDefItem.name;

          if (userDimName != null && dataDimNameMap.get(userDimName) != null) {
            // Only if `series.dimensions` is defined in option
            // displayName, will be set, and dimension will be displayed vertically in
            // tooltip by default.
            resultItem.name = resultItem.displayName = userDimName;
          }

          dimDefItem.type != null && (resultItem.type = dimDefItem.type);
          dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName);
          var newIdx = resultList.length;
          indicesMap[dimIdx] = newIdx;
          resultItem.storeDimIndex = dimIdx;
          resultList.push(resultItem);
          return resultItem;
        }

        return resultList[idx];
      }

      if (!omitUnusedDimensions) {
        for (var i = 0; i < dimCount; i++) {
          getResultItem(i);
        }
      } // Set `coordDim` and `coordDimIndex` by `encodeDefMap` and normalize `encodeDefMap`.


      encodeDefMap.each(function (dataDimsRaw, coordDim) {
        var dataDims = normalizeToArray(dataDimsRaw).slice(); // Note: It is allowed that `dataDims.length` is `0`, e.g., options is
        // `{encode: {x: -1, y: 1}}`. Should not filter anything in
        // this case.

        if (dataDims.length === 1 && !isString(dataDims[0]) && dataDims[0] < 0) {
          encodeDefMap.set(coordDim, false);
          return;
        }

        var validDataDims = encodeDefMap.set(coordDim, []);
        each(dataDims, function (resultDimIdxOrName, idx) {
          // The input resultDimIdx can be dim name or index.
          var resultDimIdx = isString(resultDimIdxOrName) ? dataDimNameMap.get(resultDimIdxOrName) : resultDimIdxOrName;

          if (resultDimIdx != null && resultDimIdx < dimCount) {
            validDataDims[idx] = resultDimIdx;
            applyDim(getResultItem(resultDimIdx), coordDim, idx);
          }
        });
      }); // Apply templates and default order from `sysDims`.

      var availDimIdx = 0;
      each(sysDims, function (sysDimItemRaw) {
        var coordDim;
        var sysDimItemDimsDef;
        var sysDimItemOtherDims;
        var sysDimItem;

        if (isString(sysDimItemRaw)) {
          coordDim = sysDimItemRaw;
          sysDimItem = {};
        } else {
          sysDimItem = sysDimItemRaw;
          coordDim = sysDimItem.name;
          var ordinalMeta = sysDimItem.ordinalMeta;
          sysDimItem.ordinalMeta = null;
          sysDimItem = extend({}, sysDimItem);
          sysDimItem.ordinalMeta = ordinalMeta; // `coordDimIndex` should not be set directly.

          sysDimItemDimsDef = sysDimItem.dimsDef;
          sysDimItemOtherDims = sysDimItem.otherDims;
          sysDimItem.name = sysDimItem.coordDim = sysDimItem.coordDimIndex = sysDimItem.dimsDef = sysDimItem.otherDims = null;
        }

        var dataDims = encodeDefMap.get(coordDim); // negative resultDimIdx means no need to mapping.

        if (dataDims === false) {
          return;
        }

        dataDims = normalizeToArray(dataDims); // dimensions provides default dim sequences.

        if (!dataDims.length) {
          for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) {
            while (availDimIdx < dimCount && getResultItem(availDimIdx).coordDim != null) {
              availDimIdx++;
            }

            availDimIdx < dimCount && dataDims.push(availDimIdx++);
          }
        } // Apply templates.


        each(dataDims, function (resultDimIdx, coordDimIndex) {
          var resultItem = getResultItem(resultDimIdx); // Coordinate system has a higher priority on dim type than source.

          if (isUsingSourceDimensionsDef && sysDimItem.type != null) {
            resultItem.type = sysDimItem.type;
          }

          applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex);

          if (resultItem.name == null && sysDimItemDimsDef) {
            var sysDimItemDimsDefItem = sysDimItemDimsDef[coordDimIndex];
            !isObject(sysDimItemDimsDefItem) && (sysDimItemDimsDefItem = {
              name: sysDimItemDimsDefItem
            });
            resultItem.name = resultItem.displayName = sysDimItemDimsDefItem.name;
            resultItem.defaultTooltip = sysDimItemDimsDefItem.defaultTooltip;
          } // FIXME refactor, currently only used in case: {otherDims: {tooltip: false}}


          sysDimItemOtherDims && defaults(resultItem.otherDims, sysDimItemOtherDims);
        });
      });

      function applyDim(resultItem, coordDim, coordDimIndex) {
        if (VISUAL_DIMENSIONS.get(coordDim) != null) {
          resultItem.otherDims[coordDim] = coordDimIndex;
        } else {
          resultItem.coordDim = coordDim;
          resultItem.coordDimIndex = coordDimIndex;
          coordDimNameMap.set(coordDim, true);
        }
      } // Make sure the first extra dim is 'value'.


      var generateCoord = opt.generateCoord;
      var generateCoordCount = opt.generateCoordCount;
      var fromZero = generateCoordCount != null;
      generateCoordCount = generateCoord ? generateCoordCount || 1 : 0;
      var extra = generateCoord || 'value';

      function ifNoNameFillWithCoordName(resultItem) {
        if (resultItem.name == null) {
          // Duplication will be removed in the next step.
          resultItem.name = resultItem.coordDim;
        }
      } // Set dim `name` and other `coordDim` and other props.


      if (!omitUnusedDimensions) {
        for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
          var resultItem = getResultItem(resultDimIdx);
          var coordDim = resultItem.coordDim;

          if (coordDim == null) {
            // TODO no need to generate coordDim for isExtraCoord?
            resultItem.coordDim = genCoordDimName(extra, coordDimNameMap, fromZero);
            resultItem.coordDimIndex = 0; // Series specified generateCoord is using out.

            if (!generateCoord || generateCoordCount <= 0) {
              resultItem.isExtraCoord = true;
            }

            generateCoordCount--;
          }

          ifNoNameFillWithCoordName(resultItem);

          if (resultItem.type == null && (guessOrdinal(source, resultDimIdx) === BE_ORDINAL.Must // Consider the case:
          // {
          //    dataset: {source: [
          //        ['2001', 123],
          //        ['2002', 456],
          //        ...
          //        ['The others', 987],
          //    ]},
          //    series: {type: 'pie'}
          // }
          // The first column should better be treated as a "ordinal" although it
          // might not be detected as an "ordinal" by `guessOrdinal`.
          || resultItem.isExtraCoord && (resultItem.otherDims.itemName != null || resultItem.otherDims.seriesName != null))) {
            resultItem.type = 'ordinal';
          }
        }
      } else {
        each(resultList, function (resultItem) {
          // PENDING: guessOrdinal or let user specify type: 'ordinal' manually?
          ifNoNameFillWithCoordName(resultItem);
        }); // Sort dimensions: there are some rule that use the last dim as label,
        // and for some latter travel process easier.

        resultList.sort(function (item0, item1) {
          return item0.storeDimIndex - item1.storeDimIndex;
        });
      }

      removeDuplication(resultList);
      return new SeriesDataSchema({
        source: source,
        dimensions: resultList,
        fullDimensionCount: dimCount,
        dimensionOmitted: omitUnusedDimensions
      });
    }

    function removeDuplication(result) {
      var duplicationMap = createHashMap();

      for (var i = 0; i < result.length; i++) {
        var dim = result[i];
        var dimOriginalName = dim.name;
        var count = duplicationMap.get(dimOriginalName) || 0;

        if (count > 0) {
          // Starts from 0.
          dim.name = dimOriginalName + (count - 1);
        }

        count++;
        duplicationMap.set(dimOriginalName, count);
      }
    } // ??? TODO
    // Originally detect dimCount by data[0]. Should we
    // optimize it to only by sysDims and dimensions and encode.
    // So only necessary dims will be initialized.
    // But
    // (1) custom series should be considered. where other dims
    // may be visited.
    // (2) sometimes user need to calculate bubble size or use visualMap
    // on other dimensions besides coordSys needed.
    // So, dims that is not used by system, should be shared in data store?


    function getDimCount(source, sysDims, dimsDef, optDimCount) {
      // Note that the result dimCount should not small than columns count
      // of data, otherwise `dataDimNameMap` checking will be incorrect.
      var dimCount = Math.max(source.dimensionsDetectedCount || 1, sysDims.length, dimsDef.length, optDimCount || 0);
      each(sysDims, function (sysDimItem) {
        var sysDimItemDimsDef;

        if (isObject(sysDimItem) && (sysDimItemDimsDef = sysDimItem.dimsDef)) {
          dimCount = Math.max(dimCount, sysDimItemDimsDef.length);
        }
      });
      return dimCount;
    }

    function genCoordDimName(name, map, fromZero) {
      if (fromZero || map.hasKey(name)) {
        var i = 0;

        while (map.hasKey(name + i)) {
          i++;
        }

        name += i;
      }

      map.set(name, true);
      return name;
    }

    /**
     * @class
     * For example:
     * {
     *     coordSysName: 'cartesian2d',
     *     coordSysDims: ['x', 'y', ...],
     *     axisMap: HashMap({
     *         x: xAxisModel,
     *         y: yAxisModel
     *     }),
     *     categoryAxisMap: HashMap({
     *         x: xAxisModel,
     *         y: undefined
     *     }),
     *     // The index of the first category axis in `coordSysDims`.
     *     // `null/undefined` means no category axis exists.
     *     firstCategoryDimIndex: 1,
     *     // To replace user specified encode.
     * }
     */

    var CoordSysInfo =
    /** @class */
    function () {
      function CoordSysInfo(coordSysName) {
        this.coordSysDims = [];
        this.axisMap = createHashMap();
        this.categoryAxisMap = createHashMap();
        this.coordSysName = coordSysName;
      }

      return CoordSysInfo;
    }();

    function getCoordSysInfoBySeries(seriesModel) {
      var coordSysName = seriesModel.get('coordinateSystem');
      var result = new CoordSysInfo(coordSysName);
      var fetch = fetchers[coordSysName];

      if (fetch) {
        fetch(seriesModel, result, result.axisMap, result.categoryAxisMap);
        return result;
      }
    }
    var fetchers = {
      cartesian2d: function (seriesModel, result, axisMap, categoryAxisMap) {
        var xAxisModel = seriesModel.getReferringComponents('xAxis', SINGLE_REFERRING).models[0];
        var yAxisModel = seriesModel.getReferringComponents('yAxis', SINGLE_REFERRING).models[0];

        if ("development" !== 'production') {
          if (!xAxisModel) {
            throw new Error('xAxis "' + retrieve(seriesModel.get('xAxisIndex'), seriesModel.get('xAxisId'), 0) + '" not found');
          }

          if (!yAxisModel) {
            throw new Error('yAxis "' + retrieve(seriesModel.get('xAxisIndex'), seriesModel.get('yAxisId'), 0) + '" not found');
          }
        }

        result.coordSysDims = ['x', 'y'];
        axisMap.set('x', xAxisModel);
        axisMap.set('y', yAxisModel);

        if (isCategory(xAxisModel)) {
          categoryAxisMap.set('x', xAxisModel);
          result.firstCategoryDimIndex = 0;
        }

        if (isCategory(yAxisModel)) {
          categoryAxisMap.set('y', yAxisModel);
          result.firstCategoryDimIndex == null && (result.firstCategoryDimIndex = 1);
        }
      },
      singleAxis: function (seriesModel, result, axisMap, categoryAxisMap) {
        var singleAxisModel = seriesModel.getReferringComponents('singleAxis', SINGLE_REFERRING).models[0];

        if ("development" !== 'production') {
          if (!singleAxisModel) {
            throw new Error('singleAxis should be specified.');
          }
        }

        result.coordSysDims = ['single'];
        axisMap.set('single', singleAxisModel);

        if (isCategory(singleAxisModel)) {
          categoryAxisMap.set('single', singleAxisModel);
          result.firstCategoryDimIndex = 0;
        }
      },
      polar: function (seriesModel, result, axisMap, categoryAxisMap) {
        var polarModel = seriesModel.getReferringComponents('polar', SINGLE_REFERRING).models[0];
        var radiusAxisModel = polarModel.findAxisModel('radiusAxis');
        var angleAxisModel = polarModel.findAxisModel('angleAxis');

        if ("development" !== 'production') {
          if (!angleAxisModel) {
            throw new Error('angleAxis option not found');
          }

          if (!radiusAxisModel) {
            throw new Error('radiusAxis option not found');
          }
        }

        result.coordSysDims = ['radius', 'angle'];
        axisMap.set('radius', radiusAxisModel);
        axisMap.set('angle', angleAxisModel);

        if (isCategory(radiusAxisModel)) {
          categoryAxisMap.set('radius', radiusAxisModel);
          result.firstCategoryDimIndex = 0;
        }

        if (isCategory(angleAxisModel)) {
          categoryAxisMap.set('angle', angleAxisModel);
          result.firstCategoryDimIndex == null && (result.firstCategoryDimIndex = 1);
        }
      },
      geo: function (seriesModel, result, axisMap, categoryAxisMap) {
        result.coordSysDims = ['lng', 'lat'];
      },
      parallel: function (seriesModel, result, axisMap, categoryAxisMap) {
        var ecModel = seriesModel.ecModel;
        var parallelModel = ecModel.getComponent('parallel', seriesModel.get('parallelIndex'));
        var coordSysDims = result.coordSysDims = parallelModel.dimensions.slice();
        each(parallelModel.parallelAxisIndex, function (axisIndex, index) {
          var axisModel = ecModel.getComponent('parallelAxis', axisIndex);
          var axisDim = coordSysDims[index];
          axisMap.set(axisDim, axisModel);

          if (isCategory(axisModel)) {
            categoryAxisMap.set(axisDim, axisModel);

            if (result.firstCategoryDimIndex == null) {
              result.firstCategoryDimIndex = index;
            }
          }
        });
      }
    };

    function isCategory(axisModel) {
      return axisModel.get('type') === 'category';
    }

    /**
     * Note that it is too complicated to support 3d stack by value
     * (have to create two-dimension inverted index), so in 3d case
     * we just support that stacked by index.
     *
     * @param seriesModel
     * @param dimensionsInput The same as the input of <module:echarts/data/SeriesData>.
     *        The input will be modified.
     * @param opt
     * @param opt.stackedCoordDimension Specify a coord dimension if needed.
     * @param opt.byIndex=false
     * @return calculationInfo
     * {
     *     stackedDimension: string
     *     stackedByDimension: string
     *     isStackedByIndex: boolean
     *     stackedOverDimension: string
     *     stackResultDimension: string
     * }
     */

    function enableDataStack(seriesModel, dimensionsInput, opt) {
      opt = opt || {};
      var byIndex = opt.byIndex;
      var stackedCoordDimension = opt.stackedCoordDimension;
      var dimensionDefineList;
      var schema;
      var store;

      if (isLegacyDimensionsInput(dimensionsInput)) {
        dimensionDefineList = dimensionsInput;
      } else {
        schema = dimensionsInput.schema;
        dimensionDefineList = schema.dimensions;
        store = dimensionsInput.store;
      } // Compatibal: when `stack` is set as '', do not stack.


      var mayStack = !!(seriesModel && seriesModel.get('stack'));
      var stackedByDimInfo;
      var stackedDimInfo;
      var stackResultDimension;
      var stackedOverDimension;
      each(dimensionDefineList, function (dimensionInfo, index) {
        if (isString(dimensionInfo)) {
          dimensionDefineList[index] = dimensionInfo = {
            name: dimensionInfo
          };
        }

        if (mayStack && !dimensionInfo.isExtraCoord) {
          // Find the first ordinal dimension as the stackedByDimInfo.
          if (!byIndex && !stackedByDimInfo && dimensionInfo.ordinalMeta) {
            stackedByDimInfo = dimensionInfo;
          } // Find the first stackable dimension as the stackedDimInfo.


          if (!stackedDimInfo && dimensionInfo.type !== 'ordinal' && dimensionInfo.type !== 'time' && (!stackedCoordDimension || stackedCoordDimension === dimensionInfo.coordDim)) {
            stackedDimInfo = dimensionInfo;
          }
        }
      });

      if (stackedDimInfo && !byIndex && !stackedByDimInfo) {
        // Compatible with previous design, value axis (time axis) only stack by index.
        // It may make sense if the user provides elaborately constructed data.
        byIndex = true;
      } // Add stack dimension, they can be both calculated by coordinate system in `unionExtent`.
      // That put stack logic in List is for using conveniently in echarts extensions, but it
      // might not be a good way.


      if (stackedDimInfo) {
        // Use a weird name that not duplicated with other names.
        // Also need to use seriesModel.id as postfix because different
        // series may share same data store. The stack dimension needs to be distinguished.
        stackResultDimension = '__\0ecstackresult_' + seriesModel.id;
        stackedOverDimension = '__\0ecstackedover_' + seriesModel.id; // Create inverted index to fast query index by value.

        if (stackedByDimInfo) {
          stackedByDimInfo.createInvertedIndices = true;
        }

        var stackedDimCoordDim_1 = stackedDimInfo.coordDim;
        var stackedDimType = stackedDimInfo.type;
        var stackedDimCoordIndex_1 = 0;
        each(dimensionDefineList, function (dimensionInfo) {
          if (dimensionInfo.coordDim === stackedDimCoordDim_1) {
            stackedDimCoordIndex_1++;
          }
        });
        var stackedOverDimensionDefine = {
          name: stackResultDimension,
          coordDim: stackedDimCoordDim_1,
          coordDimIndex: stackedDimCoordIndex_1,
          type: stackedDimType,
          isExtraCoord: true,
          isCalculationCoord: true,
          storeDimIndex: dimensionDefineList.length
        };
        var stackResultDimensionDefine = {
          name: stackedOverDimension,
          // This dimension contains stack base (generally, 0), so do not set it as
          // `stackedDimCoordDim` to avoid extent calculation, consider log scale.
          coordDim: stackedOverDimension,
          coordDimIndex: stackedDimCoordIndex_1 + 1,
          type: stackedDimType,
          isExtraCoord: true,
          isCalculationCoord: true,
          storeDimIndex: dimensionDefineList.length + 1
        };

        if (schema) {
          if (store) {
            stackedOverDimensionDefine.storeDimIndex = store.ensureCalculationDimension(stackedOverDimension, stackedDimType);
            stackResultDimensionDefine.storeDimIndex = store.ensureCalculationDimension(stackResultDimension, stackedDimType);
          }

          schema.appendCalculationDimension(stackedOverDimensionDefine);
          schema.appendCalculationDimension(stackResultDimensionDefine);
        } else {
          dimensionDefineList.push(stackedOverDimensionDefine);
          dimensionDefineList.push(stackResultDimensionDefine);
        }
      }

      return {
        stackedDimension: stackedDimInfo && stackedDimInfo.name,
        stackedByDimension: stackedByDimInfo && stackedByDimInfo.name,
        isStackedByIndex: byIndex,
        stackedOverDimension: stackedOverDimension,
        stackResultDimension: stackResultDimension
      };
    }

    function isLegacyDimensionsInput(dimensionsInput) {
      return !isSeriesDataSchema(dimensionsInput.schema);
    }

    function isDimensionStacked(data, stackedDim) {
      // Each single series only maps to one pair of axis. So we do not need to
      // check stackByDim, whatever stacked by a dimension or stacked by index.
      return !!stackedDim && stackedDim === data.getCalculationInfo('stackedDimension');
    }
    function getStackedDimension(data, targetDim) {
      return isDimensionStacked(data, targetDim) ? data.getCalculationInfo('stackResultDimension') : targetDim;
    }

    function getCoordSysDimDefs(seriesModel, coordSysInfo) {
      var coordSysName = seriesModel.get('coordinateSystem');
      var registeredCoordSys = CoordinateSystemManager.get(coordSysName);
      var coordSysDimDefs;

      if (coordSysInfo && coordSysInfo.coordSysDims) {
        coordSysDimDefs = map(coordSysInfo.coordSysDims, function (dim) {
          var dimInfo = {
            name: dim
          };
          var axisModel = coordSysInfo.axisMap.get(dim);

          if (axisModel) {
            var axisType = axisModel.get('type');
            dimInfo.type = getDimensionTypeByAxis(axisType);
          }

          return dimInfo;
        });
      }

      if (!coordSysDimDefs) {
        // Get dimensions from registered coordinate system
        coordSysDimDefs = registeredCoordSys && (registeredCoordSys.getDimensionsInfo ? registeredCoordSys.getDimensionsInfo() : registeredCoordSys.dimensions.slice()) || ['x', 'y'];
      }

      return coordSysDimDefs;
    }

    function injectOrdinalMeta(dimInfoList, createInvertedIndices, coordSysInfo) {
      var firstCategoryDimIndex;
      var hasNameEncode;
      coordSysInfo && each(dimInfoList, function (dimInfo, dimIndex) {
        var coordDim = dimInfo.coordDim;
        var categoryAxisModel = coordSysInfo.categoryAxisMap.get(coordDim);

        if (categoryAxisModel) {
          if (firstCategoryDimIndex == null) {
            firstCategoryDimIndex = dimIndex;
          }

          dimInfo.ordinalMeta = categoryAxisModel.getOrdinalMeta();

          if (createInvertedIndices) {
            dimInfo.createInvertedIndices = true;
          }
        }

        if (dimInfo.otherDims.itemName != null) {
          hasNameEncode = true;
        }
      });

      if (!hasNameEncode && firstCategoryDimIndex != null) {
        dimInfoList[firstCategoryDimIndex].otherDims.itemName = 0;
      }

      return firstCategoryDimIndex;
    }
    /**
     * Caution: there are side effects to `sourceManager` in this method.
     * Should better only be called in `Series['getInitialData']`.
     */


    function createSeriesData(sourceRaw, seriesModel, opt) {
      opt = opt || {};
      var sourceManager = seriesModel.getSourceManager();
      var source;
      var isOriginalSource = false;

      if (sourceRaw) {
        isOriginalSource = true;
        source = createSourceFromSeriesDataOption(sourceRaw);
      } else {
        source = sourceManager.getSource(); // Is series.data. not dataset.

        isOriginalSource = source.sourceFormat === SOURCE_FORMAT_ORIGINAL;
      }

      var coordSysInfo = getCoordSysInfoBySeries(seriesModel);
      var coordSysDimDefs = getCoordSysDimDefs(seriesModel, coordSysInfo);
      var useEncodeDefaulter = opt.useEncodeDefaulter;
      var encodeDefaulter = isFunction(useEncodeDefaulter) ? useEncodeDefaulter : useEncodeDefaulter ? curry(makeSeriesEncodeForAxisCoordSys, coordSysDimDefs, seriesModel) : null;
      var createDimensionOptions = {
        coordDimensions: coordSysDimDefs,
        generateCoord: opt.generateCoord,
        encodeDefine: seriesModel.getEncode(),
        encodeDefaulter: encodeDefaulter,
        canOmitUnusedDimensions: !isOriginalSource
      };
      var schema = prepareSeriesDataSchema(source, createDimensionOptions);
      var firstCategoryDimIndex = injectOrdinalMeta(schema.dimensions, opt.createInvertedIndices, coordSysInfo);
      var store = !isOriginalSource ? sourceManager.getSharedDataStore(schema) : null;
      var stackCalculationInfo = enableDataStack(seriesModel, {
        schema: schema,
        store: store
      });
      var data = new SeriesData(schema, seriesModel);
      data.setCalculationInfo(stackCalculationInfo);
      var dimValueGetter = firstCategoryDimIndex != null && isNeedCompleteOrdinalData(source) ? function (itemOpt, dimName, dataIndex, dimIndex) {
        // Use dataIndex as ordinal value in categoryAxis
        return dimIndex === firstCategoryDimIndex ? dataIndex : this.defaultDimValueGetter(itemOpt, dimName, dataIndex, dimIndex);
      } : null;
      data.hasItemOption = false;
      data.initData( // Try to reuse the data store in sourceManager if using dataset.
      isOriginalSource ? source : store, null, dimValueGetter);
      return data;
    }

    function isNeedCompleteOrdinalData(source) {
      if (source.sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        var sampleItem = firstDataNotNull(source.data || []);
        return !isArray(getDataItemValue(sampleItem));
      }
    }

    function firstDataNotNull(arr) {
      var i = 0;

      while (i < arr.length && arr[i] == null) {
        i++;
      }

      return arr[i];
    }

    var Scale =
    /** @class */
    function () {
      function Scale(setting) {
        this._setting = setting || {};
        this._extent = [Infinity, -Infinity];
      }

      Scale.prototype.getSetting = function (name) {
        return this._setting[name];
      };
      /**
       * Set extent from data
       */


      Scale.prototype.unionExtent = function (other) {
        var extent = this._extent;
        other[0] < extent[0] && (extent[0] = other[0]);
        other[1] > extent[1] && (extent[1] = other[1]); // not setExtent because in log axis it may transformed to power
        // this.setExtent(extent[0], extent[1]);
      };
      /**
       * Set extent from data
       */


      Scale.prototype.unionExtentFromData = function (data, dim) {
        this.unionExtent(data.getApproximateExtent(dim));
      };
      /**
       * Get extent
       *
       * Extent is always in increase order.
       */


      Scale.prototype.getExtent = function () {
        return this._extent.slice();
      };
      /**
       * Set extent
       */


      Scale.prototype.setExtent = function (start, end) {
        var thisExtent = this._extent;

        if (!isNaN(start)) {
          thisExtent[0] = start;
        }

        if (!isNaN(end)) {
          thisExtent[1] = end;
        }
      };
      /**
       * If value is in extent range
       */


      Scale.prototype.isInExtentRange = function (value) {
        return this._extent[0] <= value && this._extent[1] >= value;
      };
      /**
       * When axis extent depends on data and no data exists,
       * axis ticks should not be drawn, which is named 'blank'.
       */


      Scale.prototype.isBlank = function () {
        return this._isBlank;
      };
      /**
       * When axis extent depends on data and no data exists,
       * axis ticks should not be drawn, which is named 'blank'.
       */


      Scale.prototype.setBlank = function (isBlank) {
        this._isBlank = isBlank;
      };

      return Scale;
    }();

    enableClassManagement(Scale);

    var uidBase = 0;

    var OrdinalMeta =
    /** @class */
    function () {
      function OrdinalMeta(opt) {
        this.categories = opt.categories || [];
        this._needCollect = opt.needCollect;
        this._deduplication = opt.deduplication;
        this.uid = ++uidBase;
      }

      OrdinalMeta.createByAxisModel = function (axisModel) {
        var option = axisModel.option;
        var data = option.data;
        var categories = data && map(data, getName);
        return new OrdinalMeta({
          categories: categories,
          needCollect: !categories,
          // deduplication is default in axis.
          deduplication: option.dedplication !== false
        });
      };

      OrdinalMeta.prototype.getOrdinal = function (category) {
        // @ts-ignore
        return this._getOrCreateMap().get(category);
      };
      /**
       * @return The ordinal. If not found, return NaN.
       */


      OrdinalMeta.prototype.parseAndCollect = function (category) {
        var index;
        var needCollect = this._needCollect; // The value of category dim can be the index of the given category set.
        // This feature is only supported when !needCollect, because we should
        // consider a common case: a value is 2017, which is a number but is
        // expected to be tread as a category. This case usually happen in dataset,
        // where it happent to be no need of the index feature.

        if (!isString(category) && !needCollect) {
          return category;
        } // Optimize for the scenario:
        // category is ['2012-01-01', '2012-01-02', ...], where the input
        // data has been ensured not duplicate and is large data.
        // Notice, if a dataset dimension provide categroies, usually echarts
        // should remove duplication except user tell echarts dont do that
        // (set axis.deduplication = false), because echarts do not know whether
        // the values in the category dimension has duplication (consider the
        // parallel-aqi example)


        if (needCollect && !this._deduplication) {
          index = this.categories.length;
          this.categories[index] = category;
          return index;
        }

        var map = this._getOrCreateMap(); // @ts-ignore


        index = map.get(category);

        if (index == null) {
          if (needCollect) {
            index = this.categories.length;
            this.categories[index] = category; // @ts-ignore

            map.set(category, index);
          } else {
            index = NaN;
          }
        }

        return index;
      }; // Consider big data, do not create map until needed.


      OrdinalMeta.prototype._getOrCreateMap = function () {
        return this._map || (this._map = createHashMap(this.categories));
      };

      return OrdinalMeta;
    }();

    function getName(obj) {
      if (isObject(obj) && obj.value != null) {
        return obj.value;
      } else {
        return obj + '';
      }
    }

    function isValueNice(val) {
      var exp10 = Math.pow(10, quantityExponent(Math.abs(val)));
      var f = Math.abs(val / exp10);
      return f === 0 || f === 1 || f === 2 || f === 3 || f === 5;
    }
    function isIntervalOrLogScale(scale) {
      return scale.type === 'interval' || scale.type === 'log';
    }
    /**
     * @param extent Both extent[0] and extent[1] should be valid number.
     *               Should be extent[0] < extent[1].
     * @param splitNumber splitNumber should be >= 1.
     */

    function intervalScaleNiceTicks(extent, splitNumber, minInterval, maxInterval) {
      var result = {};
      var span = extent[1] - extent[0];
      var interval = result.interval = nice(span / splitNumber, true);

      if (minInterval != null && interval < minInterval) {
        interval = result.interval = minInterval;
      }

      if (maxInterval != null && interval > maxInterval) {
        interval = result.interval = maxInterval;
      } // Tow more digital for tick.


      var precision = result.intervalPrecision = getIntervalPrecision(interval); // Niced extent inside original extent

      var niceTickExtent = result.niceTickExtent = [round(Math.ceil(extent[0] / interval) * interval, precision), round(Math.floor(extent[1] / interval) * interval, precision)];
      fixExtent(niceTickExtent, extent);
      return result;
    }
    function increaseInterval(interval) {
      var exp10 = Math.pow(10, quantityExponent(interval)); // Increase interval

      var f = interval / exp10;

      if (!f) {
        f = 1;
      } else if (f === 2) {
        f = 3;
      } else if (f === 3) {
        f = 5;
      } else {
        // f is 1 or 5
        f *= 2;
      }

      return round(f * exp10);
    }
    /**
     * @return interval precision
     */

    function getIntervalPrecision(interval) {
      // Tow more digital for tick.
      return getPrecision(interval) + 2;
    }

    function clamp(niceTickExtent, idx, extent) {
      niceTickExtent[idx] = Math.max(Math.min(niceTickExtent[idx], extent[1]), extent[0]);
    } // In some cases (e.g., splitNumber is 1), niceTickExtent may be out of extent.


    function fixExtent(niceTickExtent, extent) {
      !isFinite(niceTickExtent[0]) && (niceTickExtent[0] = extent[0]);
      !isFinite(niceTickExtent[1]) && (niceTickExtent[1] = extent[1]);
      clamp(niceTickExtent, 0, extent);
      clamp(niceTickExtent, 1, extent);

      if (niceTickExtent[0] > niceTickExtent[1]) {
        niceTickExtent[0] = niceTickExtent[1];
      }
    }
    function contain$1(val, extent) {
      return val >= extent[0] && val <= extent[1];
    }
    function normalize$1(val, extent) {
      if (extent[1] === extent[0]) {
        return 0.5;
      }

      return (val - extent[0]) / (extent[1] - extent[0]);
    }
    function scale$2(val, extent) {
      return val * (extent[1] - extent[0]) + extent[0];
    }

    var OrdinalScale =
    /** @class */
    function (_super) {
      __extends(OrdinalScale, _super);

      function OrdinalScale(setting) {
        var _this = _super.call(this, setting) || this;

        _this.type = 'ordinal';

        var ordinalMeta = _this.getSetting('ordinalMeta'); // Caution: Should not use instanceof, consider ec-extensions using
        // import approach to get OrdinalMeta class.


        if (!ordinalMeta) {
          ordinalMeta = new OrdinalMeta({});
        }

        if (isArray(ordinalMeta)) {
          ordinalMeta = new OrdinalMeta({
            categories: map(ordinalMeta, function (item) {
              return isObject(item) ? item.value : item;
            })
          });
        }

        _this._ordinalMeta = ordinalMeta;
        _this._extent = _this.getSetting('extent') || [0, ordinalMeta.categories.length - 1];
        return _this;
      }

      OrdinalScale.prototype.parse = function (val) {
        // Caution: Math.round(null) will return `0` rather than `NaN`
        if (val == null) {
          return NaN;
        }

        return isString(val) ? this._ordinalMeta.getOrdinal(val) // val might be float.
        : Math.round(val);
      };

      OrdinalScale.prototype.contain = function (rank) {
        rank = this.parse(rank);
        return contain$1(rank, this._extent) && this._ordinalMeta.categories[rank] != null;
      };
      /**
       * Normalize given rank or name to linear [0, 1]
       * @param val raw ordinal number.
       * @return normalized value in [0, 1].
       */


      OrdinalScale.prototype.normalize = function (val) {
        val = this._getTickNumber(this.parse(val));
        return normalize$1(val, this._extent);
      };
      /**
       * @param val normalized value in [0, 1].
       * @return raw ordinal number.
       */


      OrdinalScale.prototype.scale = function (val) {
        val = Math.round(scale$2(val, this._extent));
        return this.getRawOrdinalNumber(val);
      };

      OrdinalScale.prototype.getTicks = function () {
        var ticks = [];
        var extent = this._extent;
        var rank = extent[0];

        while (rank <= extent[1]) {
          ticks.push({
            value: rank
          });
          rank++;
        }

        return ticks;
      };

      OrdinalScale.prototype.getMinorTicks = function (splitNumber) {
        // Not support.
        return;
      };
      /**
       * @see `Ordinal['_ordinalNumbersByTick']`
       */


      OrdinalScale.prototype.setSortInfo = function (info) {
        if (info == null) {
          this._ordinalNumbersByTick = this._ticksByOrdinalNumber = null;
          return;
        }

        var infoOrdinalNumbers = info.ordinalNumbers;
        var ordinalsByTick = this._ordinalNumbersByTick = [];
        var ticksByOrdinal = this._ticksByOrdinalNumber = []; // Unnecessary support negative tick in `realtimeSort`.

        var tickNum = 0;
        var allCategoryLen = this._ordinalMeta.categories.length;

        for (var len = Math.min(allCategoryLen, infoOrdinalNumbers.length); tickNum < len; ++tickNum) {
          var ordinalNumber = infoOrdinalNumbers[tickNum];
          ordinalsByTick[tickNum] = ordinalNumber;
          ticksByOrdinal[ordinalNumber] = tickNum;
        } // Handle that `series.data` only covers part of the `axis.category.data`.


        var unusedOrdinal = 0;

        for (; tickNum < allCategoryLen; ++tickNum) {
          while (ticksByOrdinal[unusedOrdinal] != null) {
            unusedOrdinal++;
          }
          ordinalsByTick.push(unusedOrdinal);
          ticksByOrdinal[unusedOrdinal] = tickNum;
        }
      };

      OrdinalScale.prototype._getTickNumber = function (ordinal) {
        var ticksByOrdinalNumber = this._ticksByOrdinalNumber; // also support ordinal out of range of `ordinalMeta.categories.length`,
        // where ordinal numbers are used as tick value directly.

        return ticksByOrdinalNumber && ordinal >= 0 && ordinal < ticksByOrdinalNumber.length ? ticksByOrdinalNumber[ordinal] : ordinal;
      };
      /**
       * @usage
       * ```js
       * const ordinalNumber = ordinalScale.getRawOrdinalNumber(tickVal);
       *
       * // case0
       * const rawOrdinalValue = axisModel.getCategories()[ordinalNumber];
       * // case1
       * const rawOrdinalValue = this._ordinalMeta.categories[ordinalNumber];
       * // case2
       * const coord = axis.dataToCoord(ordinalNumber);
       * ```
       *
       * @param {OrdinalNumber} tickNumber index of display
       */


      OrdinalScale.prototype.getRawOrdinalNumber = function (tickNumber) {
        var ordinalNumbersByTick = this._ordinalNumbersByTick; // tickNumber may be out of range, e.g., when axis max is larger than `ordinalMeta.categories.length`.,
        // where ordinal numbers are used as tick value directly.

        return ordinalNumbersByTick && tickNumber >= 0 && tickNumber < ordinalNumbersByTick.length ? ordinalNumbersByTick[tickNumber] : tickNumber;
      };
      /**
       * Get item on tick
       */


      OrdinalScale.prototype.getLabel = function (tick) {
        if (!this.isBlank()) {
          var ordinalNumber = this.getRawOrdinalNumber(tick.value);
          var cateogry = this._ordinalMeta.categories[ordinalNumber]; // Note that if no data, ordinalMeta.categories is an empty array.
          // Return empty if it's not exist.

          return cateogry == null ? '' : cateogry + '';
        }
      };

      OrdinalScale.prototype.count = function () {
        return this._extent[1] - this._extent[0] + 1;
      };

      OrdinalScale.prototype.unionExtentFromData = function (data, dim) {
        this.unionExtent(data.getApproximateExtent(dim));
      };
      /**
       * @override
       * If value is in extent range
       */


      OrdinalScale.prototype.isInExtentRange = function (value) {
        value = this._getTickNumber(value);
        return this._extent[0] <= value && this._extent[1] >= value;
      };

      OrdinalScale.prototype.getOrdinalMeta = function () {
        return this._ordinalMeta;
      };

      OrdinalScale.prototype.calcNiceTicks = function () {};

      OrdinalScale.prototype.calcNiceExtent = function () {};

      OrdinalScale.type = 'ordinal';
      return OrdinalScale;
    }(Scale);

    Scale.registerClass(OrdinalScale);

    var roundNumber = round;

    var IntervalScale =
    /** @class */
    function (_super) {
      __extends(IntervalScale, _super);

      function IntervalScale() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'interval'; // Step is calculated in adjustExtent.

        _this._interval = 0;
        _this._intervalPrecision = 2;
        return _this;
      }

      IntervalScale.prototype.parse = function (val) {
        return val;
      };

      IntervalScale.prototype.contain = function (val) {
        return contain$1(val, this._extent);
      };

      IntervalScale.prototype.normalize = function (val) {
        return normalize$1(val, this._extent);
      };

      IntervalScale.prototype.scale = function (val) {
        return scale$2(val, this._extent);
      };

      IntervalScale.prototype.setExtent = function (start, end) {
        var thisExtent = this._extent; // start,end may be a Number like '25',so...

        if (!isNaN(start)) {
          thisExtent[0] = parseFloat(start);
        }

        if (!isNaN(end)) {
          thisExtent[1] = parseFloat(end);
        }
      };

      IntervalScale.prototype.unionExtent = function (other) {
        var extent = this._extent;
        other[0] < extent[0] && (extent[0] = other[0]);
        other[1] > extent[1] && (extent[1] = other[1]); // unionExtent may called by it's sub classes

        this.setExtent(extent[0], extent[1]);
      };

      IntervalScale.prototype.getInterval = function () {
        return this._interval;
      };

      IntervalScale.prototype.setInterval = function (interval) {
        this._interval = interval; // Dropped auto calculated niceExtent and use user-set extent.
        // We assume user wants to set both interval, min, max to get a better result.

        this._niceExtent = this._extent.slice();
        this._intervalPrecision = getIntervalPrecision(interval);
      };
      /**
       * @param expandToNicedExtent Whether expand the ticks to niced extent.
       */


      IntervalScale.prototype.getTicks = function (expandToNicedExtent) {
        var interval = this._interval;
        var extent = this._extent;
        var niceTickExtent = this._niceExtent;
        var intervalPrecision = this._intervalPrecision;
        var ticks = []; // If interval is 0, return [];

        if (!interval) {
          return ticks;
        } // Consider this case: using dataZoom toolbox, zoom and zoom.


        var safeLimit = 10000;

        if (extent[0] < niceTickExtent[0]) {
          if (expandToNicedExtent) {
            ticks.push({
              value: roundNumber(niceTickExtent[0] - interval, intervalPrecision)
            });
          } else {
            ticks.push({
              value: extent[0]
            });
          }
        }

        var tick = niceTickExtent[0];

        while (tick <= niceTickExtent[1]) {
          ticks.push({
            value: tick
          }); // Avoid rounding error

          tick = roundNumber(tick + interval, intervalPrecision);

          if (tick === ticks[ticks.length - 1].value) {
            // Consider out of safe float point, e.g.,
            // -3711126.9907707 + 2e-10 === -3711126.9907707
            break;
          }

          if (ticks.length > safeLimit) {
            return [];
          }
        } // Consider this case: the last item of ticks is smaller
        // than niceTickExtent[1] and niceTickExtent[1] === extent[1].


        var lastNiceTick = ticks.length ? ticks[ticks.length - 1].value : niceTickExtent[1];

        if (extent[1] > lastNiceTick) {
          if (expandToNicedExtent) {
            ticks.push({
              value: roundNumber(lastNiceTick + interval, intervalPrecision)
            });
          } else {
            ticks.push({
              value: extent[1]
            });
          }
        }

        return ticks;
      };

      IntervalScale.prototype.getMinorTicks = function (splitNumber) {
        var ticks = this.getTicks(true);
        var minorTicks = [];
        var extent = this.getExtent();

        for (var i = 1; i < ticks.length; i++) {
          var nextTick = ticks[i];
          var prevTick = ticks[i - 1];
          var count = 0;
          var minorTicksGroup = [];
          var interval = nextTick.value - prevTick.value;
          var minorInterval = interval / splitNumber;

          while (count < splitNumber - 1) {
            var minorTick = roundNumber(prevTick.value + (count + 1) * minorInterval); // For the first and last interval. The count may be less than splitNumber.

            if (minorTick > extent[0] && minorTick < extent[1]) {
              minorTicksGroup.push(minorTick);
            }

            count++;
          }

          minorTicks.push(minorTicksGroup);
        }

        return minorTicks;
      };
      /**
       * @param opt.precision If 'auto', use nice presision.
       * @param opt.pad returns 1.50 but not 1.5 if precision is 2.
       */


      IntervalScale.prototype.getLabel = function (data, opt) {
        if (data == null) {
          return '';
        }

        var precision = opt && opt.precision;

        if (precision == null) {
          precision = getPrecision(data.value) || 0;
        } else if (precision === 'auto') {
          // Should be more precise then tick.
          precision = this._intervalPrecision;
        } // (1) If `precision` is set, 12.005 should be display as '12.00500'.
        // (2) Use roundNumber (toFixed) to avoid scientific notation like '3.5e-7'.


        var dataNum = roundNumber(data.value, precision, true);
        return addCommas(dataNum);
      };
      /**
       * @param splitNumber By default `5`.
       */


      IntervalScale.prototype.calcNiceTicks = function (splitNumber, minInterval, maxInterval) {
        splitNumber = splitNumber || 5;
        var extent = this._extent;
        var span = extent[1] - extent[0];

        if (!isFinite(span)) {
          return;
        } // User may set axis min 0 and data are all negative
        // FIXME If it needs to reverse ?


        if (span < 0) {
          span = -span;
          extent.reverse();
        }

        var result = intervalScaleNiceTicks(extent, splitNumber, minInterval, maxInterval);
        this._intervalPrecision = result.intervalPrecision;
        this._interval = result.interval;
        this._niceExtent = result.niceTickExtent;
      };

      IntervalScale.prototype.calcNiceExtent = function (opt) {
        var extent = this._extent; // If extent start and end are same, expand them

        if (extent[0] === extent[1]) {
          if (extent[0] !== 0) {
            // Expand extent
            // Note that extents can be both negative. See #13154
            var expandSize = Math.abs(extent[0]); // In the fowllowing case
            //      Axis has been fixed max 100
            //      Plus data are all 100 and axis extent are [100, 100].
            // Extend to the both side will cause expanded max is larger than fixed max.
            // So only expand to the smaller side.

            if (!opt.fixMax) {
              extent[1] += expandSize / 2;
              extent[0] -= expandSize / 2;
            } else {
              extent[0] -= expandSize / 2;
            }
          } else {
            extent[1] = 1;
          }
        }

        var span = extent[1] - extent[0]; // If there are no data and extent are [Infinity, -Infinity]

        if (!isFinite(span)) {
          extent[0] = 0;
          extent[1] = 1;
        }

        this.calcNiceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval); // let extent = this._extent;

        var interval = this._interval;

        if (!opt.fixMin) {
          extent[0] = roundNumber(Math.floor(extent[0] / interval) * interval);
        }

        if (!opt.fixMax) {
          extent[1] = roundNumber(Math.ceil(extent[1] / interval) * interval);
        }
      };

      IntervalScale.prototype.setNiceExtent = function (min, max) {
        this._niceExtent = [min, max];
      };

      IntervalScale.type = 'interval';
      return IntervalScale;
    }(Scale);

    Scale.registerClass(IntervalScale);

    /* global Float32Array */

    var supportFloat32Array = typeof Float32Array !== 'undefined';
    var Float32ArrayCtor = !supportFloat32Array ? Array : Float32Array;
    function createFloat32Array(arg) {
      if (isArray(arg)) {
        // Return self directly if don't support TypedArray.
        return supportFloat32Array ? new Float32Array(arg) : arg;
      } // Else is number


      return new Float32ArrayCtor(arg);
    }

    var STACK_PREFIX = '__ec_stack_';

    function getSeriesStackId(seriesModel) {
      return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex;
    }

    function getAxisKey(axis) {
      return axis.dim + axis.index;
    }
    function prepareLayoutBarSeries(seriesType, ecModel) {
      var seriesModels = [];
      ecModel.eachSeriesByType(seriesType, function (seriesModel) {
        // Check series coordinate, do layout for cartesian2d only
        if (isOnCartesian(seriesModel)) {
          seriesModels.push(seriesModel);
        }
      });
      return seriesModels;
    }
    /**
     * Map from (baseAxis.dim + '_' + baseAxis.index) to min gap of two adjacent
     * values.
     * This works for time axes, value axes, and log axes.
     * For a single time axis, return value is in the form like
     * {'x_0': [1000000]}.
     * The value of 1000000 is in milliseconds.
     */

    function getValueAxesMinGaps(barSeries) {
      /**
       * Map from axis.index to values.
       * For a single time axis, axisValues is in the form like
       * {'x_0': [1495555200000, 1495641600000, 1495728000000]}.
       * Items in axisValues[x], e.g. 1495555200000, are time values of all
       * series.
       */
      var axisValues = {};
      each(barSeries, function (seriesModel) {
        var cartesian = seriesModel.coordinateSystem;
        var baseAxis = cartesian.getBaseAxis();

        if (baseAxis.type !== 'time' && baseAxis.type !== 'value') {
          return;
        }

        var data = seriesModel.getData();
        var key = baseAxis.dim + '_' + baseAxis.index;
        var dimIdx = data.getDimensionIndex(data.mapDimension(baseAxis.dim));
        var store = data.getStore();

        for (var i = 0, cnt = store.count(); i < cnt; ++i) {
          var value = store.get(dimIdx, i);

          if (!axisValues[key]) {
            // No previous data for the axis
            axisValues[key] = [value];
          } else {
            // No value in previous series
            axisValues[key].push(value);
          } // Ignore duplicated time values in the same axis

        }
      });
      var axisMinGaps = {};

      for (var key in axisValues) {
        if (axisValues.hasOwnProperty(key)) {
          var valuesInAxis = axisValues[key];

          if (valuesInAxis) {
            // Sort axis values into ascending order to calculate gaps
            valuesInAxis.sort(function (a, b) {
              return a - b;
            });
            var min = null;

            for (var j = 1; j < valuesInAxis.length; ++j) {
              var delta = valuesInAxis[j] - valuesInAxis[j - 1];

              if (delta > 0) {
                // Ignore 0 delta because they are of the same axis value
                min = min === null ? delta : Math.min(min, delta);
              }
            } // Set to null if only have one data


            axisMinGaps[key] = min;
          }
        }
      }

      return axisMinGaps;
    }

    function makeColumnLayout(barSeries) {
      var axisMinGaps = getValueAxesMinGaps(barSeries);
      var seriesInfoList = [];
      each(barSeries, function (seriesModel) {
        var cartesian = seriesModel.coordinateSystem;
        var baseAxis = cartesian.getBaseAxis();
        var axisExtent = baseAxis.getExtent();
        var bandWidth;

        if (baseAxis.type === 'category') {
          bandWidth = baseAxis.getBandWidth();
        } else if (baseAxis.type === 'value' || baseAxis.type === 'time') {
          var key = baseAxis.dim + '_' + baseAxis.index;
          var minGap = axisMinGaps[key];
          var extentSpan = Math.abs(axisExtent[1] - axisExtent[0]);
          var scale = baseAxis.scale.getExtent();
          var scaleSpan = Math.abs(scale[1] - scale[0]);
          bandWidth = minGap ? extentSpan / scaleSpan * minGap : extentSpan; // When there is only one data value
        } else {
          var data = seriesModel.getData();
          bandWidth = Math.abs(axisExtent[1] - axisExtent[0]) / data.count();
        }

        var barWidth = parsePercent$1(seriesModel.get('barWidth'), bandWidth);
        var barMaxWidth = parsePercent$1(seriesModel.get('barMaxWidth'), bandWidth);
        var barMinWidth = parsePercent$1( // barMinWidth by default is 0.5 / 1 in cartesian. Because in value axis,
        // the auto-calculated bar width might be less than 0.5 / 1.
        seriesModel.get('barMinWidth') || (isInLargeMode(seriesModel) ? 0.5 : 1), bandWidth);
        var barGap = seriesModel.get('barGap');
        var barCategoryGap = seriesModel.get('barCategoryGap');
        seriesInfoList.push({
          bandWidth: bandWidth,
          barWidth: barWidth,
          barMaxWidth: barMaxWidth,
          barMinWidth: barMinWidth,
          barGap: barGap,
          barCategoryGap: barCategoryGap,
          axisKey: getAxisKey(baseAxis),
          stackId: getSeriesStackId(seriesModel)
        });
      });
      return doCalBarWidthAndOffset(seriesInfoList);
    }

    function doCalBarWidthAndOffset(seriesInfoList) {
      // Columns info on each category axis. Key is cartesian name
      var columnsMap = {};
      each(seriesInfoList, function (seriesInfo, idx) {
        var axisKey = seriesInfo.axisKey;
        var bandWidth = seriesInfo.bandWidth;
        var columnsOnAxis = columnsMap[axisKey] || {
          bandWidth: bandWidth,
          remainedWidth: bandWidth,
          autoWidthCount: 0,
          categoryGap: null,
          gap: '20%',
          stacks: {}
        };
        var stacks = columnsOnAxis.stacks;
        columnsMap[axisKey] = columnsOnAxis;
        var stackId = seriesInfo.stackId;

        if (!stacks[stackId]) {
          columnsOnAxis.autoWidthCount++;
        }

        stacks[stackId] = stacks[stackId] || {
          width: 0,
          maxWidth: 0
        }; // Caution: In a single coordinate system, these barGrid attributes
        // will be shared by series. Consider that they have default values,
        // only the attributes set on the last series will work.
        // Do not change this fact unless there will be a break change.

        var barWidth = seriesInfo.barWidth;

        if (barWidth && !stacks[stackId].width) {
          // See #6312, do not restrict width.
          stacks[stackId].width = barWidth;
          barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth);
          columnsOnAxis.remainedWidth -= barWidth;
        }

        var barMaxWidth = seriesInfo.barMaxWidth;
        barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth);
        var barMinWidth = seriesInfo.barMinWidth;
        barMinWidth && (stacks[stackId].minWidth = barMinWidth);
        var barGap = seriesInfo.barGap;
        barGap != null && (columnsOnAxis.gap = barGap);
        var barCategoryGap = seriesInfo.barCategoryGap;
        barCategoryGap != null && (columnsOnAxis.categoryGap = barCategoryGap);
      });
      var result = {};
      each(columnsMap, function (columnsOnAxis, coordSysName) {
        result[coordSysName] = {};
        var stacks = columnsOnAxis.stacks;
        var bandWidth = columnsOnAxis.bandWidth;
        var categoryGapPercent = columnsOnAxis.categoryGap;

        if (categoryGapPercent == null) {
          var columnCount = keys(stacks).length; // More columns in one group
          // the spaces between group is smaller. Or the column will be too thin.

          categoryGapPercent = Math.max(35 - columnCount * 4, 15) + '%';
        }

        var categoryGap = parsePercent$1(categoryGapPercent, bandWidth);
        var barGapPercent = parsePercent$1(columnsOnAxis.gap, 1);
        var remainedWidth = columnsOnAxis.remainedWidth;
        var autoWidthCount = columnsOnAxis.autoWidthCount;
        var autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
        autoWidth = Math.max(autoWidth, 0); // Find if any auto calculated bar exceeded maxBarWidth

        each(stacks, function (column) {
          var maxWidth = column.maxWidth;
          var minWidth = column.minWidth;

          if (!column.width) {
            var finalWidth = autoWidth;

            if (maxWidth && maxWidth < finalWidth) {
              finalWidth = Math.min(maxWidth, remainedWidth);
            } // `minWidth` has higher priority. `minWidth` decide that whether the
            // bar is able to be visible. So `minWidth` should not be restricted
            // by `maxWidth` or `remainedWidth` (which is from `bandWidth`). In
            // the extreme cases for `value` axis, bars are allowed to overlap
            // with each other if `minWidth` specified.


            if (minWidth && minWidth > finalWidth) {
              finalWidth = minWidth;
            }

            if (finalWidth !== autoWidth) {
              column.width = finalWidth;
              remainedWidth -= finalWidth + barGapPercent * finalWidth;
              autoWidthCount--;
            }
          } else {
            // `barMinWidth/barMaxWidth` has higher priority than `barWidth`, as
            // CSS does. Because barWidth can be a percent value, where
            // `barMaxWidth` can be used to restrict the final width.
            var finalWidth = column.width;

            if (maxWidth) {
              finalWidth = Math.min(finalWidth, maxWidth);
            } // `minWidth` has higher priority, as described above


            if (minWidth) {
              finalWidth = Math.max(finalWidth, minWidth);
            }

            column.width = finalWidth;
            remainedWidth -= finalWidth + barGapPercent * finalWidth;
            autoWidthCount--;
          }
        }); // Recalculate width again

        autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
        autoWidth = Math.max(autoWidth, 0);
        var widthSum = 0;
        var lastColumn;
        each(stacks, function (column, idx) {
          if (!column.width) {
            column.width = autoWidth;
          }

          lastColumn = column;
          widthSum += column.width * (1 + barGapPercent);
        });

        if (lastColumn) {
          widthSum -= lastColumn.width * barGapPercent;
        }

        var offset = -widthSum / 2;
        each(stacks, function (column, stackId) {
          result[coordSysName][stackId] = result[coordSysName][stackId] || {
            bandWidth: bandWidth,
            offset: offset,
            width: column.width
          };
          offset += column.width * (1 + barGapPercent);
        });
      });
      return result;
    }

    function retrieveColumnLayout(barWidthAndOffset, axis, seriesModel) {
      if (barWidthAndOffset && axis) {
        var result = barWidthAndOffset[getAxisKey(axis)];

        if (result != null && seriesModel != null) {
          return result[getSeriesStackId(seriesModel)];
        }

        return result;
      }
    }
    function layout(seriesType, ecModel) {
      var seriesModels = prepareLayoutBarSeries(seriesType, ecModel);
      var barWidthAndOffset = makeColumnLayout(seriesModels);
      each(seriesModels, function (seriesModel) {
        var data = seriesModel.getData();
        var cartesian = seriesModel.coordinateSystem;
        var baseAxis = cartesian.getBaseAxis();
        var stackId = getSeriesStackId(seriesModel);
        var columnLayoutInfo = barWidthAndOffset[getAxisKey(baseAxis)][stackId];
        var columnOffset = columnLayoutInfo.offset;
        var columnWidth = columnLayoutInfo.width;
        data.setLayout({
          bandWidth: columnLayoutInfo.bandWidth,
          offset: columnOffset,
          size: columnWidth
        });
      });
    } // TODO: Do not support stack in large mode yet.

    function createProgressiveLayout(seriesType) {
      return {
        seriesType: seriesType,
        plan: createRenderPlanner(),
        reset: function (seriesModel) {
          if (!isOnCartesian(seriesModel)) {
            return;
          }

          var data = seriesModel.getData();
          var cartesian = seriesModel.coordinateSystem;
          var baseAxis = cartesian.getBaseAxis();
          var valueAxis = cartesian.getOtherAxis(baseAxis);
          var valueDimIdx = data.getDimensionIndex(data.mapDimension(valueAxis.dim));
          var baseDimIdx = data.getDimensionIndex(data.mapDimension(baseAxis.dim));
          var drawBackground = seriesModel.get('showBackground', true);
          var valueDim = data.mapDimension(valueAxis.dim);
          var stackResultDim = data.getCalculationInfo('stackResultDimension');
          var stacked = isDimensionStacked(data, valueDim) && !!data.getCalculationInfo('stackedOnSeries');
          var isValueAxisH = valueAxis.isHorizontal();
          var valueAxisStart = getValueAxisStart(baseAxis, valueAxis);
          var isLarge = isInLargeMode(seriesModel);
          var barMinHeight = seriesModel.get('barMinHeight') || 0;
          var stackedDimIdx = stackResultDim && data.getDimensionIndex(stackResultDim); // Layout info.

          var columnWidth = data.getLayout('size');
          var columnOffset = data.getLayout('offset');
          return {
            progress: function (params, data) {
              var count = params.count;
              var largePoints = isLarge && createFloat32Array(count * 3);
              var largeBackgroundPoints = isLarge && drawBackground && createFloat32Array(count * 3);
              var largeDataIndices = isLarge && createFloat32Array(count);
              var coordLayout = cartesian.master.getRect();
              var bgSize = isValueAxisH ? coordLayout.width : coordLayout.height;
              var dataIndex;
              var store = data.getStore();
              var idxOffset = 0;

              while ((dataIndex = params.next()) != null) {
                var value = store.get(stacked ? stackedDimIdx : valueDimIdx, dataIndex);
                var baseValue = store.get(baseDimIdx, dataIndex);
                var baseCoord = valueAxisStart;
                var startValue = void 0; // Because of the barMinHeight, we can not use the value in
                // stackResultDimension directly.

                if (stacked) {
                  startValue = +value - store.get(valueDimIdx, dataIndex);
                }

                var x = void 0;
                var y = void 0;
                var width = void 0;
                var height = void 0;

                if (isValueAxisH) {
                  var coord = cartesian.dataToPoint([value, baseValue]);

                  if (stacked) {
                    var startCoord = cartesian.dataToPoint([startValue, baseValue]);
                    baseCoord = startCoord[0];
                  }

                  x = baseCoord;
                  y = coord[1] + columnOffset;
                  width = coord[0] - baseCoord;
                  height = columnWidth;

                  if (Math.abs(width) < barMinHeight) {
                    width = (width < 0 ? -1 : 1) * barMinHeight;
                  }
                } else {
                  var coord = cartesian.dataToPoint([baseValue, value]);

                  if (stacked) {
                    var startCoord = cartesian.dataToPoint([baseValue, startValue]);
                    baseCoord = startCoord[1];
                  }

                  x = coord[0] + columnOffset;
                  y = baseCoord;
                  width = columnWidth;
                  height = coord[1] - baseCoord;

                  if (Math.abs(height) < barMinHeight) {
                    // Include zero to has a positive bar
                    height = (height <= 0 ? -1 : 1) * barMinHeight;
                  }
                }

                if (!isLarge) {
                  data.setItemLayout(dataIndex, {
                    x: x,
                    y: y,
                    width: width,
                    height: height
                  });
                } else {
                  largePoints[idxOffset] = x;
                  largePoints[idxOffset + 1] = y;
                  largePoints[idxOffset + 2] = isValueAxisH ? width : height;

                  if (largeBackgroundPoints) {
                    largeBackgroundPoints[idxOffset] = isValueAxisH ? coordLayout.x : x;
                    largeBackgroundPoints[idxOffset + 1] = isValueAxisH ? y : coordLayout.y;
                    largeBackgroundPoints[idxOffset + 2] = bgSize;
                  }

                  largeDataIndices[dataIndex] = dataIndex;
                }

                idxOffset += 3;
              }

              if (isLarge) {
                data.setLayout({
                  largePoints: largePoints,
                  largeDataIndices: largeDataIndices,
                  largeBackgroundPoints: largeBackgroundPoints,
                  valueAxisHorizontal: isValueAxisH
                });
              }
            }
          };
        }
      };
    }

    function isOnCartesian(seriesModel) {
      return seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d';
    }

    function isInLargeMode(seriesModel) {
      return seriesModel.pipelineContext && seriesModel.pipelineContext.large;
    } // See cases in `test/bar-start.html` and `#7412`, `#8747`.


    function getValueAxisStart(baseAxis, valueAxis) {
      return valueAxis.toGlobalCoord(valueAxis.dataToCoord(valueAxis.type === 'log' ? 1 : 0));
    }

    var bisect = function (a, x, lo, hi) {
      while (lo < hi) {
        var mid = lo + hi >>> 1;

        if (a[mid][1] < x) {
          lo = mid + 1;
        } else {
          hi = mid;
        }
      }

      return lo;
    };

    var TimeScale =
    /** @class */
    function (_super) {
      __extends(TimeScale, _super);

      function TimeScale(settings) {
        var _this = _super.call(this, settings) || this;

        _this.type = 'time';
        return _this;
      }
      /**
       * Get label is mainly for other components like dataZoom, tooltip.
       */


      TimeScale.prototype.getLabel = function (tick) {
        var useUTC = this.getSetting('useUTC');
        return format(tick.value, fullLeveledFormatter[getDefaultFormatPrecisionOfInterval(getPrimaryTimeUnit(this._minLevelUnit))] || fullLeveledFormatter.second, useUTC, this.getSetting('locale'));
      };

      TimeScale.prototype.getFormattedLabel = function (tick, idx, labelFormatter) {
        var isUTC = this.getSetting('useUTC');
        var lang = this.getSetting('locale');
        return leveledFormat(tick, idx, labelFormatter, lang, isUTC);
      };
      /**
       * @override
       */


      TimeScale.prototype.getTicks = function () {
        var interval = this._interval;
        var extent = this._extent;
        var ticks = []; // If interval is 0, return [];

        if (!interval) {
          return ticks;
        }

        ticks.push({
          value: extent[0],
          level: 0
        });
        var useUTC = this.getSetting('useUTC');
        var innerTicks = getIntervalTicks(this._minLevelUnit, this._approxInterval, useUTC, extent);
        ticks = ticks.concat(innerTicks);
        ticks.push({
          value: extent[1],
          level: 0
        });
        return ticks;
      };

      TimeScale.prototype.calcNiceExtent = function (opt) {
        var extent = this._extent; // If extent start and end are same, expand them

        if (extent[0] === extent[1]) {
          // Expand extent
          extent[0] -= ONE_DAY;
          extent[1] += ONE_DAY;
        } // If there are no data and extent are [Infinity, -Infinity]


        if (extent[1] === -Infinity && extent[0] === Infinity) {
          var d = new Date();
          extent[1] = +new Date(d.getFullYear(), d.getMonth(), d.getDate());
          extent[0] = extent[1] - ONE_DAY;
        }

        this.calcNiceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval);
      };

      TimeScale.prototype.calcNiceTicks = function (approxTickNum, minInterval, maxInterval) {
        approxTickNum = approxTickNum || 10;
        var extent = this._extent;
        var span = extent[1] - extent[0];
        this._approxInterval = span / approxTickNum;

        if (minInterval != null && this._approxInterval < minInterval) {
          this._approxInterval = minInterval;
        }

        if (maxInterval != null && this._approxInterval > maxInterval) {
          this._approxInterval = maxInterval;
        }

        var scaleIntervalsLen = scaleIntervals.length;
        var idx = Math.min(bisect(scaleIntervals, this._approxInterval, 0, scaleIntervalsLen), scaleIntervalsLen - 1); // Interval that can be used to calculate ticks

        this._interval = scaleIntervals[idx][1]; // Min level used when picking ticks from top down.
        // We check one more level to avoid the ticks are to sparse in some case.

        this._minLevelUnit = scaleIntervals[Math.max(idx - 1, 0)][0];
      };

      TimeScale.prototype.parse = function (val) {
        // val might be float.
        return isNumber(val) ? val : +parseDate(val);
      };

      TimeScale.prototype.contain = function (val) {
        return contain$1(this.parse(val), this._extent);
      };

      TimeScale.prototype.normalize = function (val) {
        return normalize$1(this.parse(val), this._extent);
      };

      TimeScale.prototype.scale = function (val) {
        return scale$2(val, this._extent);
      };

      TimeScale.type = 'time';
      return TimeScale;
    }(IntervalScale);
    /**
     * This implementation was originally copied from "d3.js"
     * <https://github.com/d3/d3/blob/b516d77fb8566b576088e73410437494717ada26/src/time/scale.js>
     * with some modifications made for this program.
     * See the license statement at the head of this file.
     */


    var scaleIntervals = [// Format                           interval
    ['second', ONE_SECOND], ['minute', ONE_MINUTE], ['hour', ONE_HOUR], ['quarter-day', ONE_HOUR * 6], ['half-day', ONE_HOUR * 12], ['day', ONE_DAY * 1.2], ['half-week', ONE_DAY * 3.5], ['week', ONE_DAY * 7], ['month', ONE_DAY * 31], ['quarter', ONE_DAY * 95], ['half-year', ONE_YEAR / 2], ['year', ONE_YEAR] // 1Y
    ];

    function isUnitValueSame(unit, valueA, valueB, isUTC) {
      var dateA = parseDate(valueA);
      var dateB = parseDate(valueB);

      var isSame = function (unit) {
        return getUnitValue(dateA, unit, isUTC) === getUnitValue(dateB, unit, isUTC);
      };

      var isSameYear = function () {
        return isSame('year');
      }; // const isSameHalfYear = () => isSameYear() && isSame('half-year');
      // const isSameQuater = () => isSameYear() && isSame('quarter');


      var isSameMonth = function () {
        return isSameYear() && isSame('month');
      };

      var isSameDay = function () {
        return isSameMonth() && isSame('day');
      }; // const isSameHalfDay = () => isSameDay() && isSame('half-day');


      var isSameHour = function () {
        return isSameDay() && isSame('hour');
      };

      var isSameMinute = function () {
        return isSameHour() && isSame('minute');
      };

      var isSameSecond = function () {
        return isSameMinute() && isSame('second');
      };

      var isSameMilliSecond = function () {
        return isSameSecond() && isSame('millisecond');
      };

      switch (unit) {
        case 'year':
          return isSameYear();

        case 'month':
          return isSameMonth();

        case 'day':
          return isSameDay();

        case 'hour':
          return isSameHour();

        case 'minute':
          return isSameMinute();

        case 'second':
          return isSameSecond();

        case 'millisecond':
          return isSameMilliSecond();
      }
    } // const primaryUnitGetters = {
    //     year: fullYearGetterName(),
    //     month: monthGetterName(),
    //     day: dateGetterName(),
    //     hour: hoursGetterName(),
    //     minute: minutesGetterName(),
    //     second: secondsGetterName(),
    //     millisecond: millisecondsGetterName()
    // };
    // const primaryUnitUTCGetters = {
    //     year: fullYearGetterName(true),
    //     month: monthGetterName(true),
    //     day: dateGetterName(true),
    //     hour: hoursGetterName(true),
    //     minute: minutesGetterName(true),
    //     second: secondsGetterName(true),
    //     millisecond: millisecondsGetterName(true)
    // };
    // function moveTick(date: Date, unitName: TimeUnit, step: number, isUTC: boolean) {
    //     step = step || 1;
    //     switch (getPrimaryTimeUnit(unitName)) {
    //         case 'year':
    //             date[fullYearSetterName(isUTC)](date[fullYearGetterName(isUTC)]() + step);
    //             break;
    //         case 'month':
    //             date[monthSetterName(isUTC)](date[monthGetterName(isUTC)]() + step);
    //             break;
    //         case 'day':
    //             date[dateSetterName(isUTC)](date[dateGetterName(isUTC)]() + step);
    //             break;
    //         case 'hour':
    //             date[hoursSetterName(isUTC)](date[hoursGetterName(isUTC)]() + step);
    //             break;
    //         case 'minute':
    //             date[minutesSetterName(isUTC)](date[minutesGetterName(isUTC)]() + step);
    //             break;
    //         case 'second':
    //             date[secondsSetterName(isUTC)](date[secondsGetterName(isUTC)]() + step);
    //             break;
    //         case 'millisecond':
    //             date[millisecondsSetterName(isUTC)](date[millisecondsGetterName(isUTC)]() + step);
    //             break;
    //     }
    //     return date.getTime();
    // }
    // const DATE_INTERVALS = [[8, 7.5], [4, 3.5], [2, 1.5]];
    // const MONTH_INTERVALS = [[6, 5.5], [3, 2.5], [2, 1.5]];
    // const MINUTES_SECONDS_INTERVALS = [[30, 30], [20, 20], [15, 15], [10, 10], [5, 5], [2, 2]];


    function getDateInterval(approxInterval, daysInMonth) {
      approxInterval /= ONE_DAY;
      return approxInterval > 16 ? 16 // Math.floor(daysInMonth / 2) + 1  // In this case we only want one tick between two months.
      : approxInterval > 7.5 ? 7 // TODO week 7 or day 8?
      : approxInterval > 3.5 ? 4 : approxInterval > 1.5 ? 2 : 1;
    }

    function getMonthInterval(approxInterval) {
      var APPROX_ONE_MONTH = 30 * ONE_DAY;
      approxInterval /= APPROX_ONE_MONTH;
      return approxInterval > 6 ? 6 : approxInterval > 3 ? 3 : approxInterval > 2 ? 2 : 1;
    }

    function getHourInterval(approxInterval) {
      approxInterval /= ONE_HOUR;
      return approxInterval > 12 ? 12 : approxInterval > 6 ? 6 : approxInterval > 3.5 ? 4 : approxInterval > 2 ? 2 : 1;
    }

    function getMinutesAndSecondsInterval(approxInterval, isMinutes) {
      approxInterval /= isMinutes ? ONE_MINUTE : ONE_SECOND;
      return approxInterval > 30 ? 30 : approxInterval > 20 ? 20 : approxInterval > 15 ? 15 : approxInterval > 10 ? 10 : approxInterval > 5 ? 5 : approxInterval > 2 ? 2 : 1;
    }

    function getMillisecondsInterval(approxInterval) {
      return nice(approxInterval, true);
    }

    function getFirstTimestampOfUnit(date, unitName, isUTC) {
      var outDate = new Date(date);

      switch (getPrimaryTimeUnit(unitName)) {
        case 'year':
        case 'month':
          outDate[monthSetterName(isUTC)](0);

        case 'day':
          outDate[dateSetterName(isUTC)](1);

        case 'hour':
          outDate[hoursSetterName(isUTC)](0);

        case 'minute':
          outDate[minutesSetterName(isUTC)](0);

        case 'second':
          outDate[secondsSetterName(isUTC)](0);
          outDate[millisecondsSetterName(isUTC)](0);
      }

      return outDate.getTime();
    }

    function getIntervalTicks(bottomUnitName, approxInterval, isUTC, extent) {
      var safeLimit = 10000;
      var unitNames = timeUnits;
      var iter = 0;

      function addTicksInSpan(interval, minTimestamp, maxTimestamp, getMethodName, setMethodName, isDate, out) {
        var date = new Date(minTimestamp);
        var dateTime = minTimestamp;
        var d = date[getMethodName](); // if (isDate) {
        //     d -= 1; // Starts with 0;   PENDING
        // }

        while (dateTime < maxTimestamp && dateTime <= extent[1]) {
          out.push({
            value: dateTime
          });
          d += interval;
          date[setMethodName](d);
          dateTime = date.getTime();
        } // This extra tick is for calcuating ticks of next level. Will not been added to the final result


        out.push({
          value: dateTime,
          notAdd: true
        });
      }

      function addLevelTicks(unitName, lastLevelTicks, levelTicks) {
        var newAddedTicks = [];
        var isFirstLevel = !lastLevelTicks.length;

        if (isUnitValueSame(getPrimaryTimeUnit(unitName), extent[0], extent[1], isUTC)) {
          return;
        }

        if (isFirstLevel) {
          lastLevelTicks = [{
            // TODO Optimize. Not include so may ticks.
            value: getFirstTimestampOfUnit(new Date(extent[0]), unitName, isUTC)
          }, {
            value: extent[1]
          }];
        }

        for (var i = 0; i < lastLevelTicks.length - 1; i++) {
          var startTick = lastLevelTicks[i].value;
          var endTick = lastLevelTicks[i + 1].value;

          if (startTick === endTick) {
            continue;
          }

          var interval = void 0;
          var getterName = void 0;
          var setterName = void 0;
          var isDate = false;

          switch (unitName) {
            case 'year':
              interval = Math.max(1, Math.round(approxInterval / ONE_DAY / 365));
              getterName = fullYearGetterName(isUTC);
              setterName = fullYearSetterName(isUTC);
              break;

            case 'half-year':
            case 'quarter':
            case 'month':
              interval = getMonthInterval(approxInterval);
              getterName = monthGetterName(isUTC);
              setterName = monthSetterName(isUTC);
              break;

            case 'week': // PENDING If week is added. Ignore day.

            case 'half-week':
            case 'day':
              interval = getDateInterval(approxInterval); // Use 32 days and let interval been 16

              getterName = dateGetterName(isUTC);
              setterName = dateSetterName(isUTC);
              isDate = true;
              break;

            case 'half-day':
            case 'quarter-day':
            case 'hour':
              interval = getHourInterval(approxInterval);
              getterName = hoursGetterName(isUTC);
              setterName = hoursSetterName(isUTC);
              break;

            case 'minute':
              interval = getMinutesAndSecondsInterval(approxInterval, true);
              getterName = minutesGetterName(isUTC);
              setterName = minutesSetterName(isUTC);
              break;

            case 'second':
              interval = getMinutesAndSecondsInterval(approxInterval, false);
              getterName = secondsGetterName(isUTC);
              setterName = secondsSetterName(isUTC);
              break;

            case 'millisecond':
              interval = getMillisecondsInterval(approxInterval);
              getterName = millisecondsGetterName(isUTC);
              setterName = millisecondsSetterName(isUTC);
              break;
          }

          addTicksInSpan(interval, startTick, endTick, getterName, setterName, isDate, newAddedTicks);

          if (unitName === 'year' && levelTicks.length > 1 && i === 0) {
            // Add nearest years to the left extent.
            levelTicks.unshift({
              value: levelTicks[0].value - interval
            });
          }
        }

        for (var i = 0; i < newAddedTicks.length; i++) {
          levelTicks.push(newAddedTicks[i]);
        } // newAddedTicks.length && console.log(unitName, newAddedTicks);


        return newAddedTicks;
      }

      var levelsTicks = [];
      var currentLevelTicks = [];
      var tickCount = 0;
      var lastLevelTickCount = 0;

      for (var i = 0; i < unitNames.length && iter++ < safeLimit; ++i) {
        var primaryTimeUnit = getPrimaryTimeUnit(unitNames[i]);

        if (!isPrimaryTimeUnit(unitNames[i])) {
          // TODO
          continue;
        }

        addLevelTicks(unitNames[i], levelsTicks[levelsTicks.length - 1] || [], currentLevelTicks);
        var nextPrimaryTimeUnit = unitNames[i + 1] ? getPrimaryTimeUnit(unitNames[i + 1]) : null;

        if (primaryTimeUnit !== nextPrimaryTimeUnit) {
          if (currentLevelTicks.length) {
            lastLevelTickCount = tickCount; // Remove the duplicate so the tick count can be precisely.

            currentLevelTicks.sort(function (a, b) {
              return a.value - b.value;
            });
            var levelTicksRemoveDuplicated = [];

            for (var i_1 = 0; i_1 < currentLevelTicks.length; ++i_1) {
              var tickValue = currentLevelTicks[i_1].value;

              if (i_1 === 0 || currentLevelTicks[i_1 - 1].value !== tickValue) {
                levelTicksRemoveDuplicated.push(currentLevelTicks[i_1]);

                if (tickValue >= extent[0] && tickValue <= extent[1]) {
                  tickCount++;
                }
              }
            }

            var targetTickNum = (extent[1] - extent[0]) / approxInterval; // Added too much in this level and not too less in last level

            if (tickCount > targetTickNum * 1.5 && lastLevelTickCount > targetTickNum / 1.5) {
              break;
            } // Only treat primary time unit as one level.


            levelsTicks.push(levelTicksRemoveDuplicated);

            if (tickCount > targetTickNum || bottomUnitName === unitNames[i]) {
              break;
            }
          } // Reset if next unitName is primary


          currentLevelTicks = [];
        }
      }

      if ("development" !== 'production') {
        if (iter >= safeLimit) {
          warn('Exceed safe limit.');
        }
      }

      var levelsTicksInExtent = filter(map(levelsTicks, function (levelTicks) {
        return filter(levelTicks, function (tick) {
          return tick.value >= extent[0] && tick.value <= extent[1] && !tick.notAdd;
        });
      }), function (levelTicks) {
        return levelTicks.length > 0;
      });
      var ticks = [];
      var maxLevel = levelsTicksInExtent.length - 1;

      for (var i = 0; i < levelsTicksInExtent.length; ++i) {
        var levelTicks = levelsTicksInExtent[i];

        for (var k = 0; k < levelTicks.length; ++k) {
          ticks.push({
            value: levelTicks[k].value,
            level: maxLevel - i
          });
        }
      }

      ticks.sort(function (a, b) {
        return a.value - b.value;
      }); // Remove duplicates

      var result = [];

      for (var i = 0; i < ticks.length; ++i) {
        if (i === 0 || ticks[i].value !== ticks[i - 1].value) {
          result.push(ticks[i]);
        }
      }

      return result;
    }

    Scale.registerClass(TimeScale);

    var scaleProto = Scale.prototype; // FIXME:TS refactor: not good to call it directly with `this`?

    var intervalScaleProto = IntervalScale.prototype;
    var roundingErrorFix = round;
    var mathFloor = Math.floor;
    var mathCeil = Math.ceil;
    var mathPow$1 = Math.pow;
    var mathLog = Math.log;

    var LogScale =
    /** @class */
    function (_super) {
      __extends(LogScale, _super);

      function LogScale() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'log';
        _this.base = 10;
        _this._originalScale = new IntervalScale(); // FIXME:TS actually used by `IntervalScale`

        _this._interval = 0;
        return _this;
      }
      /**
       * @param Whether expand the ticks to niced extent.
       */


      LogScale.prototype.getTicks = function (expandToNicedExtent) {
        var originalScale = this._originalScale;
        var extent = this._extent;
        var originalExtent = originalScale.getExtent();
        var ticks = intervalScaleProto.getTicks.call(this, expandToNicedExtent);
        return map(ticks, function (tick) {
          var val = tick.value;
          var powVal = round(mathPow$1(this.base, val)); // Fix #4158

          powVal = val === extent[0] && this._fixMin ? fixRoundingError(powVal, originalExtent[0]) : powVal;
          powVal = val === extent[1] && this._fixMax ? fixRoundingError(powVal, originalExtent[1]) : powVal;
          return {
            value: powVal
          };
        }, this);
      };

      LogScale.prototype.setExtent = function (start, end) {
        var base = mathLog(this.base); // log(-Infinity) is NaN, so safe guard here

        start = mathLog(Math.max(0, start)) / base;
        end = mathLog(Math.max(0, end)) / base;
        intervalScaleProto.setExtent.call(this, start, end);
      };
      /**
       * @return {number} end
       */


      LogScale.prototype.getExtent = function () {
        var base = this.base;
        var extent = scaleProto.getExtent.call(this);
        extent[0] = mathPow$1(base, extent[0]);
        extent[1] = mathPow$1(base, extent[1]); // Fix #4158

        var originalScale = this._originalScale;
        var originalExtent = originalScale.getExtent();
        this._fixMin && (extent[0] = fixRoundingError(extent[0], originalExtent[0]));
        this._fixMax && (extent[1] = fixRoundingError(extent[1], originalExtent[1]));
        return extent;
      };

      LogScale.prototype.unionExtent = function (extent) {
        this._originalScale.unionExtent(extent);

        var base = this.base;
        extent[0] = mathLog(extent[0]) / mathLog(base);
        extent[1] = mathLog(extent[1]) / mathLog(base);
        scaleProto.unionExtent.call(this, extent);
      };

      LogScale.prototype.unionExtentFromData = function (data, dim) {
        // TODO
        // filter value that <= 0
        this.unionExtent(data.getApproximateExtent(dim));
      };
      /**
       * Update interval and extent of intervals for nice ticks
       * @param approxTickNum default 10 Given approx tick number
       */


      LogScale.prototype.calcNiceTicks = function (approxTickNum) {
        approxTickNum = approxTickNum || 10;
        var extent = this._extent;
        var span = extent[1] - extent[0];

        if (span === Infinity || span <= 0) {
          return;
        }

        var interval = quantity(span);
        var err = approxTickNum / span * interval; // Filter ticks to get closer to the desired count.

        if (err <= 0.5) {
          interval *= 10;
        } // Interval should be integer


        while (!isNaN(interval) && Math.abs(interval) < 1 && Math.abs(interval) > 0) {
          interval *= 10;
        }

        var niceExtent = [round(mathCeil(extent[0] / interval) * interval), round(mathFloor(extent[1] / interval) * interval)];
        this._interval = interval;
        this._niceExtent = niceExtent;
      };

      LogScale.prototype.calcNiceExtent = function (opt) {
        intervalScaleProto.calcNiceExtent.call(this, opt);
        this._fixMin = opt.fixMin;
        this._fixMax = opt.fixMax;
      };

      LogScale.prototype.parse = function (val) {
        return val;
      };

      LogScale.prototype.contain = function (val) {
        val = mathLog(val) / mathLog(this.base);
        return contain$1(val, this._extent);
      };

      LogScale.prototype.normalize = function (val) {
        val = mathLog(val) / mathLog(this.base);
        return normalize$1(val, this._extent);
      };

      LogScale.prototype.scale = function (val) {
        val = scale$2(val, this._extent);
        return mathPow$1(this.base, val);
      };

      LogScale.type = 'log';
      return LogScale;
    }(Scale);

    var proto = LogScale.prototype;
    proto.getMinorTicks = intervalScaleProto.getMinorTicks;
    proto.getLabel = intervalScaleProto.getLabel;

    function fixRoundingError(val, originalVal) {
      return roundingErrorFix(val, getPrecision(originalVal));
    }

    Scale.registerClass(LogScale);

    var ScaleRawExtentInfo =
    /** @class */
    function () {
      function ScaleRawExtentInfo(scale, model, // Usually: data extent from all series on this axis.
      originalExtent) {
        this._prepareParams(scale, model, originalExtent);
      }
      /**
       * Parameters depending on outside (like model, user callback)
       * are prepared and fixed here.
       */


      ScaleRawExtentInfo.prototype._prepareParams = function (scale, model, // Usually: data extent from all series on this axis.
      dataExtent) {
        if (dataExtent[1] < dataExtent[0]) {
          dataExtent = [NaN, NaN];
        }

        this._dataMin = dataExtent[0];
        this._dataMax = dataExtent[1];
        var isOrdinal = this._isOrdinal = scale.type === 'ordinal';
        this._needCrossZero = scale.type === 'interval' && model.getNeedCrossZero && model.getNeedCrossZero();
        var modelMinRaw = this._modelMinRaw = model.get('min', true);

        if (isFunction(modelMinRaw)) {
          // This callback always provides users the full data extent (before data is filtered).
          this._modelMinNum = parseAxisModelMinMax(scale, modelMinRaw({
            min: dataExtent[0],
            max: dataExtent[1]
          }));
        } else if (modelMinRaw !== 'dataMin') {
          this._modelMinNum = parseAxisModelMinMax(scale, modelMinRaw);
        }

        var modelMaxRaw = this._modelMaxRaw = model.get('max', true);

        if (isFunction(modelMaxRaw)) {
          // This callback always provides users the full data extent (before data is filtered).
          this._modelMaxNum = parseAxisModelMinMax(scale, modelMaxRaw({
            min: dataExtent[0],
            max: dataExtent[1]
          }));
        } else if (modelMaxRaw !== 'dataMax') {
          this._modelMaxNum = parseAxisModelMinMax(scale, modelMaxRaw);
        }

        if (isOrdinal) {
          // FIXME: there is a flaw here: if there is no "block" data processor like `dataZoom`,
          // and progressive rendering is using, here the category result might just only contain
          // the processed chunk rather than the entire result.
          this._axisDataLen = model.getCategories().length;
        } else {
          var boundaryGap = model.get('boundaryGap');
          var boundaryGapArr = isArray(boundaryGap) ? boundaryGap : [boundaryGap || 0, boundaryGap || 0];

          if (typeof boundaryGapArr[0] === 'boolean' || typeof boundaryGapArr[1] === 'boolean') {
            if ("development" !== 'production') {
              console.warn('Boolean type for boundaryGap is only ' + 'allowed for ordinal axis. Please use string in ' + 'percentage instead, e.g., "20%". Currently, ' + 'boundaryGap is set to be 0.');
            }

            this._boundaryGapInner = [0, 0];
          } else {
            this._boundaryGapInner = [parsePercent(boundaryGapArr[0], 1), parsePercent(boundaryGapArr[1], 1)];
          }
        }
      };
      /**
       * Calculate extent by prepared parameters.
       * This method has no external dependency and can be called duplicatedly,
       * getting the same result.
       * If parameters changed, should call this method to recalcuate.
       */


      ScaleRawExtentInfo.prototype.calculate = function () {
        // Notice: When min/max is not set (that is, when there are null/undefined,
        // which is the most common case), these cases should be ensured:
        // (1) For 'ordinal', show all axis.data.
        // (2) For others:
        //      + `boundaryGap` is applied (if min/max set, boundaryGap is
        //      disabled).
        //      + If `needCrossZero`, min/max should be zero, otherwise, min/max should
        //      be the result that originalExtent enlarged by boundaryGap.
        // (3) If no data, it should be ensured that `scale.setBlank` is set.
        var isOrdinal = this._isOrdinal;
        var dataMin = this._dataMin;
        var dataMax = this._dataMax;
        var axisDataLen = this._axisDataLen;
        var boundaryGapInner = this._boundaryGapInner;
        var span = !isOrdinal ? dataMax - dataMin || Math.abs(dataMin) : null; // Currently if a `'value'` axis model min is specified as 'dataMin'/'dataMax',
        // `boundaryGap` will not be used. It's the different from specifying as `null`/`undefined`.

        var min = this._modelMinRaw === 'dataMin' ? dataMin : this._modelMinNum;
        var max = this._modelMaxRaw === 'dataMax' ? dataMax : this._modelMaxNum; // If `_modelMinNum`/`_modelMaxNum` is `null`/`undefined`, should not be fixed.

        var minFixed = min != null;
        var maxFixed = max != null;

        if (min == null) {
          min = isOrdinal ? axisDataLen ? 0 : NaN : dataMin - boundaryGapInner[0] * span;
        }

        if (max == null) {
          max = isOrdinal ? axisDataLen ? axisDataLen - 1 : NaN : dataMax + boundaryGapInner[1] * span;
        }

        (min == null || !isFinite(min)) && (min = NaN);
        (max == null || !isFinite(max)) && (max = NaN);
        var isBlank = eqNaN(min) || eqNaN(max) || isOrdinal && !axisDataLen; // If data extent modified, need to recalculated to ensure cross zero.

        if (this._needCrossZero) {
          // Axis is over zero and min is not set
          if (min > 0 && max > 0 && !minFixed) {
            min = 0; // minFixed = true;
          } // Axis is under zero and max is not set


          if (min < 0 && max < 0 && !maxFixed) {
            max = 0; // maxFixed = true;
          } // PENDING:
          // When `needCrossZero` and all data is positive/negative, should it be ensured
          // that the results processed by boundaryGap are positive/negative?
          // If so, here `minFixed`/`maxFixed` need to be set.

        }

        var determinedMin = this._determinedMin;
        var determinedMax = this._determinedMax;

        if (determinedMin != null) {
          min = determinedMin;
          minFixed = true;
        }

        if (determinedMax != null) {
          max = determinedMax;
          maxFixed = true;
        } // Ensure min/max be finite number or NaN here. (not to be null/undefined)
        // `NaN` means min/max axis is blank.


        return {
          min: min,
          max: max,
          minFixed: minFixed,
          maxFixed: maxFixed,
          isBlank: isBlank
        };
      };

      ScaleRawExtentInfo.prototype.modifyDataMinMax = function (minMaxName, val) {
        if ("development" !== 'production') {
          assert(!this.frozen);
        }

        this[DATA_MIN_MAX_ATTR[minMaxName]] = val;
      };

      ScaleRawExtentInfo.prototype.setDeterminedMinMax = function (minMaxName, val) {
        var attr = DETERMINED_MIN_MAX_ATTR[minMaxName];

        if ("development" !== 'production') {
          assert(!this.frozen // Earse them usually means logic flaw.
          && this[attr] == null);
        }

        this[attr] = val;
      };

      ScaleRawExtentInfo.prototype.freeze = function () {
        // @ts-ignore
        this.frozen = true;
      };

      return ScaleRawExtentInfo;
    }();
    var DETERMINED_MIN_MAX_ATTR = {
      min: '_determinedMin',
      max: '_determinedMax'
    };
    var DATA_MIN_MAX_ATTR = {
      min: '_dataMin',
      max: '_dataMax'
    };
    /**
     * Get scale min max and related info only depends on model settings.
     * This method can be called after coordinate system created.
     * For example, in data processing stage.
     *
     * Scale extent info probably be required multiple times during a workflow.
     * For example:
     * (1) `dataZoom` depends it to get the axis extent in "100%" state.
     * (2) `processor/extentCalculator` depends it to make sure whether axis extent is specified.
     * (3) `coordSys.update` use it to finally decide the scale extent.
     * But the callback of `min`/`max` should not be called multiple times.
     * The code below should not be implemented repeatedly either.
     * So we cache the result in the scale instance, which will be recreated at the beginning
     * of the workflow (because `scale` instance will be recreated each round of the workflow).
     */

    function ensureScaleRawExtentInfo(scale, model, // Usually: data extent from all series on this axis.
    originalExtent) {
      // Do not permit to recreate.
      var rawExtentInfo = scale.rawExtentInfo;

      if (rawExtentInfo) {
        return rawExtentInfo;
      }

      rawExtentInfo = new ScaleRawExtentInfo(scale, model, originalExtent); // @ts-ignore

      scale.rawExtentInfo = rawExtentInfo;
      return rawExtentInfo;
    }
    function parseAxisModelMinMax(scale, minMax) {
      return minMax == null ? null : eqNaN(minMax) ? NaN : scale.parse(minMax);
    }

    /**
     * Get axis scale extent before niced.
     * Item of returned array can only be number (including Infinity and NaN).
     *
     * Caution:
     * Precondition of calling this method:
     * The scale extent has been initialized using series data extent via
     * `scale.setExtent` or `scale.unionExtentFromData`;
     */

    function getScaleExtent(scale, model) {
      var scaleType = scale.type;
      var rawExtentResult = ensureScaleRawExtentInfo(scale, model, scale.getExtent()).calculate();
      scale.setBlank(rawExtentResult.isBlank);
      var min = rawExtentResult.min;
      var max = rawExtentResult.max; // If bars are placed on a base axis of type time or interval account for axis boundary overflow and current axis
      // is base axis
      // FIXME
      // (1) Consider support value axis, where below zero and axis `onZero` should be handled properly.
      // (2) Refactor the logic with `barGrid`. Is it not need to `makeBarWidthAndOffsetInfo` twice with different extent?
      //     Should not depend on series type `bar`?
      // (3) Fix that might overlap when using dataZoom.
      // (4) Consider other chart types using `barGrid`?
      // See #6728, #4862, `test/bar-overflow-time-plot.html`

      var ecModel = model.ecModel;

      if (ecModel && scaleType === 'time'
      /* || scaleType === 'interval' */
      ) {
        var barSeriesModels = prepareLayoutBarSeries('bar', ecModel);
        var isBaseAxisAndHasBarSeries_1 = false;
        each(barSeriesModels, function (seriesModel) {
          isBaseAxisAndHasBarSeries_1 = isBaseAxisAndHasBarSeries_1 || seriesModel.getBaseAxis() === model.axis;
        });

        if (isBaseAxisAndHasBarSeries_1) {
          // Calculate placement of bars on axis. TODO should be decoupled
          // with barLayout
          var barWidthAndOffset = makeColumnLayout(barSeriesModels); // Adjust axis min and max to account for overflow

          var adjustedScale = adjustScaleForOverflow(min, max, model, barWidthAndOffset);
          min = adjustedScale.min;
          max = adjustedScale.max;
        }
      }

      return {
        extent: [min, max],
        // "fix" means "fixed", the value should not be
        // changed in the subsequent steps.
        fixMin: rawExtentResult.minFixed,
        fixMax: rawExtentResult.maxFixed
      };
    }

    function adjustScaleForOverflow(min, max, model, // Only support cartesian coord yet.
    barWidthAndOffset) {
      // Get Axis Length
      var axisExtent = model.axis.getExtent();
      var axisLength = axisExtent[1] - axisExtent[0]; // Get bars on current base axis and calculate min and max overflow

      var barsOnCurrentAxis = retrieveColumnLayout(barWidthAndOffset, model.axis);

      if (barsOnCurrentAxis === undefined) {
        return {
          min: min,
          max: max
        };
      }

      var minOverflow = Infinity;
      each(barsOnCurrentAxis, function (item) {
        minOverflow = Math.min(item.offset, minOverflow);
      });
      var maxOverflow = -Infinity;
      each(barsOnCurrentAxis, function (item) {
        maxOverflow = Math.max(item.offset + item.width, maxOverflow);
      });
      minOverflow = Math.abs(minOverflow);
      maxOverflow = Math.abs(maxOverflow);
      var totalOverFlow = minOverflow + maxOverflow; // Calculate required buffer based on old range and overflow

      var oldRange = max - min;
      var oldRangePercentOfNew = 1 - (minOverflow + maxOverflow) / axisLength;
      var overflowBuffer = oldRange / oldRangePercentOfNew - oldRange;
      max += overflowBuffer * (maxOverflow / totalOverFlow);
      min -= overflowBuffer * (minOverflow / totalOverFlow);
      return {
        min: min,
        max: max
      };
    } // Precondition of calling this method:
    // The scale extent has been initialized using series data extent via
    // `scale.setExtent` or `scale.unionExtentFromData`;


    function niceScaleExtent(scale, inModel) {
      var model = inModel;
      var extentInfo = getScaleExtent(scale, model);
      var extent = extentInfo.extent;
      var splitNumber = model.get('splitNumber');

      if (scale instanceof LogScale) {
        scale.base = model.get('logBase');
      }

      var scaleType = scale.type;
      var interval = model.get('interval');
      var isIntervalOrTime = scaleType === 'interval' || scaleType === 'time';
      scale.setExtent(extent[0], extent[1]);
      scale.calcNiceExtent({
        splitNumber: splitNumber,
        fixMin: extentInfo.fixMin,
        fixMax: extentInfo.fixMax,
        minInterval: isIntervalOrTime ? model.get('minInterval') : null,
        maxInterval: isIntervalOrTime ? model.get('maxInterval') : null
      }); // If some one specified the min, max. And the default calculated interval
      // is not good enough. He can specify the interval. It is often appeared
      // in angle axis with angle 0 - 360. Interval calculated in interval scale is hard
      // to be 60.
      // FIXME

      if (interval != null) {
        scale.setInterval && scale.setInterval(interval);
      }
    }
    /**
     * @param axisType Default retrieve from model.type
     */

    function createScaleByModel(model, axisType) {
      axisType = axisType || model.get('type');

      if (axisType) {
        switch (axisType) {
          // Buildin scale
          case 'category':
            return new OrdinalScale({
              ordinalMeta: model.getOrdinalMeta ? model.getOrdinalMeta() : model.getCategories(),
              extent: [Infinity, -Infinity]
            });

          case 'time':
            return new TimeScale({
              locale: model.ecModel.getLocaleModel(),
              useUTC: model.ecModel.get('useUTC')
            });

          default:
            // case 'value'/'interval', 'log', or others.
            return new (Scale.getClass(axisType) || IntervalScale)();
        }
      }
    }
    /**
     * Check if the axis cross 0
     */

    function ifAxisCrossZero(axis) {
      var dataExtent = axis.scale.getExtent();
      var min = dataExtent[0];
      var max = dataExtent[1];
      return !(min > 0 && max > 0 || min < 0 && max < 0);
    }
    /**
     * @param axis
     * @return Label formatter function.
     *         param: {number} tickValue,
     *         param: {number} idx, the index in all ticks.
     *                         If category axis, this param is not required.
     *         return: {string} label string.
     */

    function makeLabelFormatter(axis) {
      var labelFormatter = axis.getLabelModel().get('formatter');
      var categoryTickStart = axis.type === 'category' ? axis.scale.getExtent()[0] : null;

      if (axis.scale.type === 'time') {
        return function (tpl) {
          return function (tick, idx) {
            return axis.scale.getFormattedLabel(tick, idx, tpl);
          };
        }(labelFormatter);
      } else if (isString(labelFormatter)) {
        return function (tpl) {
          return function (tick) {
            // For category axis, get raw value; for numeric axis,
            // get formatted label like '1,333,444'.
            var label = axis.scale.getLabel(tick);
            var text = tpl.replace('{value}', label != null ? label : '');
            return text;
          };
        }(labelFormatter);
      } else if (isFunction(labelFormatter)) {
        return function (cb) {
          return function (tick, idx) {
            // The original intention of `idx` is "the index of the tick in all ticks".
            // But the previous implementation of category axis do not consider the
            // `axisLabel.interval`, which cause that, for example, the `interval` is
            // `1`, then the ticks "name5", "name7", "name9" are displayed, where the
            // corresponding `idx` are `0`, `2`, `4`, but not `0`, `1`, `2`. So we keep
            // the definition here for back compatibility.
            if (categoryTickStart != null) {
              idx = tick.value - categoryTickStart;
            }

            return cb(getAxisRawValue(axis, tick), idx, tick.level != null ? {
              level: tick.level
            } : null);
          };
        }(labelFormatter);
      } else {
        return function (tick) {
          return axis.scale.getLabel(tick);
        };
      }
    }
    function getAxisRawValue(axis, tick) {
      // In category axis with data zoom, tick is not the original
      // index of axis.data. So tick should not be exposed to user
      // in category axis.
      return axis.type === 'category' ? axis.scale.getLabel(tick) : tick.value;
    }
    /**
     * @param axis
     * @return Be null/undefined if no labels.
     */

    function estimateLabelUnionRect(axis) {
      var axisModel = axis.model;
      var scale = axis.scale;

      if (!axisModel.get(['axisLabel', 'show']) || scale.isBlank()) {
        return;
      }

      var realNumberScaleTicks;
      var tickCount;
      var categoryScaleExtent = scale.getExtent(); // Optimize for large category data, avoid call `getTicks()`.

      if (scale instanceof OrdinalScale) {
        tickCount = scale.count();
      } else {
        realNumberScaleTicks = scale.getTicks();
        tickCount = realNumberScaleTicks.length;
      }

      var axisLabelModel = axis.getLabelModel();
      var labelFormatter = makeLabelFormatter(axis);
      var rect;
      var step = 1; // Simple optimization for large amount of labels

      if (tickCount > 40) {
        step = Math.ceil(tickCount / 40);
      }

      for (var i = 0; i < tickCount; i += step) {
        var tick = realNumberScaleTicks ? realNumberScaleTicks[i] : {
          value: categoryScaleExtent[0] + i
        };
        var label = labelFormatter(tick, i);
        var unrotatedSingleRect = axisLabelModel.getTextRect(label);
        var singleRect = rotateTextRect(unrotatedSingleRect, axisLabelModel.get('rotate') || 0);
        rect ? rect.union(singleRect) : rect = singleRect;
      }

      return rect;
    }

    function rotateTextRect(textRect, rotate) {
      var rotateRadians = rotate * Math.PI / 180;
      var beforeWidth = textRect.width;
      var beforeHeight = textRect.height;
      var afterWidth = beforeWidth * Math.abs(Math.cos(rotateRadians)) + Math.abs(beforeHeight * Math.sin(rotateRadians));
      var afterHeight = beforeWidth * Math.abs(Math.sin(rotateRadians)) + Math.abs(beforeHeight * Math.cos(rotateRadians));
      var rotatedRect = new BoundingRect(textRect.x, textRect.y, afterWidth, afterHeight);
      return rotatedRect;
    }
    /**
     * @param model axisLabelModel or axisTickModel
     * @return {number|String} Can be null|'auto'|number|function
     */


    function getOptionCategoryInterval(model) {
      var interval = model.get('interval');
      return interval == null ? 'auto' : interval;
    }
    /**
     * Set `categoryInterval` as 0 implicitly indicates that
     * show all labels regardless of overlap.
     * @param {Object} axis axisModel.axis
     */

    function shouldShowAllLabels(axis) {
      return axis.type === 'category' && getOptionCategoryInterval(axis.getLabelModel()) === 0;
    }
    function getDataDimensionsOnAxis(data, axisDim) {
      // Remove duplicated dat dimensions caused by `getStackedDimension`.
      var dataDimMap = {}; // Currently `mapDimensionsAll` will contain stack result dimension ('__\0ecstackresult').
      // PENDING: is it reasonable? Do we need to remove the original dim from "coord dim" since
      // there has been stacked result dim?

      each(data.mapDimensionsAll(axisDim), function (dataDim) {
        // For example, the extent of the original dimension
        // is [0.1, 0.5], the extent of the `stackResultDimension`
        // is [7, 9], the final extent should NOT include [0.1, 0.5],
        // because there is no graphic corresponding to [0.1, 0.5].
        // See the case in `test/area-stack.html` `main1`, where area line
        // stack needs `yAxis` not start from 0.
        dataDimMap[getStackedDimension(data, dataDim)] = true;
      });
      return keys(dataDimMap);
    }
    function unionAxisExtentFromData(dataExtent, data, axisDim) {
      if (data) {
        each(getDataDimensionsOnAxis(data, axisDim), function (dim) {
          var seriesExtent = data.getApproximateExtent(dim);
          seriesExtent[0] < dataExtent[0] && (dataExtent[0] = seriesExtent[0]);
          seriesExtent[1] > dataExtent[1] && (dataExtent[1] = seriesExtent[1]);
        });
      }
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    var AxisModelCommonMixin =
    /** @class */
    function () {
      function AxisModelCommonMixin() {}

      AxisModelCommonMixin.prototype.getNeedCrossZero = function () {
        var option = this.option;
        return !option.scale;
      };
      /**
       * Should be implemented by each axis model if necessary.
       * @return coordinate system model
       */


      AxisModelCommonMixin.prototype.getCoordSysModel = function () {
        return;
      };

      return AxisModelCommonMixin;
    }();

    /**
     * Create a multi dimension List structure from seriesModel.
     */

    function createList(seriesModel) {
      return createSeriesData(null, seriesModel);
    } // export function createGraph(seriesModel) {
    var dataStack$1 = {
      isDimensionStacked: isDimensionStacked,
      enableDataStack: enableDataStack,
      getStackedDimension: getStackedDimension
    };
    /**
     * Create scale
     * @param {Array.<number>} dataExtent
     * @param {Object|module:echarts/Model} option If `optoin.type`
     *        is secified, it can only be `'value'` currently.
     */

    function createScale(dataExtent, option) {
      var axisModel = option;

      if (!(option instanceof Model)) {
        axisModel = new Model(option); // FIXME
        // Currently AxisModelCommonMixin has nothing to do with the
        // the requirements of `axisHelper.createScaleByModel`. For
        // example the methods `getCategories` and `getOrdinalMeta`
        // are required for `'category'` axis, and ecModel is required
        // for `'time'` axis. But occasionally echarts-gl happened
        // to only use `'value'` axis.
        // zrUtil.mixin(axisModel, AxisModelCommonMixin);
      }

      var scale = createScaleByModel(axisModel);
      scale.setExtent(dataExtent[0], dataExtent[1]);
      niceScaleExtent(scale, axisModel);
      return scale;
    }
    /**
     * Mixin common methods to axis model,
     *
     * Include methods
     * `getFormattedLabels() => Array.<string>`
     * `getCategories() => Array.<string>`
     * `getMin(origin: boolean) => number`
     * `getMax(origin: boolean) => number`
     * `getNeedCrossZero() => boolean`
     */

    function mixinAxisModelCommonMethods(Model) {
      mixin(Model, AxisModelCommonMixin);
    }
    function createTextStyle$1(textStyleModel, opts) {
      opts = opts || {};
      return createTextStyle(textStyleModel, null, null, opts.state !== 'normal');
    }

    var helper = /*#__PURE__*/Object.freeze({
        __proto__: null,
        createList: createList,
        getLayoutRect: getLayoutRect,
        dataStack: dataStack$1,
        createScale: createScale,
        mixinAxisModelCommonMethods: mixinAxisModelCommonMethods,
        getECData: getECData,
        createTextStyle: createTextStyle$1,
        createDimensions: createDimensions,
        createSymbol: createSymbol,
        enableHoverEmphasis: enableHoverEmphasis
    });

    var EPSILON$4 = 1e-8;
    function isAroundEqual$1(a, b) {
        return Math.abs(a - b) < EPSILON$4;
    }
    function contain$2(points, x, y) {
        var w = 0;
        var p = points[0];
        if (!p) {
            return false;
        }
        for (var i = 1; i < points.length; i++) {
            var p2 = points[i];
            w += windingLine(p[0], p[1], p2[0], p2[1], x, y);
            p = p2;
        }
        var p0 = points[0];
        if (!isAroundEqual$1(p[0], p0[0]) || !isAroundEqual$1(p[1], p0[1])) {
            w += windingLine(p[0], p[1], p0[0], p0[1], x, y);
        }
        return w !== 0;
    }

    var TMP_TRANSFORM = [];

    function transformPoints(points, transform) {
      for (var p = 0; p < points.length; p++) {
        applyTransform(points[p], points[p], transform);
      }
    }

    function updateBBoxFromPoints(points, min$1, max$1, projection) {
      for (var i = 0; i < points.length; i++) {
        var p = points[i];

        if (projection) {
          // projection may return null point.
          p = projection.project(p);
        }

        if (p && isFinite(p[0]) && isFinite(p[1])) {
          min(min$1, min$1, p);
          max(max$1, max$1, p);
        }
      }
    }

    function centroid(points) {
      var signedArea = 0;
      var cx = 0;
      var cy = 0;
      var len = points.length;
      var x0 = points[len - 1][0];
      var y0 = points[len - 1][1]; // Polygon should been closed.

      for (var i = 0; i < len; i++) {
        var x1 = points[i][0];
        var y1 = points[i][1];
        var a = x0 * y1 - x1 * y0;
        signedArea += a;
        cx += (x0 + x1) * a;
        cy += (y0 + y1) * a;
        x0 = x1;
        y0 = y1;
      }

      return signedArea ? [cx / signedArea / 3, cy / signedArea / 3, signedArea] : [points[0][0] || 0, points[0][1] || 0];
    }

    var Region =
    /** @class */
    function () {
      function Region(name) {
        this.name = name;
      }

      Region.prototype.setCenter = function (center) {
        this._center = center;
      };
      /**
       * Get center point in data unit. That is,
       * for GeoJSONRegion, the unit is lat/lng,
       * for GeoSVGRegion, the unit is SVG local coord.
       */


      Region.prototype.getCenter = function () {
        var center = this._center;

        if (!center) {
          // In most cases there are no need to calculate this center.
          // So calculate only when called.
          center = this._center = this.calcCenter();
        }

        return center;
      };

      return Region;
    }();

    var GeoJSONPolygonGeometry =
    /** @class */
    function () {
      function GeoJSONPolygonGeometry(exterior, interiors) {
        this.type = 'polygon';
        this.exterior = exterior;
        this.interiors = interiors;
      }

      return GeoJSONPolygonGeometry;
    }();

    var GeoJSONLineStringGeometry =
    /** @class */
    function () {
      function GeoJSONLineStringGeometry(points) {
        this.type = 'linestring';
        this.points = points;
      }

      return GeoJSONLineStringGeometry;
    }();

    var GeoJSONRegion =
    /** @class */
    function (_super) {
      __extends(GeoJSONRegion, _super);

      function GeoJSONRegion(name, geometries, cp) {
        var _this = _super.call(this, name) || this;

        _this.type = 'geoJSON';
        _this.geometries = geometries;
        _this._center = cp && [cp[0], cp[1]];
        return _this;
      }

      GeoJSONRegion.prototype.calcCenter = function () {
        var geometries = this.geometries;
        var largestGeo;
        var largestGeoSize = 0;

        for (var i = 0; i < geometries.length; i++) {
          var geo = geometries[i];
          var exterior = geo.exterior; // Simple trick to use points count instead of polygon area as region size.
          // Ignore linestring

          var size = exterior && exterior.length;

          if (size > largestGeoSize) {
            largestGeo = geo;
            largestGeoSize = size;
          }
        }

        if (largestGeo) {
          return centroid(largestGeo.exterior);
        } // from bounding rect by default.


        var rect = this.getBoundingRect();
        return [rect.x + rect.width / 2, rect.y + rect.height / 2];
      };

      GeoJSONRegion.prototype.getBoundingRect = function (projection) {
        var rect = this._rect; // Always recalculate if using projection.

        if (rect && !projection) {
          return rect;
        }

        var min = [Infinity, Infinity];
        var max = [-Infinity, -Infinity];
        var geometries = this.geometries;
        each(geometries, function (geo) {
          if (geo.type === 'polygon') {
            // Doesn't consider hole
            updateBBoxFromPoints(geo.exterior, min, max, projection);
          } else {
            each(geo.points, function (points) {
              updateBBoxFromPoints(points, min, max, projection);
            });
          }
        }); // Normalie invalid bounding.

        if (!(isFinite(min[0]) && isFinite(min[1]) && isFinite(max[0]) && isFinite(max[1]))) {
          min[0] = min[1] = max[0] = max[1] = 0;
        }

        rect = new BoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]);

        if (!projection) {
          this._rect = rect;
        }

        return rect;
      };

      GeoJSONRegion.prototype.contain = function (coord) {
        var rect = this.getBoundingRect();
        var geometries = this.geometries;

        if (!rect.contain(coord[0], coord[1])) {
          return false;
        }

        loopGeo: for (var i = 0, len = geometries.length; i < len; i++) {
          var geo = geometries[i]; // Only support polygon.

          if (geo.type !== 'polygon') {
            continue;
          }

          var exterior = geo.exterior;
          var interiors = geo.interiors;

          if (contain$2(exterior, coord[0], coord[1])) {
            // Not in the region if point is in the hole.
            for (var k = 0; k < (interiors ? interiors.length : 0); k++) {
              if (contain$2(interiors[k], coord[0], coord[1])) {
                continue loopGeo;
              }
            }

            return true;
          }
        }

        return false;
      };
      /**
       * Transform the raw coords to target bounding.
       * @param x
       * @param y
       * @param width
       * @param height
       */


      GeoJSONRegion.prototype.transformTo = function (x, y, width, height) {
        var rect = this.getBoundingRect();
        var aspect = rect.width / rect.height;

        if (!width) {
          width = aspect * height;
        } else if (!height) {
          height = width / aspect;
        }

        var target = new BoundingRect(x, y, width, height);
        var transform = rect.calculateTransform(target);
        var geometries = this.geometries;

        for (var i = 0; i < geometries.length; i++) {
          var geo = geometries[i];

          if (geo.type === 'polygon') {
            transformPoints(geo.exterior, transform);
            each(geo.interiors, function (interior) {
              transformPoints(interior, transform);
            });
          } else {
            each(geo.points, function (points) {
              transformPoints(points, transform);
            });
          }
        }

        rect = this._rect;
        rect.copy(target); // Update center

        this._center = [rect.x + rect.width / 2, rect.y + rect.height / 2];
      };

      GeoJSONRegion.prototype.cloneShallow = function (name) {
        name == null && (name = this.name);
        var newRegion = new GeoJSONRegion(name, this.geometries, this._center);
        newRegion._rect = this._rect;
        newRegion.transformTo = null; // Simply avoid to be called.

        return newRegion;
      };

      return GeoJSONRegion;
    }(Region);

    var GeoSVGRegion =
    /** @class */
    function (_super) {
      __extends(GeoSVGRegion, _super);

      function GeoSVGRegion(name, elOnlyForCalculate) {
        var _this = _super.call(this, name) || this;

        _this.type = 'geoSVG';
        _this._elOnlyForCalculate = elOnlyForCalculate;
        return _this;
      }

      GeoSVGRegion.prototype.calcCenter = function () {
        var el = this._elOnlyForCalculate;
        var rect = el.getBoundingRect();
        var center = [rect.x + rect.width / 2, rect.y + rect.height / 2];
        var mat = identity(TMP_TRANSFORM);
        var target = el;

        while (target && !target.isGeoSVGGraphicRoot) {
          mul$1(mat, target.getLocalTransform(), mat);
          target = target.parent;
        }

        invert(mat, mat);
        applyTransform(center, center, mat);
        return center;
      };

      return GeoSVGRegion;
    }(Region);

    function decode(json) {
      if (!json.UTF8Encoding) {
        return json;
      }

      var jsonCompressed = json;
      var encodeScale = jsonCompressed.UTF8Scale;

      if (encodeScale == null) {
        encodeScale = 1024;
      }

      var features = jsonCompressed.features;
      each(features, function (feature) {
        var geometry = feature.geometry;
        var encodeOffsets = geometry.encodeOffsets;
        var coordinates = geometry.coordinates; // Geometry may be appeded manually in the script after json loaded.
        // In this case this geometry is usually not encoded.

        if (!encodeOffsets) {
          return;
        }

        switch (geometry.type) {
          case 'LineString':
            geometry.coordinates = decodeRing(coordinates, encodeOffsets, encodeScale);
            break;

          case 'Polygon':
            decodeRings(coordinates, encodeOffsets, encodeScale);
            break;

          case 'MultiLineString':
            decodeRings(coordinates, encodeOffsets, encodeScale);
            break;

          case 'MultiPolygon':
            each(coordinates, function (rings, idx) {
              return decodeRings(rings, encodeOffsets[idx], encodeScale);
            });
        }
      }); // Has been decoded

      jsonCompressed.UTF8Encoding = false;
      return jsonCompressed;
    }

    function decodeRings(rings, encodeOffsets, encodeScale) {
      for (var c = 0; c < rings.length; c++) {
        rings[c] = decodeRing(rings[c], encodeOffsets[c], encodeScale);
      }
    }

    function decodeRing(coordinate, encodeOffsets, encodeScale) {
      var result = [];
      var prevX = encodeOffsets[0];
      var prevY = encodeOffsets[1];

      for (var i = 0; i < coordinate.length; i += 2) {
        var x = coordinate.charCodeAt(i) - 64;
        var y = coordinate.charCodeAt(i + 1) - 64; // ZigZag decoding

        x = x >> 1 ^ -(x & 1);
        y = y >> 1 ^ -(y & 1); // Delta deocding

        x += prevX;
        y += prevY;
        prevX = x;
        prevY = y; // Dequantize

        result.push([x / encodeScale, y / encodeScale]);
      }

      return result;
    }

    function parseGeoJSON(geoJson, nameProperty) {
      geoJson = decode(geoJson);
      return map(filter(geoJson.features, function (featureObj) {
        // Output of mapshaper may have geometry null
        return featureObj.geometry && featureObj.properties && featureObj.geometry.coordinates.length > 0;
      }), function (featureObj) {
        var properties = featureObj.properties;
        var geo = featureObj.geometry;
        var geometries = [];

        switch (geo.type) {
          case 'Polygon':
            var coordinates = geo.coordinates; // According to the GeoJSON specification.
            // First must be exterior, and the rest are all interior(holes).

            geometries.push(new GeoJSONPolygonGeometry(coordinates[0], coordinates.slice(1)));
            break;

          case 'MultiPolygon':
            each(geo.coordinates, function (item) {
              if (item[0]) {
                geometries.push(new GeoJSONPolygonGeometry(item[0], item.slice(1)));
              }
            });
            break;

          case 'LineString':
            geometries.push(new GeoJSONLineStringGeometry([geo.coordinates]));
            break;

          case 'MultiLineString':
            geometries.push(new GeoJSONLineStringGeometry(geo.coordinates));
        }

        var region = new GeoJSONRegion(properties[nameProperty || 'name'], geometries, properties.cp);
        region.properties = properties;
        return region;
      });
    }

    var number = /*#__PURE__*/Object.freeze({
        __proto__: null,
        linearMap: linearMap,
        round: round,
        asc: asc,
        getPrecision: getPrecision,
        getPrecisionSafe: getPrecisionSafe,
        getPixelPrecision: getPixelPrecision,
        getPercentWithPrecision: getPercentWithPrecision,
        MAX_SAFE_INTEGER: MAX_SAFE_INTEGER,
        remRadian: remRadian,
        isRadianAroundZero: isRadianAroundZero,
        parseDate: parseDate,
        quantity: quantity,
        quantityExponent: quantityExponent,
        nice: nice,
        quantile: quantile,
        reformIntervals: reformIntervals,
        isNumeric: isNumeric,
        numericToNumber: numericToNumber
    });

    var time = /*#__PURE__*/Object.freeze({
        __proto__: null,
        parse: parseDate,
        format: format
    });

    var graphic$1 = /*#__PURE__*/Object.freeze({
        __proto__: null,
        extendShape: extendShape,
        extendPath: extendPath,
        makePath: makePath,
        makeImage: makeImage,
        mergePath: mergePath$1,
        resizePath: resizePath,
        createIcon: createIcon,
        updateProps: updateProps,
        initProps: initProps,
        getTransform: getTransform,
        clipPointsByRect: clipPointsByRect,
        clipRectByRect: clipRectByRect,
        registerShape: registerShape,
        getShapeClass: getShapeClass,
        Group: Group,
        Image: ZRImage,
        Text: ZRText,
        Circle: Circle,
        Ellipse: Ellipse,
        Sector: Sector,
        Ring: Ring,
        Polygon: Polygon,
        Polyline: Polyline,
        Rect: Rect,
        Line: Line,
        BezierCurve: BezierCurve,
        Arc: Arc,
        IncrementalDisplayable: IncrementalDisplayable,
        CompoundPath: CompoundPath,
        LinearGradient: LinearGradient,
        RadialGradient: RadialGradient,
        BoundingRect: BoundingRect
    });

    var format$1 = /*#__PURE__*/Object.freeze({
        __proto__: null,
        addCommas: addCommas,
        toCamelCase: toCamelCase,
        normalizeCssArray: normalizeCssArray$1,
        encodeHTML: encodeHTML,
        formatTpl: formatTpl,
        getTooltipMarker: getTooltipMarker,
        formatTime: formatTime,
        capitalFirst: capitalFirst,
        truncateText: truncateText,
        getTextRect: getTextRect
    });

    var util$1 = /*#__PURE__*/Object.freeze({
        __proto__: null,
        map: map,
        each: each,
        indexOf: indexOf,
        inherits: inherits,
        reduce: reduce,
        filter: filter,
        bind: bind,
        curry: curry,
        isArray: isArray,
        isString: isString,
        isObject: isObject,
        isFunction: isFunction,
        extend: extend,
        defaults: defaults,
        clone: clone,
        merge: merge
    });

    var inner$5 = makeInner();
    function createAxisLabels(axis) {
      // Only ordinal scale support tick interval
      return axis.type === 'category' ? makeCategoryLabels(axis) : makeRealNumberLabels(axis);
    }
    /**
     * @param {module:echats/coord/Axis} axis
     * @param {module:echarts/model/Model} tickModel For example, can be axisTick, splitLine, splitArea.
     * @return {Object} {
     *     ticks: Array.<number>
     *     tickCategoryInterval: number
     * }
     */

    function createAxisTicks(axis, tickModel) {
      // Only ordinal scale support tick interval
      return axis.type === 'category' ? makeCategoryTicks(axis, tickModel) : {
        ticks: map(axis.scale.getTicks(), function (tick) {
          return tick.value;
        })
      };
    }

    function makeCategoryLabels(axis) {
      var labelModel = axis.getLabelModel();
      var result = makeCategoryLabelsActually(axis, labelModel);
      return !labelModel.get('show') || axis.scale.isBlank() ? {
        labels: [],
        labelCategoryInterval: result.labelCategoryInterval
      } : result;
    }

    function makeCategoryLabelsActually(axis, labelModel) {
      var labelsCache = getListCache(axis, 'labels');
      var optionLabelInterval = getOptionCategoryInterval(labelModel);
      var result = listCacheGet(labelsCache, optionLabelInterval);

      if (result) {
        return result;
      }

      var labels;
      var numericLabelInterval;

      if (isFunction(optionLabelInterval)) {
        labels = makeLabelsByCustomizedCategoryInterval(axis, optionLabelInterval);
      } else {
        numericLabelInterval = optionLabelInterval === 'auto' ? makeAutoCategoryInterval(axis) : optionLabelInterval;
        labels = makeLabelsByNumericCategoryInterval(axis, numericLabelInterval);
      } // Cache to avoid calling interval function repeatedly.


      return listCacheSet(labelsCache, optionLabelInterval, {
        labels: labels,
        labelCategoryInterval: numericLabelInterval
      });
    }

    function makeCategoryTicks(axis, tickModel) {
      var ticksCache = getListCache(axis, 'ticks');
      var optionTickInterval = getOptionCategoryInterval(tickModel);
      var result = listCacheGet(ticksCache, optionTickInterval);

      if (result) {
        return result;
      }

      var ticks;
      var tickCategoryInterval; // Optimize for the case that large category data and no label displayed,
      // we should not return all ticks.

      if (!tickModel.get('show') || axis.scale.isBlank()) {
        ticks = [];
      }

      if (isFunction(optionTickInterval)) {
        ticks = makeLabelsByCustomizedCategoryInterval(axis, optionTickInterval, true);
      } // Always use label interval by default despite label show. Consider this
      // scenario, Use multiple grid with the xAxis sync, and only one xAxis shows
      // labels. `splitLine` and `axisTick` should be consistent in this case.
      else if (optionTickInterval === 'auto') {
          var labelsResult = makeCategoryLabelsActually(axis, axis.getLabelModel());
          tickCategoryInterval = labelsResult.labelCategoryInterval;
          ticks = map(labelsResult.labels, function (labelItem) {
            return labelItem.tickValue;
          });
        } else {
          tickCategoryInterval = optionTickInterval;
          ticks = makeLabelsByNumericCategoryInterval(axis, tickCategoryInterval, true);
        } // Cache to avoid calling interval function repeatedly.


      return listCacheSet(ticksCache, optionTickInterval, {
        ticks: ticks,
        tickCategoryInterval: tickCategoryInterval
      });
    }

    function makeRealNumberLabels(axis) {
      var ticks = axis.scale.getTicks();
      var labelFormatter = makeLabelFormatter(axis);
      return {
        labels: map(ticks, function (tick, idx) {
          return {
            level: tick.level,
            formattedLabel: labelFormatter(tick, idx),
            rawLabel: axis.scale.getLabel(tick),
            tickValue: tick.value
          };
        })
      };
    }

    function getListCache(axis, prop) {
      // Because key can be a function, and cache size always is small, we use array cache.
      return inner$5(axis)[prop] || (inner$5(axis)[prop] = []);
    }

    function listCacheGet(cache, key) {
      for (var i = 0; i < cache.length; i++) {
        if (cache[i].key === key) {
          return cache[i].value;
        }
      }
    }

    function listCacheSet(cache, key, value) {
      cache.push({
        key: key,
        value: value
      });
      return value;
    }

    function makeAutoCategoryInterval(axis) {
      var result = inner$5(axis).autoInterval;
      return result != null ? result : inner$5(axis).autoInterval = axis.calculateCategoryInterval();
    }
    /**
     * Calculate interval for category axis ticks and labels.
     * To get precise result, at least one of `getRotate` and `isHorizontal`
     * should be implemented in axis.
     */


    function calculateCategoryInterval(axis) {
      var params = fetchAutoCategoryIntervalCalculationParams(axis);
      var labelFormatter = makeLabelFormatter(axis);
      var rotation = (params.axisRotate - params.labelRotate) / 180 * Math.PI;
      var ordinalScale = axis.scale;
      var ordinalExtent = ordinalScale.getExtent(); // Providing this method is for optimization:
      // avoid generating a long array by `getTicks`
      // in large category data case.

      var tickCount = ordinalScale.count();

      if (ordinalExtent[1] - ordinalExtent[0] < 1) {
        return 0;
      }

      var step = 1; // Simple optimization. Empirical value: tick count should less than 40.

      if (tickCount > 40) {
        step = Math.max(1, Math.floor(tickCount / 40));
      }

      var tickValue = ordinalExtent[0];
      var unitSpan = axis.dataToCoord(tickValue + 1) - axis.dataToCoord(tickValue);
      var unitW = Math.abs(unitSpan * Math.cos(rotation));
      var unitH = Math.abs(unitSpan * Math.sin(rotation));
      var maxW = 0;
      var maxH = 0; // Caution: Performance sensitive for large category data.
      // Consider dataZoom, we should make appropriate step to avoid O(n) loop.

      for (; tickValue <= ordinalExtent[1]; tickValue += step) {
        var width = 0;
        var height = 0; // Not precise, do not consider align and vertical align
        // and each distance from axis line yet.

        var rect = getBoundingRect(labelFormatter({
          value: tickValue
        }), params.font, 'center', 'top'); // Magic number

        width = rect.width * 1.3;
        height = rect.height * 1.3; // Min size, void long loop.

        maxW = Math.max(maxW, width, 7);
        maxH = Math.max(maxH, height, 7);
      }

      var dw = maxW / unitW;
      var dh = maxH / unitH; // 0/0 is NaN, 1/0 is Infinity.

      isNaN(dw) && (dw = Infinity);
      isNaN(dh) && (dh = Infinity);
      var interval = Math.max(0, Math.floor(Math.min(dw, dh)));
      var cache = inner$5(axis.model);
      var axisExtent = axis.getExtent();
      var lastAutoInterval = cache.lastAutoInterval;
      var lastTickCount = cache.lastTickCount; // Use cache to keep interval stable while moving zoom window,
      // otherwise the calculated interval might jitter when the zoom
      // window size is close to the interval-changing size.
      // For example, if all of the axis labels are `a, b, c, d, e, f, g`.
      // The jitter will cause that sometimes the displayed labels are
      // `a, d, g` (interval: 2) sometimes `a, c, e`(interval: 1).

      if (lastAutoInterval != null && lastTickCount != null && Math.abs(lastAutoInterval - interval) <= 1 && Math.abs(lastTickCount - tickCount) <= 1 // Always choose the bigger one, otherwise the critical
      // point is not the same when zooming in or zooming out.
      && lastAutoInterval > interval // If the axis change is caused by chart resize, the cache should not
      // be used. Otherwise some hidden labels might not be shown again.
      && cache.axisExtent0 === axisExtent[0] && cache.axisExtent1 === axisExtent[1]) {
        interval = lastAutoInterval;
      } // Only update cache if cache not used, otherwise the
      // changing of interval is too insensitive.
      else {
          cache.lastTickCount = tickCount;
          cache.lastAutoInterval = interval;
          cache.axisExtent0 = axisExtent[0];
          cache.axisExtent1 = axisExtent[1];
        }

      return interval;
    }

    function fetchAutoCategoryIntervalCalculationParams(axis) {
      var labelModel = axis.getLabelModel();
      return {
        axisRotate: axis.getRotate ? axis.getRotate() : axis.isHorizontal && !axis.isHorizontal() ? 90 : 0,
        labelRotate: labelModel.get('rotate') || 0,
        font: labelModel.getFont()
      };
    }

    function makeLabelsByNumericCategoryInterval(axis, categoryInterval, onlyTick) {
      var labelFormatter = makeLabelFormatter(axis);
      var ordinalScale = axis.scale;
      var ordinalExtent = ordinalScale.getExtent();
      var labelModel = axis.getLabelModel();
      var result = []; // TODO: axisType: ordinalTime, pick the tick from each month/day/year/...

      var step = Math.max((categoryInterval || 0) + 1, 1);
      var startTick = ordinalExtent[0];
      var tickCount = ordinalScale.count(); // Calculate start tick based on zero if possible to keep label consistent
      // while zooming and moving while interval > 0. Otherwise the selection
      // of displayable ticks and symbols probably keep changing.
      // 3 is empirical value.

      if (startTick !== 0 && step > 1 && tickCount / step > 2) {
        startTick = Math.round(Math.ceil(startTick / step) * step);
      } // (1) Only add min max label here but leave overlap checking
      // to render stage, which also ensure the returned list
      // suitable for splitLine and splitArea rendering.
      // (2) Scales except category always contain min max label so
      // do not need to perform this process.


      var showAllLabel = shouldShowAllLabels(axis);
      var includeMinLabel = labelModel.get('showMinLabel') || showAllLabel;
      var includeMaxLabel = labelModel.get('showMaxLabel') || showAllLabel;

      if (includeMinLabel && startTick !== ordinalExtent[0]) {
        addItem(ordinalExtent[0]);
      } // Optimize: avoid generating large array by `ordinalScale.getTicks()`.


      var tickValue = startTick;

      for (; tickValue <= ordinalExtent[1]; tickValue += step) {
        addItem(tickValue);
      }

      if (includeMaxLabel && tickValue - step !== ordinalExtent[1]) {
        addItem(ordinalExtent[1]);
      }

      function addItem(tickValue) {
        var tickObj = {
          value: tickValue
        };
        result.push(onlyTick ? tickValue : {
          formattedLabel: labelFormatter(tickObj),
          rawLabel: ordinalScale.getLabel(tickObj),
          tickValue: tickValue
        });
      }

      return result;
    }

    function makeLabelsByCustomizedCategoryInterval(axis, categoryInterval, onlyTick) {
      var ordinalScale = axis.scale;
      var labelFormatter = makeLabelFormatter(axis);
      var result = [];
      each(ordinalScale.getTicks(), function (tick) {
        var rawLabel = ordinalScale.getLabel(tick);
        var tickValue = tick.value;

        if (categoryInterval(tick.value, rawLabel)) {
          result.push(onlyTick ? tickValue : {
            formattedLabel: labelFormatter(tick),
            rawLabel: rawLabel,
            tickValue: tickValue
          });
        }
      });
      return result;
    }

    var NORMALIZED_EXTENT = [0, 1];
    /**
     * Base class of Axis.
     */

    var Axis =
    /** @class */
    function () {
      function Axis(dim, scale, extent) {
        this.onBand = false;
        this.inverse = false;
        this.dim = dim;
        this.scale = scale;
        this._extent = extent || [0, 0];
      }
      /**
       * If axis extent contain given coord
       */


      Axis.prototype.contain = function (coord) {
        var extent = this._extent;
        var min = Math.min(extent[0], extent[1]);
        var max = Math.max(extent[0], extent[1]);
        return coord >= min && coord <= max;
      };
      /**
       * If axis extent contain given data
       */


      Axis.prototype.containData = function (data) {
        return this.scale.contain(data);
      };
      /**
       * Get coord extent.
       */


      Axis.prototype.getExtent = function () {
        return this._extent.slice();
      };
      /**
       * Get precision used for formatting
       */


      Axis.prototype.getPixelPrecision = function (dataExtent) {
        return getPixelPrecision(dataExtent || this.scale.getExtent(), this._extent);
      };
      /**
       * Set coord extent
       */


      Axis.prototype.setExtent = function (start, end) {
        var extent = this._extent;
        extent[0] = start;
        extent[1] = end;
      };
      /**
       * Convert data to coord. Data is the rank if it has an ordinal scale
       */


      Axis.prototype.dataToCoord = function (data, clamp) {
        var extent = this._extent;
        var scale = this.scale;
        data = scale.normalize(data);

        if (this.onBand && scale.type === 'ordinal') {
          extent = extent.slice();
          fixExtentWithBands(extent, scale.count());
        }

        return linearMap(data, NORMALIZED_EXTENT, extent, clamp);
      };
      /**
       * Convert coord to data. Data is the rank if it has an ordinal scale
       */


      Axis.prototype.coordToData = function (coord, clamp) {
        var extent = this._extent;
        var scale = this.scale;

        if (this.onBand && scale.type === 'ordinal') {
          extent = extent.slice();
          fixExtentWithBands(extent, scale.count());
        }

        var t = linearMap(coord, extent, NORMALIZED_EXTENT, clamp);
        return this.scale.scale(t);
      };
      /**
       * Convert pixel point to data in axis
       */


      Axis.prototype.pointToData = function (point, clamp) {
        // Should be implemented in derived class if necessary.
        return;
      };
      /**
       * Different from `zrUtil.map(axis.getTicks(), axis.dataToCoord, axis)`,
       * `axis.getTicksCoords` considers `onBand`, which is used by
       * `boundaryGap:true` of category axis and splitLine and splitArea.
       * @param opt.tickModel default: axis.model.getModel('axisTick')
       * @param opt.clamp If `true`, the first and the last
       *        tick must be at the axis end points. Otherwise, clip ticks
       *        that outside the axis extent.
       */


      Axis.prototype.getTicksCoords = function (opt) {
        opt = opt || {};
        var tickModel = opt.tickModel || this.getTickModel();
        var result = createAxisTicks(this, tickModel);
        var ticks = result.ticks;
        var ticksCoords = map(ticks, function (tickVal) {
          return {
            coord: this.dataToCoord(this.scale.type === 'ordinal' ? this.scale.getRawOrdinalNumber(tickVal) : tickVal),
            tickValue: tickVal
          };
        }, this);
        var alignWithLabel = tickModel.get('alignWithLabel');
        fixOnBandTicksCoords(this, ticksCoords, alignWithLabel, opt.clamp);
        return ticksCoords;
      };

      Axis.prototype.getMinorTicksCoords = function () {
        if (this.scale.type === 'ordinal') {
          // Category axis doesn't support minor ticks
          return [];
        }

        var minorTickModel = this.model.getModel('minorTick');
        var splitNumber = minorTickModel.get('splitNumber'); // Protection.

        if (!(splitNumber > 0 && splitNumber < 100)) {
          splitNumber = 5;
        }

        var minorTicks = this.scale.getMinorTicks(splitNumber);
        var minorTicksCoords = map(minorTicks, function (minorTicksGroup) {
          return map(minorTicksGroup, function (minorTick) {
            return {
              coord: this.dataToCoord(minorTick),
              tickValue: minorTick
            };
          }, this);
        }, this);
        return minorTicksCoords;
      };

      Axis.prototype.getViewLabels = function () {
        return createAxisLabels(this).labels;
      };

      Axis.prototype.getLabelModel = function () {
        return this.model.getModel('axisLabel');
      };
      /**
       * Notice here we only get the default tick model. For splitLine
       * or splitArea, we should pass the splitLineModel or splitAreaModel
       * manually when calling `getTicksCoords`.
       * In GL, this method may be overridden to:
       * `axisModel.getModel('axisTick', grid3DModel.getModel('axisTick'));`
       */


      Axis.prototype.getTickModel = function () {
        return this.model.getModel('axisTick');
      };
      /**
       * Get width of band
       */


      Axis.prototype.getBandWidth = function () {
        var axisExtent = this._extent;
        var dataExtent = this.scale.getExtent();
        var len = dataExtent[1] - dataExtent[0] + (this.onBand ? 1 : 0); // Fix #2728, avoid NaN when only one data.

        len === 0 && (len = 1);
        var size = Math.abs(axisExtent[1] - axisExtent[0]);
        return Math.abs(size) / len;
      };
      /**
       * Only be called in category axis.
       * Can be overridden, consider other axes like in 3D.
       * @return Auto interval for cateogry axis tick and label
       */


      Axis.prototype.calculateCategoryInterval = function () {
        return calculateCategoryInterval(this);
      };

      return Axis;
    }();

    function fixExtentWithBands(extent, nTick) {
      var size = extent[1] - extent[0];
      var len = nTick;
      var margin = size / len / 2;
      extent[0] += margin;
      extent[1] -= margin;
    } // If axis has labels [1, 2, 3, 4]. Bands on the axis are
    // |---1---|---2---|---3---|---4---|.
    // So the displayed ticks and splitLine/splitArea should between
    // each data item, otherwise cause misleading (e.g., split tow bars
    // of a single data item when there are two bar series).
    // Also consider if tickCategoryInterval > 0 and onBand, ticks and
    // splitLine/spliteArea should layout appropriately corresponding
    // to displayed labels. (So we should not use `getBandWidth` in this
    // case).


    function fixOnBandTicksCoords(axis, ticksCoords, alignWithLabel, clamp) {
      var ticksLen = ticksCoords.length;

      if (!axis.onBand || alignWithLabel || !ticksLen) {
        return;
      }

      var axisExtent = axis.getExtent();
      var last;
      var diffSize;

      if (ticksLen === 1) {
        ticksCoords[0].coord = axisExtent[0];
        last = ticksCoords[1] = {
          coord: axisExtent[0]
        };
      } else {
        var crossLen = ticksCoords[ticksLen - 1].tickValue - ticksCoords[0].tickValue;
        var shift_1 = (ticksCoords[ticksLen - 1].coord - ticksCoords[0].coord) / crossLen;
        each(ticksCoords, function (ticksItem) {
          ticksItem.coord -= shift_1 / 2;
        });
        var dataExtent = axis.scale.getExtent();
        diffSize = 1 + dataExtent[1] - ticksCoords[ticksLen - 1].tickValue;
        last = {
          coord: ticksCoords[ticksLen - 1].coord + shift_1 * diffSize
        };
        ticksCoords.push(last);
      }

      var inverse = axisExtent[0] > axisExtent[1]; // Handling clamp.

      if (littleThan(ticksCoords[0].coord, axisExtent[0])) {
        clamp ? ticksCoords[0].coord = axisExtent[0] : ticksCoords.shift();
      }

      if (clamp && littleThan(axisExtent[0], ticksCoords[0].coord)) {
        ticksCoords.unshift({
          coord: axisExtent[0]
        });
      }

      if (littleThan(axisExtent[1], last.coord)) {
        clamp ? last.coord = axisExtent[1] : ticksCoords.pop();
      }

      if (clamp && littleThan(last.coord, axisExtent[1])) {
        ticksCoords.push({
          coord: axisExtent[1]
        });
      }

      function littleThan(a, b) {
        // Avoid rounding error cause calculated tick coord different with extent.
        // It may cause an extra unnecessary tick added.
        a = round(a);
        b = round(b);
        return inverse ? a > b : a < b;
      }
    }

    // Should use `ComponentModel.extend` or `class XXXX extend ComponentModel` to create class.
    // Then use `registerComponentModel` in `install` parameter when `use` this extension. For example:
    // class Bar3DModel extends ComponentModel {}
    // export function install(registers) { registers.registerComponentModel(Bar3DModel); }
    // echarts.use(install);

    function extendComponentModel(proto) {
      var Model = ComponentModel.extend(proto);
      ComponentModel.registerClass(Model);
      return Model;
    }
    function extendComponentView(proto) {
      var View = ComponentView.extend(proto);
      ComponentView.registerClass(View);
      return View;
    }
    function extendSeriesModel(proto) {
      var Model = SeriesModel.extend(proto);
      SeriesModel.registerClass(Model);
      return Model;
    }
    function extendChartView(proto) {
      var View = ChartView.extend(proto);
      ChartView.registerClass(View);
      return View;
    }

    function projectPointToLine(x1, y1, x2, y2, x, y, out, limitToEnds) {
      var dx = x - x1;
      var dy = y - y1;
      var dx1 = x2 - x1;
      var dy1 = y2 - y1;
      var lineLen = Math.sqrt(dx1 * dx1 + dy1 * dy1);
      dx1 /= lineLen;
      dy1 /= lineLen; // dot product

      var projectedLen = dx * dx1 + dy * dy1;
      var t = projectedLen / lineLen;

      if (limitToEnds) {
        t = Math.min(Math.max(t, 0), 1);
      }

      t *= lineLen;
      var ox = out[0] = x1 + t * dx1;
      var oy = out[1] = y1 + t * dy1;
      return Math.sqrt((ox - x) * (ox - x) + (oy - y) * (oy - y));
    }


    var pt0 = new Point();
    var pt1 = new Point();
    var pt2 = new Point();
    var dir = new Point();
    var dir2 = new Point();

    var tmpArr = [];
    var tmpProjPoint = new Point();
    /**
     * Reduce the line segment attached to the label to limit the turn angle between two segments.
     * @param linePoints
     * @param minTurnAngle Radian of minimum turn angle. 0 - 180
     */

    function limitTurnAngle(linePoints, minTurnAngle) {
      if (!(minTurnAngle <= 180 && minTurnAngle > 0)) {
        return;
      }

      minTurnAngle = minTurnAngle / 180 * Math.PI; // The line points can be
      //      /pt1----pt2 (label)
      //     /
      // pt0/

      pt0.fromArray(linePoints[0]);
      pt1.fromArray(linePoints[1]);
      pt2.fromArray(linePoints[2]);
      Point.sub(dir, pt0, pt1);
      Point.sub(dir2, pt2, pt1);
      var len1 = dir.len();
      var len2 = dir2.len();

      if (len1 < 1e-3 || len2 < 1e-3) {
        return;
      }

      dir.scale(1 / len1);
      dir2.scale(1 / len2);
      var angleCos = dir.dot(dir2);
      var minTurnAngleCos = Math.cos(minTurnAngle);

      if (minTurnAngleCos < angleCos) {
        // Smaller than minTurnAngle
        // Calculate project point of pt0 on pt1-pt2
        var d = projectPointToLine(pt1.x, pt1.y, pt2.x, pt2.y, pt0.x, pt0.y, tmpArr, false);
        tmpProjPoint.fromArray(tmpArr); // Calculate new projected length with limited minTurnAngle and get the new connect point

        tmpProjPoint.scaleAndAdd(dir2, d / Math.tan(Math.PI - minTurnAngle)); // Limit the new calculated connect point between pt1 and pt2.

        var t = pt2.x !== pt1.x ? (tmpProjPoint.x - pt1.x) / (pt2.x - pt1.x) : (tmpProjPoint.y - pt1.y) / (pt2.y - pt1.y);

        if (isNaN(t)) {
          return;
        }

        if (t < 0) {
          Point.copy(tmpProjPoint, pt1);
        } else if (t > 1) {
          Point.copy(tmpProjPoint, pt2);
        }

        tmpProjPoint.toArray(linePoints[1]);
      }
    }
    /**
     * Limit the angle of line and the surface
     * @param maxSurfaceAngle Radian of minimum turn angle. 0 - 180. 0 is same direction to normal. 180 is opposite
     */

    function limitSurfaceAngle(linePoints, surfaceNormal, maxSurfaceAngle) {
      if (!(maxSurfaceAngle <= 180 && maxSurfaceAngle > 0)) {
        return;
      }

      maxSurfaceAngle = maxSurfaceAngle / 180 * Math.PI;
      pt0.fromArray(linePoints[0]);
      pt1.fromArray(linePoints[1]);
      pt2.fromArray(linePoints[2]);
      Point.sub(dir, pt1, pt0);
      Point.sub(dir2, pt2, pt1);
      var len1 = dir.len();
      var len2 = dir2.len();

      if (len1 < 1e-3 || len2 < 1e-3) {
        return;
      }

      dir.scale(1 / len1);
      dir2.scale(1 / len2);
      var angleCos = dir.dot(surfaceNormal);
      var maxSurfaceAngleCos = Math.cos(maxSurfaceAngle);

      if (angleCos < maxSurfaceAngleCos) {
        // Calculate project point of pt0 on pt1-pt2
        var d = projectPointToLine(pt1.x, pt1.y, pt2.x, pt2.y, pt0.x, pt0.y, tmpArr, false);
        tmpProjPoint.fromArray(tmpArr);
        var HALF_PI = Math.PI / 2;
        var angle2 = Math.acos(dir2.dot(surfaceNormal));
        var newAngle = HALF_PI + angle2 - maxSurfaceAngle;

        if (newAngle >= HALF_PI) {
          // parallel
          Point.copy(tmpProjPoint, pt2);
        } else {
          // Calculate new projected length with limited minTurnAngle and get the new connect point
          tmpProjPoint.scaleAndAdd(dir2, d / Math.tan(Math.PI / 2 - newAngle)); // Limit the new calculated connect point between pt1 and pt2.

          var t = pt2.x !== pt1.x ? (tmpProjPoint.x - pt1.x) / (pt2.x - pt1.x) : (tmpProjPoint.y - pt1.y) / (pt2.y - pt1.y);

          if (isNaN(t)) {
            return;
          }

          if (t < 0) {
            Point.copy(tmpProjPoint, pt1);
          } else if (t > 1) {
            Point.copy(tmpProjPoint, pt2);
          }
        }

        tmpProjPoint.toArray(linePoints[1]);
      }
    }

    function setLabelLineState(labelLine, ignore, stateName, stateModel) {
      var isNormal = stateName === 'normal';
      var stateObj = isNormal ? labelLine : labelLine.ensureState(stateName); // Make sure display.

      stateObj.ignore = ignore; // Set smooth

      var smooth = stateModel.get('smooth');

      if (smooth && smooth === true) {
        smooth = 0.3;
      }

      stateObj.shape = stateObj.shape || {};

      if (smooth > 0) {
        stateObj.shape.smooth = smooth;
      }

      var styleObj = stateModel.getModel('lineStyle').getLineStyle();
      isNormal ? labelLine.useStyle(styleObj) : stateObj.style = styleObj;
    }

    function buildLabelLinePath(path, shape) {
      var smooth = shape.smooth;
      var points = shape.points;

      if (!points) {
        return;
      }

      path.moveTo(points[0][0], points[0][1]);

      if (smooth > 0 && points.length >= 3) {
        var len1 = dist(points[0], points[1]);
        var len2 = dist(points[1], points[2]);

        if (!len1 || !len2) {
          path.lineTo(points[1][0], points[1][1]);
          path.lineTo(points[2][0], points[2][1]);
          return;
        }

        var moveLen = Math.min(len1, len2) * smooth;
        var midPoint0 = lerp([], points[1], points[0], moveLen / len1);
        var midPoint2 = lerp([], points[1], points[2], moveLen / len2);
        var midPoint1 = lerp([], midPoint0, midPoint2, 0.5);
        path.bezierCurveTo(midPoint0[0], midPoint0[1], midPoint0[0], midPoint0[1], midPoint1[0], midPoint1[1]);
        path.bezierCurveTo(midPoint2[0], midPoint2[1], midPoint2[0], midPoint2[1], points[2][0], points[2][1]);
      } else {
        for (var i = 1; i < points.length; i++) {
          path.lineTo(points[i][0], points[i][1]);
        }
      }
    }
    /**
     * Create a label line if necessary and set it's style.
     */


    function setLabelLineStyle(targetEl, statesModels, defaultStyle) {
      var labelLine = targetEl.getTextGuideLine();
      var label = targetEl.getTextContent();

      if (!label) {
        // Not show label line if there is no label.
        if (labelLine) {
          targetEl.removeTextGuideLine();
        }

        return;
      }

      var normalModel = statesModels.normal;
      var showNormal = normalModel.get('show');
      var labelIgnoreNormal = label.ignore;

      for (var i = 0; i < DISPLAY_STATES.length; i++) {
        var stateName = DISPLAY_STATES[i];
        var stateModel = statesModels[stateName];
        var isNormal = stateName === 'normal';

        if (stateModel) {
          var stateShow = stateModel.get('show');
          var isLabelIgnored = isNormal ? labelIgnoreNormal : retrieve2(label.states[stateName] && label.states[stateName].ignore, labelIgnoreNormal);

          if (isLabelIgnored // Not show when label is not shown in this state.
          || !retrieve2(stateShow, showNormal) // Use normal state by default if not set.
          ) {
              var stateObj = isNormal ? labelLine : labelLine && labelLine.states[stateName];

              if (stateObj) {
                stateObj.ignore = true;
              }

              continue;
            } // Create labelLine if not exists


          if (!labelLine) {
            labelLine = new Polyline();
            targetEl.setTextGuideLine(labelLine); // Reset state of normal because it's new created.
            // NOTE: NORMAL should always been the first!

            if (!isNormal && (labelIgnoreNormal || !showNormal)) {
              setLabelLineState(labelLine, true, 'normal', statesModels.normal);
            } // Use same state proxy.


            if (targetEl.stateProxy) {
              labelLine.stateProxy = targetEl.stateProxy;
            }
          }

          setLabelLineState(labelLine, false, stateName, stateModel);
        }
      }

      if (labelLine) {
        defaults(labelLine.style, defaultStyle); // Not fill.

        labelLine.style.fill = null;
        var showAbove = normalModel.get('showAbove');
        var labelLineConfig = targetEl.textGuideLineConfig = targetEl.textGuideLineConfig || {};
        labelLineConfig.showAbove = showAbove || false; // Custom the buildPath.

        labelLine.buildPath = buildLabelLinePath;
      }
    }
    function getLabelLineStatesModels(itemModel, labelLineName) {
      labelLineName = labelLineName || 'labelLine';
      var statesModels = {
        normal: itemModel.getModel(labelLineName)
      };

      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        var stateName = SPECIAL_STATES[i];
        statesModels[stateName] = itemModel.getModel([stateName, labelLineName]);
      }

      return statesModels;
    }

    function prepareLayoutList(input) {
      var list = [];

      for (var i = 0; i < input.length; i++) {
        var rawItem = input[i];

        if (rawItem.defaultAttr.ignore) {
          continue;
        }

        var label = rawItem.label;
        var transform = label.getComputedTransform(); // NOTE: Get bounding rect after getComputedTransform, or label may not been updated by the host el.

        var localRect = label.getBoundingRect();
        var isAxisAligned = !transform || transform[1] < 1e-5 && transform[2] < 1e-5;
        var minMargin = label.style.margin || 0;
        var globalRect = localRect.clone();
        globalRect.applyTransform(transform);
        globalRect.x -= minMargin / 2;
        globalRect.y -= minMargin / 2;
        globalRect.width += minMargin;
        globalRect.height += minMargin;
        var obb = isAxisAligned ? new OrientedBoundingRect(localRect, transform) : null;
        list.push({
          label: label,
          labelLine: rawItem.labelLine,
          rect: globalRect,
          localRect: localRect,
          obb: obb,
          priority: rawItem.priority,
          defaultAttr: rawItem.defaultAttr,
          layoutOption: rawItem.computedLayoutOption,
          axisAligned: isAxisAligned,
          transform: transform
        });
      }

      return list;
    }

    function shiftLayout(list, xyDim, sizeDim, minBound, maxBound, balanceShift) {
      var len = list.length;

      if (len < 2) {
        return;
      }

      list.sort(function (a, b) {
        return a.rect[xyDim] - b.rect[xyDim];
      });
      var lastPos = 0;
      var delta;
      var adjusted = false;
      var totalShifts = 0;

      for (var i = 0; i < len; i++) {
        var item = list[i];
        var rect = item.rect;
        delta = rect[xyDim] - lastPos;

        if (delta < 0) {
          // shiftForward(i, len, -delta);
          rect[xyDim] -= delta;
          item.label[xyDim] -= delta;
          adjusted = true;
        }

        var shift = Math.max(-delta, 0);
        totalShifts += shift;
        lastPos = rect[xyDim] + rect[sizeDim];
      }

      if (totalShifts > 0 && balanceShift) {
        // Shift back to make the distribution more equally.
        shiftList(-totalShifts / len, 0, len);
      } // TODO bleedMargin?


      var first = list[0];
      var last = list[len - 1];
      var minGap;
      var maxGap;
      updateMinMaxGap(); // If ends exceed two bounds, squeeze at most 80%, then take the gap of two bounds.

      minGap < 0 && squeezeGaps(-minGap, 0.8);
      maxGap < 0 && squeezeGaps(maxGap, 0.8);
      updateMinMaxGap();
      takeBoundsGap(minGap, maxGap, 1);
      takeBoundsGap(maxGap, minGap, -1); // Handle bailout when there is not enough space.

      updateMinMaxGap();

      if (minGap < 0) {
        squeezeWhenBailout(-minGap);
      }

      if (maxGap < 0) {
        squeezeWhenBailout(maxGap);
      }

      function updateMinMaxGap() {
        minGap = first.rect[xyDim] - minBound;
        maxGap = maxBound - last.rect[xyDim] - last.rect[sizeDim];
      }

      function takeBoundsGap(gapThisBound, gapOtherBound, moveDir) {
        if (gapThisBound < 0) {
          // Move from other gap if can.
          var moveFromMaxGap = Math.min(gapOtherBound, -gapThisBound);

          if (moveFromMaxGap > 0) {
            shiftList(moveFromMaxGap * moveDir, 0, len);
            var remained = moveFromMaxGap + gapThisBound;

            if (remained < 0) {
              squeezeGaps(-remained * moveDir, 1);
            }
          } else {
            squeezeGaps(-gapThisBound * moveDir, 1);
          }
        }
      }

      function shiftList(delta, start, end) {
        if (delta !== 0) {
          adjusted = true;
        }

        for (var i = start; i < end; i++) {
          var item = list[i];
          var rect = item.rect;
          rect[xyDim] += delta;
          item.label[xyDim] += delta;
        }
      } // Squeeze gaps if the labels exceed margin.


      function squeezeGaps(delta, maxSqeezePercent) {
        var gaps = [];
        var totalGaps = 0;

        for (var i = 1; i < len; i++) {
          var prevItemRect = list[i - 1].rect;
          var gap = Math.max(list[i].rect[xyDim] - prevItemRect[xyDim] - prevItemRect[sizeDim], 0);
          gaps.push(gap);
          totalGaps += gap;
        }

        if (!totalGaps) {
          return;
        }

        var squeezePercent = Math.min(Math.abs(delta) / totalGaps, maxSqeezePercent);

        if (delta > 0) {
          for (var i = 0; i < len - 1; i++) {
            // Distribute the shift delta to all gaps.
            var movement = gaps[i] * squeezePercent; // Forward

            shiftList(movement, 0, i + 1);
          }
        } else {
          // Backward
          for (var i = len - 1; i > 0; i--) {
            // Distribute the shift delta to all gaps.
            var movement = gaps[i - 1] * squeezePercent;
            shiftList(-movement, i, len);
          }
        }
      }
      /**
       * Squeeze to allow overlap if there is no more space available.
       * Let other overlapping strategy like hideOverlap do the job instead of keep exceeding the bounds.
       */


      function squeezeWhenBailout(delta) {
        var dir = delta < 0 ? -1 : 1;
        delta = Math.abs(delta);
        var moveForEachLabel = Math.ceil(delta / (len - 1));

        for (var i = 0; i < len - 1; i++) {
          if (dir > 0) {
            // Forward
            shiftList(moveForEachLabel, 0, i + 1);
          } else {
            // Backward
            shiftList(-moveForEachLabel, len - i - 1, len);
          }

          delta -= moveForEachLabel;

          if (delta <= 0) {
            return;
          }
        }
      }

      return adjusted;
    }
    /**
     * Adjust labels on y direction to avoid overlap.
     */

    function shiftLayoutOnY(list, topBound, bottomBound, // If average the shifts on all labels and add them to 0
    balanceShift) {
      return shiftLayout(list, 'y', 'height', topBound, bottomBound, balanceShift);
    }
    function hideOverlap(labelList) {
      var displayedLabels = []; // TODO, render overflow visible first, put in the displayedLabels.

      labelList.sort(function (a, b) {
        return b.priority - a.priority;
      });
      var globalRect = new BoundingRect(0, 0, 0, 0);

      function hideEl(el) {
        if (!el.ignore) {
          // Show on emphasis.
          var emphasisState = el.ensureState('emphasis');

          if (emphasisState.ignore == null) {
            emphasisState.ignore = false;
          }
        }

        el.ignore = true;
      }

      for (var i = 0; i < labelList.length; i++) {
        var labelItem = labelList[i];
        var isAxisAligned = labelItem.axisAligned;
        var localRect = labelItem.localRect;
        var transform = labelItem.transform;
        var label = labelItem.label;
        var labelLine = labelItem.labelLine;
        globalRect.copy(labelItem.rect); // Add a threshold because layout may be aligned precisely.

        globalRect.width -= 0.1;
        globalRect.height -= 0.1;
        globalRect.x += 0.05;
        globalRect.y += 0.05;
        var obb = labelItem.obb;
        var overlapped = false;

        for (var j = 0; j < displayedLabels.length; j++) {
          var existsTextCfg = displayedLabels[j]; // Fast rejection.

          if (!globalRect.intersect(existsTextCfg.rect)) {
            continue;
          }

          if (isAxisAligned && existsTextCfg.axisAligned) {
            // Is overlapped
            overlapped = true;
            break;
          }

          if (!existsTextCfg.obb) {
            // If self is not axis aligned. But other is.
            existsTextCfg.obb = new OrientedBoundingRect(existsTextCfg.localRect, existsTextCfg.transform);
          }

          if (!obb) {
            // If self is axis aligned. But other is not.
            obb = new OrientedBoundingRect(localRect, transform);
          }

          if (obb.intersect(existsTextCfg.obb)) {
            overlapped = true;
            break;
          }
        } // TODO Callback to determine if this overlap should be handled?


        if (overlapped) {
          hideEl(label);
          labelLine && hideEl(labelLine);
        } else {
          label.attr('ignore', labelItem.defaultAttr.ignore);
          labelLine && labelLine.attr('ignore', labelItem.defaultAttr.labelGuideIgnore);
          displayedLabels.push(labelItem);
        }
      }
    }

    var mathSin$4 = Math.sin;
    var mathCos$4 = Math.cos;
    var PI$4 = Math.PI;
    var PI2$6 = Math.PI * 2;
    var degree = 180 / PI$4;
    var SVGPathRebuilder = (function () {
        function SVGPathRebuilder() {
        }
        SVGPathRebuilder.prototype.reset = function (precision) {
            this._start = true;
            this._d = [];
            this._str = '';
            this._p = Math.pow(10, precision || 4);
        };
        SVGPathRebuilder.prototype.moveTo = function (x, y) {
            this._add('M', x, y);
        };
        SVGPathRebuilder.prototype.lineTo = function (x, y) {
            this._add('L', x, y);
        };
        SVGPathRebuilder.prototype.bezierCurveTo = function (x, y, x2, y2, x3, y3) {
            this._add('C', x, y, x2, y2, x3, y3);
        };
        SVGPathRebuilder.prototype.quadraticCurveTo = function (x, y, x2, y2) {
            this._add('Q', x, y, x2, y2);
        };
        SVGPathRebuilder.prototype.arc = function (cx, cy, r, startAngle, endAngle, anticlockwise) {
            this.ellipse(cx, cy, r, r, 0, startAngle, endAngle, anticlockwise);
        };
        SVGPathRebuilder.prototype.ellipse = function (cx, cy, rx, ry, psi, startAngle, endAngle, anticlockwise) {
            var dTheta = endAngle - startAngle;
            var clockwise = !anticlockwise;
            var dThetaPositive = Math.abs(dTheta);
            var isCircle = isAroundZero$1(dThetaPositive - PI2$6)
                || (clockwise ? dTheta >= PI2$6 : -dTheta >= PI2$6);
            var unifiedTheta = dTheta > 0 ? dTheta % PI2$6 : (dTheta % PI2$6 + PI2$6);
            var large = false;
            if (isCircle) {
                large = true;
            }
            else if (isAroundZero$1(dThetaPositive)) {
                large = false;
            }
            else {
                large = (unifiedTheta >= PI$4) === !!clockwise;
            }
            var x0 = cx + rx * mathCos$4(startAngle);
            var y0 = cy + ry * mathSin$4(startAngle);
            if (this._start) {
                this._add('M', x0, y0);
            }
            var xRot = Math.round(psi * degree);
            if (isCircle) {
                var p = 1 / this._p;
                var dTheta_1 = (clockwise ? 1 : -1) * (PI2$6 - p);
                this._add('A', rx, ry, xRot, 1, +clockwise, cx + rx * mathCos$4(startAngle + dTheta_1), cy + ry * mathSin$4(startAngle + dTheta_1));
                if (p > 1e-2) {
                    this._add('A', rx, ry, xRot, 0, +clockwise, x0, y0);
                }
            }
            else {
                var x = cx + rx * mathCos$4(endAngle);
                var y = cy + ry * mathSin$4(endAngle);
                this._add('A', rx, ry, xRot, +large, +clockwise, x, y);
            }
        };
        SVGPathRebuilder.prototype.rect = function (x, y, w, h) {
            this._add('M', x, y);
            this._add('l', w, 0);
            this._add('l', 0, h);
            this._add('l', -w, 0);
            this._add('Z');
        };
        SVGPathRebuilder.prototype.closePath = function () {
            if (this._d.length > 0) {
                this._add('Z');
            }
        };
        SVGPathRebuilder.prototype._add = function (cmd, a, b, c, d, e, f, g, h) {
            var vals = [];
            var p = this._p;
            for (var i = 1; i < arguments.length; i++) {
                var val = arguments[i];
                if (isNaN(val)) {
                    this._invalid = true;
                    return;
                }
                vals.push(Math.round(val * p) / p);
            }
            this._d.push(cmd + vals.join(' '));
            this._start = cmd === 'Z';
        };
        SVGPathRebuilder.prototype.generateStr = function () {
            this._str = this._invalid ? '' : this._d.join('');
            this._d = [];
        };
        SVGPathRebuilder.prototype.getStr = function () {
            return this._str;
        };
        return SVGPathRebuilder;
    }());

    var NONE = 'none';
    var mathRound$1 = Math.round;
    function pathHasFill(style) {
        var fill = style.fill;
        return fill != null && fill !== NONE;
    }
    function pathHasStroke(style) {
        var stroke = style.stroke;
        return stroke != null && stroke !== NONE;
    }
    var strokeProps = ['lineCap', 'miterLimit', 'lineJoin'];
    var svgStrokeProps = map(strokeProps, function (prop) { return "stroke-" + prop.toLowerCase(); });
    function mapStyleToAttrs(updateAttr, style, el, forceUpdate) {
        var opacity = style.opacity == null ? 1 : style.opacity;
        if (el instanceof ZRImage) {
            updateAttr('opacity', opacity);
            return;
        }
        if (pathHasFill(style)) {
            var fill = normalizeColor(style.fill);
            updateAttr('fill', fill.color);
            var fillOpacity = style.fillOpacity != null
                ? style.fillOpacity * fill.opacity * opacity
                : fill.opacity * opacity;
            if (forceUpdate || fillOpacity < 1) {
                updateAttr('fill-opacity', fillOpacity);
            }
        }
        else {
            updateAttr('fill', NONE);
        }
        if (pathHasStroke(style)) {
            var stroke = normalizeColor(style.stroke);
            updateAttr('stroke', stroke.color);
            var strokeScale = style.strokeNoScale
                ? el.getLineScale()
                : 1;
            var strokeWidth = (strokeScale ? (style.lineWidth || 0) / strokeScale : 0);
            var strokeOpacity = style.strokeOpacity != null
                ? style.strokeOpacity * stroke.opacity * opacity
                : stroke.opacity * opacity;
            var strokeFirst = style.strokeFirst;
            if (forceUpdate || strokeWidth !== 1) {
                updateAttr('stroke-width', strokeWidth);
            }
            if (forceUpdate || strokeFirst) {
                updateAttr('paint-order', strokeFirst ? 'stroke' : 'fill');
            }
            if (forceUpdate || strokeOpacity < 1) {
                updateAttr('stroke-opacity', strokeOpacity);
            }
            if (style.lineDash) {
                var _a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1];
                if (lineDash) {
                    lineDashOffset = mathRound$1(lineDashOffset || 0);
                    updateAttr('stroke-dasharray', lineDash.join(','));
                    if (lineDashOffset || forceUpdate) {
                        updateAttr('stroke-dashoffset', lineDashOffset);
                    }
                }
            }
            else if (forceUpdate) {
                updateAttr('stroke-dasharray', NONE);
            }
            for (var i = 0; i < strokeProps.length; i++) {
                var propName = strokeProps[i];
                if (forceUpdate || style[propName] !== DEFAULT_PATH_STYLE[propName]) {
                    var val = style[propName] || DEFAULT_PATH_STYLE[propName];
                    val && updateAttr(svgStrokeProps[i], val);
                }
            }
        }
        else if (forceUpdate) {
            updateAttr('stroke', NONE);
        }
    }

    var SVGNS = 'http://www.w3.org/2000/svg';
    var XLINKNS = 'http://www.w3.org/1999/xlink';
    var XMLNS = 'http://www.w3.org/2000/xmlns/';
    var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
    function createElement(name) {
        return document.createElementNS(SVGNS, name);
    }
    function createVNode(tag, key, attrs, children, text) {
        return {
            tag: tag,
            attrs: attrs || {},
            children: children,
            text: text,
            key: key
        };
    }
    function createElementOpen(name, attrs) {
        var attrsStr = [];
        if (attrs) {
            for (var key in attrs) {
                var val = attrs[key];
                var part = key;
                if (val === false) {
                    continue;
                }
                else if (val !== true && val != null) {
                    part += "=\"" + val + "\"";
                }
                attrsStr.push(part);
            }
        }
        return "<" + name + " " + attrsStr.join(' ') + ">";
    }
    function createElementClose(name) {
        return "</" + name + ">";
    }
    function vNodeToString(el, opts) {
        opts = opts || {};
        var S = opts.newline ? '\n' : '';
        function convertElToString(el) {
            var children = el.children, tag = el.tag, attrs = el.attrs;
            return createElementOpen(tag, attrs)
                + encodeHTML(el.text)
                + (children ? "" + S + map(children, function (child) { return convertElToString(child); }).join(S) + S : '')
                + createElementClose(tag);
        }
        return convertElToString(el);
    }
    function getCssString(selectorNodes, animationNodes, opts) {
        opts = opts || {};
        var S = opts.newline ? '\n' : '';
        var bracketBegin = " {" + S;
        var bracketEnd = S + "}";
        var selectors = map(keys(selectorNodes), function (className) {
            return className + bracketBegin + map(keys(selectorNodes[className]), function (attrName) {
                return attrName + ":" + selectorNodes[className][attrName] + ";";
            }).join(S) + bracketEnd;
        }).join(S);
        var animations = map(keys(animationNodes), function (animationName) {
            return "@keyframes " + animationName + bracketBegin + map(keys(animationNodes[animationName]), function (percent) {
                return percent + bracketBegin + map(keys(animationNodes[animationName][percent]), function (attrName) {
                    var val = animationNodes[animationName][percent][attrName];
                    if (attrName === 'd') {
                        val = "path(\"" + val + "\")";
                    }
                    return attrName + ":" + val + ";";
                }).join(S) + bracketEnd;
            }).join(S) + bracketEnd;
        }).join(S);
        if (!selectors && !animations) {
            return '';
        }
        return ['<![CDATA[', selectors, animations, ']]>'].join(S);
    }
    function createBrushScope(zrId) {
        return {
            zrId: zrId,
            shadowCache: {},
            patternCache: {},
            gradientCache: {},
            clipPathCache: {},
            defs: {},
            cssNodes: {},
            cssAnims: {},
            cssClassIdx: 0,
            cssAnimIdx: 0,
            shadowIdx: 0,
            gradientIdx: 0,
            patternIdx: 0,
            clipPathIdx: 0
        };
    }
    function createSVGVNode(width, height, children, useViewBox) {
        return createVNode('svg', 'root', {
            'width': width,
            'height': height,
            'xmlns': SVGNS,
            'xmlns:xlink': XLINKNS,
            'version': '1.1',
            'baseProfile': 'full',
            'viewBox': useViewBox ? "0 0 " + width + " " + height : false
        }, children);
    }

    var EASING_MAP = {
        cubicIn: '0.32,0,0.67,0',
        cubicOut: '0.33,1,0.68,1',
        cubicInOut: '0.65,0,0.35,1',
        quadraticIn: '0.11,0,0.5,0',
        quadraticOut: '0.5,1,0.89,1',
        quadraticInOut: '0.45,0,0.55,1',
        quarticIn: '0.5,0,0.75,0',
        quarticOut: '0.25,1,0.5,1',
        quarticInOut: '0.76,0,0.24,1',
        quinticIn: '0.64,0,0.78,0',
        quinticOut: '0.22,1,0.36,1',
        quinticInOut: '0.83,0,0.17,1',
        sinusoidalIn: '0.12,0,0.39,0',
        sinusoidalOut: '0.61,1,0.88,1',
        sinusoidalInOut: '0.37,0,0.63,1',
        exponentialIn: '0.7,0,0.84,0',
        exponentialOut: '0.16,1,0.3,1',
        exponentialInOut: '0.87,0,0.13,1',
        circularIn: '0.55,0,1,0.45',
        circularOut: '0,0.55,0.45,1',
        circularInOut: '0.85,0,0.15,1'
    };
    var transformOriginKey = 'transform-origin';
    function buildPathString(el, kfShape, path) {
        var shape = extend({}, el.shape);
        extend(shape, kfShape);
        el.buildPath(path, shape);
        var svgPathBuilder = new SVGPathRebuilder();
        svgPathBuilder.reset(getPathPrecision(el));
        path.rebuildPath(svgPathBuilder, 1);
        svgPathBuilder.generateStr();
        return svgPathBuilder.getStr();
    }
    function setTransformOrigin(target, transform) {
        var originX = transform.originX, originY = transform.originY;
        if (originX || originY) {
            target[transformOriginKey] = originX + "px " + originY + "px";
        }
    }
    var ANIMATE_STYLE_MAP = {
        fill: 'fill',
        opacity: 'opacity',
        lineWidth: 'stroke-width',
        lineDashOffset: 'stroke-dashoffset'
    };
    function addAnimation(cssAnim, scope) {
        var animationName = scope.zrId + '-ani-' + scope.cssAnimIdx++;
        scope.cssAnims[animationName] = cssAnim;
        return animationName;
    }
    function createCompoundPathCSSAnimation(el, attrs, scope) {
        var paths = el.shape.paths;
        var composedAnim = {};
        var cssAnimationCfg;
        var cssAnimationName;
        each(paths, function (path) {
            var subScope = createBrushScope(scope.zrId);
            subScope.animation = true;
            createCSSAnimation(path, {}, subScope, true);
            var cssAnims = subScope.cssAnims;
            var cssNodes = subScope.cssNodes;
            var animNames = keys(cssAnims);
            var len = animNames.length;
            if (!len) {
                return;
            }
            cssAnimationName = animNames[len - 1];
            var lastAnim = cssAnims[cssAnimationName];
            for (var percent in lastAnim) {
                var kf = lastAnim[percent];
                composedAnim[percent] = composedAnim[percent] || { d: '' };
                composedAnim[percent].d += kf.d || '';
            }
            for (var className in cssNodes) {
                var val = cssNodes[className].animation;
                if (val.indexOf(cssAnimationName) >= 0) {
                    cssAnimationCfg = val;
                }
            }
        });
        if (!cssAnimationCfg) {
            return;
        }
        attrs.d = false;
        var animationName = addAnimation(composedAnim, scope);
        return cssAnimationCfg.replace(cssAnimationName, animationName);
    }
    function getEasingFunc(easing) {
        return isString(easing)
            ? EASING_MAP[easing]
                ? "cubic-bezier(" + EASING_MAP[easing] + ")"
                : createCubicEasingFunc(easing) ? easing : ''
            : '';
    }
    function createCSSAnimation(el, attrs, scope, onlyShape) {
        var animators = el.animators;
        var len = animators.length;
        var cssAnimations = [];
        if (el instanceof CompoundPath) {
            var animationCfg = createCompoundPathCSSAnimation(el, attrs, scope);
            if (animationCfg) {
                cssAnimations.push(animationCfg);
            }
            else if (!len) {
                return;
            }
        }
        else if (!len) {
            return;
        }
        var groupAnimators = {};
        for (var i = 0; i < len; i++) {
            var animator = animators[i];
            var cfgArr = [animator.getMaxTime() / 1000 + 's'];
            var easing = getEasingFunc(animator.getClip().easing);
            var delay = animator.getDelay();
            if (easing) {
                cfgArr.push(easing);
            }
            else {
                cfgArr.push('linear');
            }
            if (delay) {
                cfgArr.push(delay / 1000 + 's');
            }
            if (animator.getLoop()) {
                cfgArr.push('infinite');
            }
            var cfg = cfgArr.join(' ');
            groupAnimators[cfg] = groupAnimators[cfg] || [cfg, []];
            groupAnimators[cfg][1].push(animator);
        }
        function createSingleCSSAnimation(groupAnimator) {
            var animators = groupAnimator[1];
            var len = animators.length;
            var transformKfs = {};
            var shapeKfs = {};
            var finalKfs = {};
            var animationTimingFunctionAttrName = 'animation-timing-function';
            function saveAnimatorTrackToCssKfs(animator, cssKfs, toCssAttrName) {
                var tracks = animator.getTracks();
                var maxTime = animator.getMaxTime();
                for (var k = 0; k < tracks.length; k++) {
                    var track = tracks[k];
                    if (track.needsAnimate()) {
                        var kfs = track.keyframes;
                        var attrName = track.propName;
                        toCssAttrName && (attrName = toCssAttrName(attrName));
                        if (attrName) {
                            for (var i = 0; i < kfs.length; i++) {
                                var kf = kfs[i];
                                var percent = Math.round(kf.time / maxTime * 100) + '%';
                                var kfEasing = getEasingFunc(kf.easing);
                                var rawValue = kf.rawValue;
                                if (isString(rawValue) || isNumber(rawValue)) {
                                    cssKfs[percent] = cssKfs[percent] || {};
                                    cssKfs[percent][attrName] = kf.rawValue;
                                    if (kfEasing) {
                                        cssKfs[percent][animationTimingFunctionAttrName] = kfEasing;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            for (var i = 0; i < len; i++) {
                var animator = animators[i];
                var targetProp = animator.targetName;
                if (!targetProp) {
                    !onlyShape && saveAnimatorTrackToCssKfs(animator, transformKfs);
                }
                else if (targetProp === 'shape') {
                    saveAnimatorTrackToCssKfs(animator, shapeKfs);
                }
            }
            for (var percent in transformKfs) {
                var transform = {};
                copyTransform(transform, el);
                extend(transform, transformKfs[percent]);
                var str = getSRTTransformString(transform);
                var timingFunction = transformKfs[percent][animationTimingFunctionAttrName];
                finalKfs[percent] = str ? {
                    transform: str
                } : {};
                setTransformOrigin(finalKfs[percent], transform);
                if (timingFunction) {
                    finalKfs[percent][animationTimingFunctionAttrName] = timingFunction;
                }
            }
            var path;
            var canAnimateShape = true;
            for (var percent in shapeKfs) {
                finalKfs[percent] = finalKfs[percent] || {};
                var isFirst = !path;
                var timingFunction = shapeKfs[percent][animationTimingFunctionAttrName];
                if (isFirst) {
                    path = new PathProxy();
                }
                var len_1 = path.len();
                path.reset();
                finalKfs[percent].d = buildPathString(el, shapeKfs[percent], path);
                var newLen = path.len();
                if (!isFirst && len_1 !== newLen) {
                    canAnimateShape = false;
                    break;
                }
                if (timingFunction) {
                    finalKfs[percent][animationTimingFunctionAttrName] = timingFunction;
                }
            }
            if (!canAnimateShape) {
                for (var percent in finalKfs) {
                    delete finalKfs[percent].d;
                }
            }
            if (!onlyShape) {
                for (var i = 0; i < len; i++) {
                    var animator = animators[i];
                    var targetProp = animator.targetName;
                    if (targetProp === 'style') {
                        saveAnimatorTrackToCssKfs(animator, finalKfs, function (propName) { return ANIMATE_STYLE_MAP[propName]; });
                    }
                }
            }
            var percents = keys(finalKfs);
            var allTransformOriginSame = true;
            var transformOrigin;
            for (var i = 1; i < percents.length; i++) {
                var p0 = percents[i - 1];
                var p1 = percents[i];
                if (finalKfs[p0][transformOriginKey] !== finalKfs[p1][transformOriginKey]) {
                    allTransformOriginSame = false;
                    break;
                }
                transformOrigin = finalKfs[p0][transformOriginKey];
            }
            if (allTransformOriginSame && transformOrigin) {
                for (var percent in finalKfs) {
                    if (finalKfs[percent][transformOriginKey]) {
                        delete finalKfs[percent][transformOriginKey];
                    }
                }
                attrs[transformOriginKey] = transformOrigin;
            }
            if (filter(percents, function (percent) { return keys(finalKfs[percent]).length > 0; }).length) {
                var animationName = addAnimation(finalKfs, scope);
                return animationName + " " + groupAnimator[0] + " both";
            }
        }
        for (var key in groupAnimators) {
            var animationCfg = createSingleCSSAnimation(groupAnimators[key]);
            if (animationCfg) {
                cssAnimations.push(animationCfg);
            }
        }
        if (cssAnimations.length) {
            var className = scope.zrId + '-cls-' + scope.cssClassIdx++;
            scope.cssNodes['.' + className] = {
                animation: cssAnimations.join(',')
            };
            attrs["class"] = className;
        }
    }

    var round$2 = Math.round;
    function isImageLike$1(val) {
        return val && isString(val.src);
    }
    function isCanvasLike(val) {
        return val && isFunction(val.toDataURL);
    }
    function setStyleAttrs(attrs, style, el, scope) {
        mapStyleToAttrs(function (key, val) {
            var isFillStroke = key === 'fill' || key === 'stroke';
            if (isFillStroke && isGradient(val)) {
                setGradient(style, attrs, key, scope);
            }
            else if (isFillStroke && isPattern(val)) {
                setPattern(el, attrs, key, scope);
            }
            else {
                attrs[key] = val;
            }
        }, style, el, false);
        setShadow(el, attrs, scope);
    }
    function noRotateScale(m) {
        return isAroundZero$1(m[0] - 1)
            && isAroundZero$1(m[1])
            && isAroundZero$1(m[2])
            && isAroundZero$1(m[3] - 1);
    }
    function noTranslate(m) {
        return isAroundZero$1(m[4]) && isAroundZero$1(m[5]);
    }
    function setTransform(attrs, m, compress) {
        if (m && !(noTranslate(m) && noRotateScale(m))) {
            var mul = compress ? 10 : 1e4;
            attrs.transform = noRotateScale(m)
                ? "translate(" + round$2(m[4] * mul) / mul + " " + round$2(m[5] * mul) / mul + ")" : getMatrixStr(m);
        }
    }
    function convertPolyShape(shape, attrs, mul) {
        var points = shape.points;
        var strArr = [];
        for (var i = 0; i < points.length; i++) {
            strArr.push(round$2(points[i][0] * mul) / mul);
            strArr.push(round$2(points[i][1] * mul) / mul);
        }
        attrs.points = strArr.join(' ');
    }
    function validatePolyShape(shape) {
        return !shape.smooth;
    }
    function createAttrsConvert(desc) {
        var normalizedDesc = map(desc, function (item) {
            return (typeof item === 'string' ? [item, item] : item);
        });
        return function (shape, attrs, mul) {
            for (var i = 0; i < normalizedDesc.length; i++) {
                var item = normalizedDesc[i];
                var val = shape[item[0]];
                if (val != null) {
                    attrs[item[1]] = round$2(val * mul) / mul;
                }
            }
        };
    }
    var builtinShapesDef = {
        circle: [createAttrsConvert(['cx', 'cy', 'r'])],
        polyline: [convertPolyShape, validatePolyShape],
        polygon: [convertPolyShape, validatePolyShape]
    };
    function hasShapeAnimation(el) {
        var animators = el.animators;
        for (var i = 0; i < animators.length; i++) {
            if (animators[i].targetName === 'shape') {
                return true;
            }
        }
        return false;
    }
    function brushSVGPath(el, scope) {
        var style = el.style;
        var shape = el.shape;
        var builtinShpDef = builtinShapesDef[el.type];
        var attrs = {};
        var needsAnimate = scope.animation;
        var svgElType = 'path';
        var strokePercent = el.style.strokePercent;
        var precision = (scope.compress && getPathPrecision(el)) || 4;
        if (builtinShpDef
            && !scope.willUpdate
            && !(builtinShpDef[1] && !builtinShpDef[1](shape))
            && !(needsAnimate && hasShapeAnimation(el))
            && !(strokePercent < 1)) {
            svgElType = el.type;
            var mul = Math.pow(10, precision);
            builtinShpDef[0](shape, attrs, mul);
        }
        else {
            if (!el.path) {
                el.createPathProxy();
            }
            var path = el.path;
            if (el.shapeChanged()) {
                path.beginPath();
                el.buildPath(path, el.shape);
                el.pathUpdated();
            }
            var pathVersion = path.getVersion();
            var elExt = el;
            var svgPathBuilder = elExt.__svgPathBuilder;
            if (elExt.__svgPathVersion !== pathVersion
                || !svgPathBuilder
                || strokePercent !== elExt.__svgPathStrokePercent) {
                if (!svgPathBuilder) {
                    svgPathBuilder = elExt.__svgPathBuilder = new SVGPathRebuilder();
                }
                svgPathBuilder.reset(precision);
                path.rebuildPath(svgPathBuilder, strokePercent);
                svgPathBuilder.generateStr();
                elExt.__svgPathVersion = pathVersion;
                elExt.__svgPathStrokePercent = strokePercent;
            }
            attrs.d = svgPathBuilder.getStr();
        }
        setTransform(attrs, el.transform);
        setStyleAttrs(attrs, style, el, scope);
        scope.animation && createCSSAnimation(el, attrs, scope);
        return createVNode(svgElType, el.id + '', attrs);
    }
    function brushSVGImage(el, scope) {
        var style = el.style;
        var image = style.image;
        if (image && !isString(image)) {
            if (isImageLike$1(image)) {
                image = image.src;
            }
            else if (isCanvasLike(image)) {
                image = image.toDataURL();
            }
        }
        if (!image) {
            return;
        }
        var x = style.x || 0;
        var y = style.y || 0;
        var dw = style.width;
        var dh = style.height;
        var attrs = {
            href: image,
            width: dw,
            height: dh
        };
        if (x) {
            attrs.x = x;
        }
        if (y) {
            attrs.y = y;
        }
        setTransform(attrs, el.transform);
        setStyleAttrs(attrs, style, el, scope);
        scope.animation && createCSSAnimation(el, attrs, scope);
        return createVNode('image', el.id + '', attrs);
    }
    function brushSVGTSpan(el, scope) {
        var style = el.style;
        var text = style.text;
        text != null && (text += '');
        if (!text || isNaN(style.x) || isNaN(style.y)) {
            return;
        }
        var font = style.font || DEFAULT_FONT;
        var x = style.x || 0;
        var y = adjustTextY(style.y || 0, getLineHeight(font), style.textBaseline);
        var textAlign = TEXT_ALIGN_TO_ANCHOR[style.textAlign]
            || style.textAlign;
        var attrs = {
            'dominant-baseline': 'central',
            'text-anchor': textAlign
        };
        if (hasSeparateFont(style)) {
            var separatedFontStr = '';
            var fontStyle = style.fontStyle;
            var fontSize = parseFontSize(style.fontSize);
            if (!parseFloat(fontSize)) {
                return;
            }
            var fontFamily = style.fontFamily || DEFAULT_FONT_FAMILY;
            var fontWeight = style.fontWeight;
            separatedFontStr += "font-size:" + fontSize + ";font-family:" + fontFamily + ";";
            if (fontStyle && fontStyle !== 'normal') {
                separatedFontStr += "font-style:" + fontStyle + ";";
            }
            if (fontWeight && fontWeight !== 'normal') {
                separatedFontStr += "font-weight:" + fontWeight + ";";
            }
            attrs.style = separatedFontStr;
        }
        else {
            attrs.style = "font: " + font;
        }
        if (text.match(/\s/)) {
            attrs['xml:space'] = 'preserve';
        }
        if (x) {
            attrs.x = x;
        }
        if (y) {
            attrs.y = y;
        }
        setTransform(attrs, el.transform);
        setStyleAttrs(attrs, style, el, scope);
        scope.animation && createCSSAnimation(el, attrs, scope);
        return createVNode('text', el.id + '', attrs, undefined, text);
    }
    function brush$1(el, scope) {
        if (el instanceof Path) {
            return brushSVGPath(el, scope);
        }
        else if (el instanceof ZRImage) {
            return brushSVGImage(el, scope);
        }
        else if (el instanceof TSpan) {
            return brushSVGTSpan(el, scope);
        }
    }
    function setShadow(el, attrs, scope) {
        var style = el.style;
        if (hasShadow(style)) {
            var shadowKey = getShadowKey(el);
            var shadowCache = scope.shadowCache;
            var shadowId = shadowCache[shadowKey];
            if (!shadowId) {
                var globalScale = el.getGlobalScale();
                var scaleX = globalScale[0];
                var scaleY = globalScale[1];
                if (!scaleX || !scaleY) {
                    return;
                }
                var offsetX = style.shadowOffsetX || 0;
                var offsetY = style.shadowOffsetY || 0;
                var blur_1 = style.shadowBlur;
                var _a = normalizeColor(style.shadowColor), opacity = _a.opacity, color = _a.color;
                var stdDx = blur_1 / 2 / scaleX;
                var stdDy = blur_1 / 2 / scaleY;
                var stdDeviation = stdDx + ' ' + stdDy;
                shadowId = scope.zrId + '-s' + scope.shadowIdx++;
                scope.defs[shadowId] = createVNode('filter', shadowId, {
                    'id': shadowId,
                    'x': '-100%',
                    'y': '-100%',
                    'width': '300%',
                    'height': '300%'
                }, [
                    createVNode('feDropShadow', '', {
                        'dx': offsetX / scaleX,
                        'dy': offsetY / scaleY,
                        'stdDeviation': stdDeviation,
                        'flood-color': color,
                        'flood-opacity': opacity
                    })
                ]);
                shadowCache[shadowKey] = shadowId;
            }
            attrs.filter = getIdURL(shadowId);
        }
    }
    function setGradient(style, attrs, target, scope) {
        var val = style[target];
        var gradientTag;
        var gradientAttrs = {
            'gradientUnits': val.global
                ? 'userSpaceOnUse'
                : 'objectBoundingBox'
        };
        if (isLinearGradient(val)) {
            gradientTag = 'linearGradient';
            gradientAttrs.x1 = val.x;
            gradientAttrs.y1 = val.y;
            gradientAttrs.x2 = val.x2;
            gradientAttrs.y2 = val.y2;
        }
        else if (isRadialGradient(val)) {
            gradientTag = 'radialGradient';
            gradientAttrs.cx = retrieve2(val.x, 0.5);
            gradientAttrs.cy = retrieve2(val.y, 0.5);
            gradientAttrs.r = retrieve2(val.r, 0.5);
        }
        else {
            if ("development" !== 'production') {
                logError('Illegal gradient type.');
            }
            return;
        }
        var colors = val.colorStops;
        var colorStops = [];
        for (var i = 0, len = colors.length; i < len; ++i) {
            var offset = round4(colors[i].offset) * 100 + '%';
            var stopColor = colors[i].color;
            var _a = normalizeColor(stopColor), color = _a.color, opacity = _a.opacity;
            var stopsAttrs = {
                'offset': offset
            };
            stopsAttrs['stop-color'] = color;
            if (opacity < 1) {
                stopsAttrs['stop-opacity'] = opacity;
            }
            colorStops.push(createVNode('stop', i + '', stopsAttrs));
        }
        var gradientVNode = createVNode(gradientTag, '', gradientAttrs, colorStops);
        var gradientKey = vNodeToString(gradientVNode);
        var gradientCache = scope.gradientCache;
        var gradientId = gradientCache[gradientKey];
        if (!gradientId) {
            gradientId = scope.zrId + '-g' + scope.gradientIdx++;
            gradientCache[gradientKey] = gradientId;
            gradientAttrs.id = gradientId;
            scope.defs[gradientId] = createVNode(gradientTag, gradientId, gradientAttrs, colorStops);
        }
        attrs[target] = getIdURL(gradientId);
    }
    function setPattern(el, attrs, target, scope) {
        var val = el.style[target];
        var boundingRect = el.getBoundingRect();
        var patternAttrs = {};
        var repeat = val.repeat;
        var noRepeat = repeat === 'no-repeat';
        var repeatX = repeat === 'repeat-x';
        var repeatY = repeat === 'repeat-y';
        var child;
        if (isImagePattern(val)) {
            var imageWidth_1 = val.imageWidth;
            var imageHeight_1 = val.imageHeight;
            var imageSrc = void 0;
            var patternImage = val.image;
            if (isString(patternImage)) {
                imageSrc = patternImage;
            }
            else if (isImageLike$1(patternImage)) {
                imageSrc = patternImage.src;
            }
            else if (isCanvasLike(patternImage)) {
                imageSrc = patternImage.toDataURL();
            }
            if (typeof Image === 'undefined') {
                var errMsg = 'Image width/height must been given explictly in svg-ssr renderer.';
                assert(imageWidth_1, errMsg);
                assert(imageHeight_1, errMsg);
            }
            else if (imageWidth_1 == null || imageHeight_1 == null) {
                var setSizeToVNode_1 = function (vNode, img) {
                    if (vNode) {
                        var svgEl = vNode.elm;
                        var width = imageWidth_1 || img.width;
                        var height = imageHeight_1 || img.height;
                        if (vNode.tag === 'pattern') {
                            if (repeatX) {
                                height = 1;
                                width /= boundingRect.width;
                            }
                            else if (repeatY) {
                                width = 1;
                                height /= boundingRect.height;
                            }
                        }
                        vNode.attrs.width = width;
                        vNode.attrs.height = height;
                        if (svgEl) {
                            svgEl.setAttribute('width', width);
                            svgEl.setAttribute('height', height);
                        }
                    }
                };
                var createdImage = createOrUpdateImage(imageSrc, null, el, function (img) {
                    noRepeat || setSizeToVNode_1(patternVNode, img);
                    setSizeToVNode_1(child, img);
                });
                if (createdImage && createdImage.width && createdImage.height) {
                    imageWidth_1 = imageWidth_1 || createdImage.width;
                    imageHeight_1 = imageHeight_1 || createdImage.height;
                }
            }
            child = createVNode('image', 'img', {
                href: imageSrc,
                width: imageWidth_1,
                height: imageHeight_1
            });
            patternAttrs.width = imageWidth_1;
            patternAttrs.height = imageHeight_1;
        }
        else if (val.svgElement) {
            child = clone(val.svgElement);
            patternAttrs.width = val.svgWidth;
            patternAttrs.height = val.svgHeight;
        }
        if (!child) {
            return;
        }
        var patternWidth;
        var patternHeight;
        if (noRepeat) {
            patternWidth = patternHeight = 1;
        }
        else if (repeatX) {
            patternHeight = 1;
            patternWidth = patternAttrs.width / boundingRect.width;
        }
        else if (repeatY) {
            patternWidth = 1;
            patternHeight = patternAttrs.height / boundingRect.height;
        }
        else {
            patternAttrs.patternUnits = 'userSpaceOnUse';
        }
        if (patternWidth != null && !isNaN(patternWidth)) {
            patternAttrs.width = patternWidth;
        }
        if (patternHeight != null && !isNaN(patternHeight)) {
            patternAttrs.height = patternHeight;
        }
        var patternTransform = getSRTTransformString(val);
        patternTransform && (patternAttrs.patternTransform = patternTransform);
        var patternVNode = createVNode('pattern', '', patternAttrs, [child]);
        var patternKey = vNodeToString(patternVNode);
        var patternCache = scope.patternCache;
        var patternId = patternCache[patternKey];
        if (!patternId) {
            patternId = scope.zrId + '-p' + scope.patternIdx++;
            patternCache[patternKey] = patternId;
            patternAttrs.id = patternId;
            patternVNode = scope.defs[patternId] = createVNode('pattern', patternId, patternAttrs, [child]);
        }
        attrs[target] = getIdURL(patternId);
    }
    function setClipPath(clipPath, attrs, scope) {
        var clipPathCache = scope.clipPathCache, defs = scope.defs;
        var clipPathId = clipPathCache[clipPath.id];
        if (!clipPathId) {
            clipPathId = scope.zrId + '-c' + scope.clipPathIdx++;
            var clipPathAttrs = {
                id: clipPathId
            };
            clipPathCache[clipPath.id] = clipPathId;
            defs[clipPathId] = createVNode('clipPath', clipPathId, clipPathAttrs, [brushSVGPath(clipPath, scope)]);
        }
        attrs['clip-path'] = getIdURL(clipPathId);
    }

    function createTextNode(text) {
        return document.createTextNode(text);
    }
    function insertBefore(parentNode, newNode, referenceNode) {
        parentNode.insertBefore(newNode, referenceNode);
    }
    function removeChild(node, child) {
        node.removeChild(child);
    }
    function appendChild(node, child) {
        node.appendChild(child);
    }
    function parentNode(node) {
        return node.parentNode;
    }
    function nextSibling(node) {
        return node.nextSibling;
    }
    function setTextContent(node, text) {
        node.textContent = text;
    }

    var colonChar = 58;
    var xChar = 120;
    var emptyNode = createVNode('', '');
    function isUndef(s) {
        return s === undefined;
    }
    function isDef(s) {
        return s !== undefined;
    }
    function createKeyToOldIdx(children, beginIdx, endIdx) {
        var map = {};
        for (var i = beginIdx; i <= endIdx; ++i) {
            var key = children[i].key;
            if (key !== undefined) {
                if ("development" !== 'production') {
                    if (map[key] != null) {
                        console.error("Duplicate key " + key);
                    }
                }
                map[key] = i;
            }
        }
        return map;
    }
    function sameVnode(vnode1, vnode2) {
        var isSameKey = vnode1.key === vnode2.key;
        var isSameTag = vnode1.tag === vnode2.tag;
        return isSameTag && isSameKey;
    }
    function createElm(vnode) {
        var i;
        var children = vnode.children;
        var tag = vnode.tag;
        if (isDef(tag)) {
            var elm = (vnode.elm = createElement(tag));
            updateAttrs(emptyNode, vnode);
            if (isArray(children)) {
                for (i = 0; i < children.length; ++i) {
                    var ch = children[i];
                    if (ch != null) {
                        appendChild(elm, createElm(ch));
                    }
                }
            }
            else if (isDef(vnode.text) && !isObject(vnode.text)) {
                appendChild(elm, createTextNode(vnode.text));
            }
        }
        else {
            vnode.elm = createTextNode(vnode.text);
        }
        return vnode.elm;
    }
    function addVnodes(parentElm, before, vnodes, startIdx, endIdx) {
        for (; startIdx <= endIdx; ++startIdx) {
            var ch = vnodes[startIdx];
            if (ch != null) {
                insertBefore(parentElm, createElm(ch), before);
            }
        }
    }
    function removeVnodes(parentElm, vnodes, startIdx, endIdx) {
        for (; startIdx <= endIdx; ++startIdx) {
            var ch = vnodes[startIdx];
            if (ch != null) {
                if (isDef(ch.tag)) {
                    var parent_1 = parentNode(ch.elm);
                    removeChild(parent_1, ch.elm);
                }
                else {
                    removeChild(parentElm, ch.elm);
                }
            }
        }
    }
    function updateAttrs(oldVnode, vnode) {
        var key;
        var elm = vnode.elm;
        var oldAttrs = oldVnode && oldVnode.attrs || {};
        var attrs = vnode.attrs || {};
        if (oldAttrs === attrs) {
            return;
        }
        for (key in attrs) {
            var cur = attrs[key];
            var old = oldAttrs[key];
            if (old !== cur) {
                if (cur === true) {
                    elm.setAttribute(key, '');
                }
                else if (cur === false) {
                    elm.removeAttribute(key);
                }
                else {
                    if (key.charCodeAt(0) !== xChar) {
                        elm.setAttribute(key, cur);
                    }
                    else if (key === 'xmlns:xlink' || key === 'xmlns') {
                        elm.setAttributeNS(XMLNS, key, cur);
                    }
                    else if (key.charCodeAt(3) === colonChar) {
                        elm.setAttributeNS(XML_NAMESPACE, key, cur);
                    }
                    else if (key.charCodeAt(5) === colonChar) {
                        elm.setAttributeNS(XLINKNS, key, cur);
                    }
                    else {
                        elm.setAttribute(key, cur);
                    }
                }
            }
        }
        for (key in oldAttrs) {
            if (!(key in attrs)) {
                elm.removeAttribute(key);
            }
        }
    }
    function updateChildren(parentElm, oldCh, newCh) {
        var oldStartIdx = 0;
        var newStartIdx = 0;
        var oldEndIdx = oldCh.length - 1;
        var oldStartVnode = oldCh[0];
        var oldEndVnode = oldCh[oldEndIdx];
        var newEndIdx = newCh.length - 1;
        var newStartVnode = newCh[0];
        var newEndVnode = newCh[newEndIdx];
        var oldKeyToIdx;
        var idxInOld;
        var elmToMove;
        var before;
        while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
            if (oldStartVnode == null) {
                oldStartVnode = oldCh[++oldStartIdx];
            }
            else if (oldEndVnode == null) {
                oldEndVnode = oldCh[--oldEndIdx];
            }
            else if (newStartVnode == null) {
                newStartVnode = newCh[++newStartIdx];
            }
            else if (newEndVnode == null) {
                newEndVnode = newCh[--newEndIdx];
            }
            else if (sameVnode(oldStartVnode, newStartVnode)) {
                patchVnode(oldStartVnode, newStartVnode);
                oldStartVnode = oldCh[++oldStartIdx];
                newStartVnode = newCh[++newStartIdx];
            }
            else if (sameVnode(oldEndVnode, newEndVnode)) {
                patchVnode(oldEndVnode, newEndVnode);
                oldEndVnode = oldCh[--oldEndIdx];
                newEndVnode = newCh[--newEndIdx];
            }
            else if (sameVnode(oldStartVnode, newEndVnode)) {
                patchVnode(oldStartVnode, newEndVnode);
                insertBefore(parentElm, oldStartVnode.elm, nextSibling(oldEndVnode.elm));
                oldStartVnode = oldCh[++oldStartIdx];
                newEndVnode = newCh[--newEndIdx];
            }
            else if (sameVnode(oldEndVnode, newStartVnode)) {
                patchVnode(oldEndVnode, newStartVnode);
                insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
                oldEndVnode = oldCh[--oldEndIdx];
                newStartVnode = newCh[++newStartIdx];
            }
            else {
                if (isUndef(oldKeyToIdx)) {
                    oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
                }
                idxInOld = oldKeyToIdx[newStartVnode.key];
                if (isUndef(idxInOld)) {
                    insertBefore(parentElm, createElm(newStartVnode), oldStartVnode.elm);
                }
                else {
                    elmToMove = oldCh[idxInOld];
                    if (elmToMove.tag !== newStartVnode.tag) {
                        insertBefore(parentElm, createElm(newStartVnode), oldStartVnode.elm);
                    }
                    else {
                        patchVnode(elmToMove, newStartVnode);
                        oldCh[idxInOld] = undefined;
                        insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm);
                    }
                }
                newStartVnode = newCh[++newStartIdx];
            }
        }
        if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) {
            if (oldStartIdx > oldEndIdx) {
                before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm;
                addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx);
            }
            else {
                removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
            }
        }
    }
    function patchVnode(oldVnode, vnode) {
        var elm = (vnode.elm = oldVnode.elm);
        var oldCh = oldVnode.children;
        var ch = vnode.children;
        if (oldVnode === vnode) {
            return;
        }
        updateAttrs(oldVnode, vnode);
        if (isUndef(vnode.text)) {
            if (isDef(oldCh) && isDef(ch)) {
                if (oldCh !== ch) {
                    updateChildren(elm, oldCh, ch);
                }
            }
            else if (isDef(ch)) {
                if (isDef(oldVnode.text)) {
                    setTextContent(elm, '');
                }
                addVnodes(elm, null, ch, 0, ch.length - 1);
            }
            else if (isDef(oldCh)) {
                removeVnodes(elm, oldCh, 0, oldCh.length - 1);
            }
            else if (isDef(oldVnode.text)) {
                setTextContent(elm, '');
            }
        }
        else if (oldVnode.text !== vnode.text) {
            if (isDef(oldCh)) {
                removeVnodes(elm, oldCh, 0, oldCh.length - 1);
            }
            setTextContent(elm, vnode.text);
        }
    }
    function patch(oldVnode, vnode) {
        if (sameVnode(oldVnode, vnode)) {
            patchVnode(oldVnode, vnode);
        }
        else {
            var elm = oldVnode.elm;
            var parent_2 = parentNode(elm);
            createElm(vnode);
            if (parent_2 !== null) {
                insertBefore(parent_2, vnode.elm, nextSibling(elm));
                removeVnodes(parent_2, [oldVnode], 0, 0);
            }
        }
        return vnode;
    }

    var svgId = 0;
    var SVGPainter = (function () {
        function SVGPainter(root, storage, opts) {
            this.type = 'svg';
            this.refreshHover = createMethodNotSupport('refreshHover');
            this.configLayer = createMethodNotSupport('configLayer');
            this.storage = storage;
            this._opts = opts = extend({}, opts);
            this.root = root;
            this._id = 'zr' + svgId++;
            this._oldVNode = createSVGVNode(opts.width, opts.height);
            if (root && !opts.ssr) {
                var viewport = this._viewport = document.createElement('div');
                viewport.style.cssText = 'position:relative;overflow:hidden';
                var svgDom = this._svgDom = this._oldVNode.elm = createElement('svg');
                updateAttrs(null, this._oldVNode);
                viewport.appendChild(svgDom);
                root.appendChild(viewport);
            }
            this.resize(opts.width, opts.height);
        }
        SVGPainter.prototype.getType = function () {
            return this.type;
        };
        SVGPainter.prototype.getViewportRoot = function () {
            return this._viewport;
        };
        SVGPainter.prototype.getViewportRootOffset = function () {
            var viewportRoot = this.getViewportRoot();
            if (viewportRoot) {
                return {
                    offsetLeft: viewportRoot.offsetLeft || 0,
                    offsetTop: viewportRoot.offsetTop || 0
                };
            }
        };
        SVGPainter.prototype.getSvgDom = function () {
            return this._svgDom;
        };
        SVGPainter.prototype.refresh = function () {
            if (this.root) {
                var vnode = this.renderToVNode({
                    willUpdate: true
                });
                vnode.attrs.style = 'position:absolute;left:0;top:0;user-select:none';
                patch(this._oldVNode, vnode);
                this._oldVNode = vnode;
            }
        };
        SVGPainter.prototype.renderOneToVNode = function (el) {
            return brush$1(el, createBrushScope(this._id));
        };
        SVGPainter.prototype.renderToVNode = function (opts) {
            opts = opts || {};
            var list = this.storage.getDisplayList(true);
            var width = this._width;
            var height = this._height;
            var scope = createBrushScope(this._id);
            scope.animation = opts.animation;
            scope.willUpdate = opts.willUpdate;
            scope.compress = opts.compress;
            var children = [];
            var bgVNode = this._bgVNode = createBackgroundVNode(width, height, this._backgroundColor, scope);
            bgVNode && children.push(bgVNode);
            var mainVNode = !opts.compress
                ? (this._mainVNode = createVNode('g', 'main', {}, [])) : null;
            this._paintList(list, scope, mainVNode ? mainVNode.children : children);
            mainVNode && children.push(mainVNode);
            var defs = map(keys(scope.defs), function (id) { return scope.defs[id]; });
            if (defs.length) {
                children.push(createVNode('defs', 'defs', {}, defs));
            }
            if (opts.animation) {
                var animationCssStr = getCssString(scope.cssNodes, scope.cssAnims, { newline: true });
                if (animationCssStr) {
                    var styleNode = createVNode('style', 'stl', {}, [], animationCssStr);
                    children.push(styleNode);
                }
            }
            return createSVGVNode(width, height, children, opts.useViewBox);
        };
        SVGPainter.prototype.renderToString = function (opts) {
            opts = opts || {};
            return vNodeToString(this.renderToVNode({
                animation: retrieve2(opts.cssAnimation, true),
                willUpdate: false,
                compress: true,
                useViewBox: retrieve2(opts.useViewBox, true)
            }), { newline: true });
        };
        SVGPainter.prototype.setBackgroundColor = function (backgroundColor) {
            this._backgroundColor = backgroundColor;
        };
        SVGPainter.prototype.getSvgRoot = function () {
            return this._mainVNode && this._mainVNode.elm;
        };
        SVGPainter.prototype._paintList = function (list, scope, out) {
            var listLen = list.length;
            var clipPathsGroupsStack = [];
            var clipPathsGroupsStackDepth = 0;
            var currentClipPathGroup;
            var prevClipPaths;
            var clipGroupNodeIdx = 0;
            for (var i = 0; i < listLen; i++) {
                var displayable = list[i];
                if (!displayable.invisible) {
                    var clipPaths = displayable.__clipPaths;
                    var len = clipPaths && clipPaths.length || 0;
                    var prevLen = prevClipPaths && prevClipPaths.length || 0;
                    var lca = void 0;
                    for (lca = Math.max(len - 1, prevLen - 1); lca >= 0; lca--) {
                        if (clipPaths && prevClipPaths
                            && clipPaths[lca] === prevClipPaths[lca]) {
                            break;
                        }
                    }
                    for (var i_1 = prevLen - 1; i_1 > lca; i_1--) {
                        clipPathsGroupsStackDepth--;
                        currentClipPathGroup = clipPathsGroupsStack[clipPathsGroupsStackDepth - 1];
                    }
                    for (var i_2 = lca + 1; i_2 < len; i_2++) {
                        var groupAttrs = {};
                        setClipPath(clipPaths[i_2], groupAttrs, scope);
                        var g = createVNode('g', 'clip-g-' + clipGroupNodeIdx++, groupAttrs, []);
                        (currentClipPathGroup ? currentClipPathGroup.children : out).push(g);
                        clipPathsGroupsStack[clipPathsGroupsStackDepth++] = g;
                        currentClipPathGroup = g;
                    }
                    prevClipPaths = clipPaths;
                    var ret = brush$1(displayable, scope);
                    if (ret) {
                        (currentClipPathGroup ? currentClipPathGroup.children : out).push(ret);
                    }
                }
            }
        };
        SVGPainter.prototype.resize = function (width, height) {
            var opts = this._opts;
            var root = this.root;
            var viewport = this._viewport;
            width != null && (opts.width = width);
            height != null && (opts.height = height);
            if (root && viewport) {
                viewport.style.display = 'none';
                width = getSize(root, 0, opts);
                height = getSize(root, 1, opts);
                viewport.style.display = '';
            }
            if (this._width !== width || this._height !== height) {
                this._width = width;
                this._height = height;
                if (viewport) {
                    var viewportStyle = viewport.style;
                    viewportStyle.width = width + 'px';
                    viewportStyle.height = height + 'px';
                }
                if (!isPattern(this._backgroundColor)) {
                    var svgDom = this._svgDom;
                    if (svgDom) {
                        svgDom.setAttribute('width', width);
                        svgDom.setAttribute('height', height);
                    }
                    var bgEl = this._bgVNode && this._bgVNode.elm;
                    if (bgEl) {
                        bgEl.setAttribute('width', width);
                        bgEl.setAttribute('height', height);
                    }
                }
                else {
                    this.refresh();
                }
            }
        };
        SVGPainter.prototype.getWidth = function () {
            return this._width;
        };
        SVGPainter.prototype.getHeight = function () {
            return this._height;
        };
        SVGPainter.prototype.dispose = function () {
            if (this.root) {
                this.root.innerHTML = '';
            }
            this._svgDom =
                this._viewport =
                    this.storage =
                        this._oldVNode =
                            this._bgVNode =
                                this._mainVNode = null;
        };
        SVGPainter.prototype.clear = function () {
            if (this._svgDom) {
                this._svgDom.innerHTML = null;
            }
            this._oldVNode = null;
        };
        SVGPainter.prototype.toDataURL = function (base64) {
            var str = this.renderToString();
            var prefix = 'data:image/svg+xml;';
            if (base64) {
                str = encodeBase64(str);
                return str && prefix + 'base64,' + str;
            }
            return prefix + 'charset=UTF-8,' + encodeURIComponent(str);
        };
        return SVGPainter;
    }());
    function createMethodNotSupport(method) {
        return function () {
            if ("development" !== 'production') {
                logError('In SVG mode painter not support method "' + method + '"');
            }
        };
    }
    function createBackgroundVNode(width, height, backgroundColor, scope) {
        var bgVNode;
        if (backgroundColor && backgroundColor !== 'none') {
            bgVNode = createVNode('rect', 'bg', {
                width: width,
                height: height,
                x: '0',
                y: '0',
                id: '0'
            });
            if (isGradient(backgroundColor)) {
                setGradient({ fill: backgroundColor }, bgVNode.attrs, 'fill', scope);
            }
            else if (isPattern(backgroundColor)) {
                setPattern({
                    style: {
                        fill: backgroundColor
                    },
                    dirty: noop,
                    getBoundingRect: function () { return ({ width: width, height: height }); }
                }, bgVNode.attrs, 'fill', scope);
            }
            else {
                var _a = normalizeColor(backgroundColor), color = _a.color, opacity = _a.opacity;
                bgVNode.attrs.fill = color;
                opacity < 1 && (bgVNode.attrs.fillOpacity = opacity);
            }
        }
        return bgVNode;
    }

    function install(registers) {
      registers.registerPainter('svg', SVGPainter);
    }

    function createDom(id, painter, dpr) {
        var newDom = platformApi.createCanvas();
        var width = painter.getWidth();
        var height = painter.getHeight();
        var newDomStyle = newDom.style;
        if (newDomStyle) {
            newDomStyle.position = 'absolute';
            newDomStyle.left = '0';
            newDomStyle.top = '0';
            newDomStyle.width = width + 'px';
            newDomStyle.height = height + 'px';
            newDom.setAttribute('data-zr-dom-id', id);
        }
        newDom.width = width * dpr;
        newDom.height = height * dpr;
        return newDom;
    }
    var Layer = (function (_super) {
        __extends(Layer, _super);
        function Layer(id, painter, dpr) {
            var _this = _super.call(this) || this;
            _this.motionBlur = false;
            _this.lastFrameAlpha = 0.7;
            _this.dpr = 1;
            _this.virtual = false;
            _this.config = {};
            _this.incremental = false;
            _this.zlevel = 0;
            _this.maxRepaintRectCount = 5;
            _this.__dirty = true;
            _this.__firstTimePaint = true;
            _this.__used = false;
            _this.__drawIndex = 0;
            _this.__startIndex = 0;
            _this.__endIndex = 0;
            _this.__prevStartIndex = null;
            _this.__prevEndIndex = null;
            var dom;
            dpr = dpr || devicePixelRatio;
            if (typeof id === 'string') {
                dom = createDom(id, painter, dpr);
            }
            else if (isObject(id)) {
                dom = id;
                id = dom.id;
            }
            _this.id = id;
            _this.dom = dom;
            var domStyle = dom.style;
            if (domStyle) {
                disableUserSelect(dom);
                dom.onselectstart = function () { return false; };
                domStyle.padding = '0';
                domStyle.margin = '0';
                domStyle.borderWidth = '0';
            }
            _this.painter = painter;
            _this.dpr = dpr;
            return _this;
        }
        Layer.prototype.getElementCount = function () {
            return this.__endIndex - this.__startIndex;
        };
        Layer.prototype.afterBrush = function () {
            this.__prevStartIndex = this.__startIndex;
            this.__prevEndIndex = this.__endIndex;
        };
        Layer.prototype.initContext = function () {
            this.ctx = this.dom.getContext('2d');
            this.ctx.dpr = this.dpr;
        };
        Layer.prototype.setUnpainted = function () {
            this.__firstTimePaint = true;
        };
        Layer.prototype.createBackBuffer = function () {
            var dpr = this.dpr;
            this.domBack = createDom('back-' + this.id, this.painter, dpr);
            this.ctxBack = this.domBack.getContext('2d');
            if (dpr !== 1) {
                this.ctxBack.scale(dpr, dpr);
            }
        };
        Layer.prototype.createRepaintRects = function (displayList, prevList, viewWidth, viewHeight) {
            if (this.__firstTimePaint) {
                this.__firstTimePaint = false;
                return null;
            }
            var mergedRepaintRects = [];
            var maxRepaintRectCount = this.maxRepaintRectCount;
            var full = false;
            var pendingRect = new BoundingRect(0, 0, 0, 0);
            function addRectToMergePool(rect) {
                if (!rect.isFinite() || rect.isZero()) {
                    return;
                }
                if (mergedRepaintRects.length === 0) {
                    var boundingRect = new BoundingRect(0, 0, 0, 0);
                    boundingRect.copy(rect);
                    mergedRepaintRects.push(boundingRect);
                }
                else {
                    var isMerged = false;
                    var minDeltaArea = Infinity;
                    var bestRectToMergeIdx = 0;
                    for (var i = 0; i < mergedRepaintRects.length; ++i) {
                        var mergedRect = mergedRepaintRects[i];
                        if (mergedRect.intersect(rect)) {
                            var pendingRect_1 = new BoundingRect(0, 0, 0, 0);
                            pendingRect_1.copy(mergedRect);
                            pendingRect_1.union(rect);
                            mergedRepaintRects[i] = pendingRect_1;
                            isMerged = true;
                            break;
                        }
                        else if (full) {
                            pendingRect.copy(rect);
                            pendingRect.union(mergedRect);
                            var aArea = rect.width * rect.height;
                            var bArea = mergedRect.width * mergedRect.height;
                            var pendingArea = pendingRect.width * pendingRect.height;
                            var deltaArea = pendingArea - aArea - bArea;
                            if (deltaArea < minDeltaArea) {
                                minDeltaArea = deltaArea;
                                bestRectToMergeIdx = i;
                            }
                        }
                    }
                    if (full) {
                        mergedRepaintRects[bestRectToMergeIdx].union(rect);
                        isMerged = true;
                    }
                    if (!isMerged) {
                        var boundingRect = new BoundingRect(0, 0, 0, 0);
                        boundingRect.copy(rect);
                        mergedRepaintRects.push(boundingRect);
                    }
                    if (!full) {
                        full = mergedRepaintRects.length >= maxRepaintRectCount;
                    }
                }
            }
            for (var i = this.__startIndex; i < this.__endIndex; ++i) {
                var el = displayList[i];
                if (el) {
                    var shouldPaint = el.shouldBePainted(viewWidth, viewHeight, true, true);
                    var prevRect = el.__isRendered && ((el.__dirty & REDRAW_BIT) || !shouldPaint)
                        ? el.getPrevPaintRect()
                        : null;
                    if (prevRect) {
                        addRectToMergePool(prevRect);
                    }
                    var curRect = shouldPaint && ((el.__dirty & REDRAW_BIT) || !el.__isRendered)
                        ? el.getPaintRect()
                        : null;
                    if (curRect) {
                        addRectToMergePool(curRect);
                    }
                }
            }
            for (var i = this.__prevStartIndex; i < this.__prevEndIndex; ++i) {
                var el = prevList[i];
                var shouldPaint = el.shouldBePainted(viewWidth, viewHeight, true, true);
                if (el && (!shouldPaint || !el.__zr) && el.__isRendered) {
                    var prevRect = el.getPrevPaintRect();
                    if (prevRect) {
                        addRectToMergePool(prevRect);
                    }
                }
            }
            var hasIntersections;
            do {
                hasIntersections = false;
                for (var i = 0; i < mergedRepaintRects.length;) {
                    if (mergedRepaintRects[i].isZero()) {
                        mergedRepaintRects.splice(i, 1);
                        continue;
                    }
                    for (var j = i + 1; j < mergedRepaintRects.length;) {
                        if (mergedRepaintRects[i].intersect(mergedRepaintRects[j])) {
                            hasIntersections = true;
                            mergedRepaintRects[i].union(mergedRepaintRects[j]);
                            mergedRepaintRects.splice(j, 1);
                        }
                        else {
                            j++;
                        }
                    }
                    i++;
                }
            } while (hasIntersections);
            this._paintRects = mergedRepaintRects;
            return mergedRepaintRects;
        };
        Layer.prototype.debugGetPaintRects = function () {
            return (this._paintRects || []).slice();
        };
        Layer.prototype.resize = function (width, height) {
            var dpr = this.dpr;
            var dom = this.dom;
            var domStyle = dom.style;
            var domBack = this.domBack;
            if (domStyle) {
                domStyle.width = width + 'px';
                domStyle.height = height + 'px';
            }
            dom.width = width * dpr;
            dom.height = height * dpr;
            if (domBack) {
                domBack.width = width * dpr;
                domBack.height = height * dpr;
                if (dpr !== 1) {
                    this.ctxBack.scale(dpr, dpr);
                }
            }
        };
        Layer.prototype.clear = function (clearAll, clearColor, repaintRects) {
            var dom = this.dom;
            var ctx = this.ctx;
            var width = dom.width;
            var height = dom.height;
            clearColor = clearColor || this.clearColor;
            var haveMotionBLur = this.motionBlur && !clearAll;
            var lastFrameAlpha = this.lastFrameAlpha;
            var dpr = this.dpr;
            var self = this;
            if (haveMotionBLur) {
                if (!this.domBack) {
                    this.createBackBuffer();
                }
                this.ctxBack.globalCompositeOperation = 'copy';
                this.ctxBack.drawImage(dom, 0, 0, width / dpr, height / dpr);
            }
            var domBack = this.domBack;
            function doClear(x, y, width, height) {
                ctx.clearRect(x, y, width, height);
                if (clearColor && clearColor !== 'transparent') {
                    var clearColorGradientOrPattern = void 0;
                    if (isGradientObject(clearColor)) {
                        var shouldCache = clearColor.global || (clearColor.__width === width
                            && clearColor.__height === height);
                        clearColorGradientOrPattern = shouldCache
                            && clearColor.__canvasGradient
                            || getCanvasGradient(ctx, clearColor, {
                                x: 0,
                                y: 0,
                                width: width,
                                height: height
                            });
                        clearColor.__canvasGradient = clearColorGradientOrPattern;
                        clearColor.__width = width;
                        clearColor.__height = height;
                    }
                    else if (isImagePatternObject(clearColor)) {
                        clearColor.scaleX = clearColor.scaleX || dpr;
                        clearColor.scaleY = clearColor.scaleY || dpr;
                        clearColorGradientOrPattern = createCanvasPattern(ctx, clearColor, {
                            dirty: function () {
                                self.setUnpainted();
                                self.__painter.refresh();
                            }
                        });
                    }
                    ctx.save();
                    ctx.fillStyle = clearColorGradientOrPattern || clearColor;
                    ctx.fillRect(x, y, width, height);
                    ctx.restore();
                }
                if (haveMotionBLur) {
                    ctx.save();
                    ctx.globalAlpha = lastFrameAlpha;
                    ctx.drawImage(domBack, x, y, width, height);
                    ctx.restore();
                }
            }
            if (!repaintRects || haveMotionBLur) {
                doClear(0, 0, width, height);
            }
            else if (repaintRects.length) {
                each(repaintRects, function (rect) {
                    doClear(rect.x * dpr, rect.y * dpr, rect.width * dpr, rect.height * dpr);
                });
            }
        };
        return Layer;
    }(Eventful));

    var HOVER_LAYER_ZLEVEL = 1e5;
    var CANVAS_ZLEVEL = 314159;
    var EL_AFTER_INCREMENTAL_INC = 0.01;
    var INCREMENTAL_INC = 0.001;
    function isLayerValid(layer) {
        if (!layer) {
            return false;
        }
        if (layer.__builtin__) {
            return true;
        }
        if (typeof (layer.resize) !== 'function'
            || typeof (layer.refresh) !== 'function') {
            return false;
        }
        return true;
    }
    function createRoot(width, height) {
        var domRoot = document.createElement('div');
        domRoot.style.cssText = [
            'position:relative',
            'width:' + width + 'px',
            'height:' + height + 'px',
            'padding:0',
            'margin:0',
            'border-width:0'
        ].join(';') + ';';
        return domRoot;
    }
    var CanvasPainter = (function () {
        function CanvasPainter(root, storage, opts, id) {
            this.type = 'canvas';
            this._zlevelList = [];
            this._prevDisplayList = [];
            this._layers = {};
            this._layerConfig = {};
            this._needsManuallyCompositing = false;
            this.type = 'canvas';
            var singleCanvas = !root.nodeName
                || root.nodeName.toUpperCase() === 'CANVAS';
            this._opts = opts = extend({}, opts || {});
            this.dpr = opts.devicePixelRatio || devicePixelRatio;
            this._singleCanvas = singleCanvas;
            this.root = root;
            var rootStyle = root.style;
            if (rootStyle) {
                disableUserSelect(root);
                root.innerHTML = '';
            }
            this.storage = storage;
            var zlevelList = this._zlevelList;
            this._prevDisplayList = [];
            var layers = this._layers;
            if (!singleCanvas) {
                this._width = getSize(root, 0, opts);
                this._height = getSize(root, 1, opts);
                var domRoot = this._domRoot = createRoot(this._width, this._height);
                root.appendChild(domRoot);
            }
            else {
                var rootCanvas = root;
                var width = rootCanvas.width;
                var height = rootCanvas.height;
                if (opts.width != null) {
                    width = opts.width;
                }
                if (opts.height != null) {
                    height = opts.height;
                }
                this.dpr = opts.devicePixelRatio || 1;
                rootCanvas.width = width * this.dpr;
                rootCanvas.height = height * this.dpr;
                this._width = width;
                this._height = height;
                var mainLayer = new Layer(rootCanvas, this, this.dpr);
                mainLayer.__builtin__ = true;
                mainLayer.initContext();
                layers[CANVAS_ZLEVEL] = mainLayer;
                mainLayer.zlevel = CANVAS_ZLEVEL;
                zlevelList.push(CANVAS_ZLEVEL);
                this._domRoot = root;
            }
        }
        CanvasPainter.prototype.getType = function () {
            return 'canvas';
        };
        CanvasPainter.prototype.isSingleCanvas = function () {
            return this._singleCanvas;
        };
        CanvasPainter.prototype.getViewportRoot = function () {
            return this._domRoot;
        };
        CanvasPainter.prototype.getViewportRootOffset = function () {
            var viewportRoot = this.getViewportRoot();
            if (viewportRoot) {
                return {
                    offsetLeft: viewportRoot.offsetLeft || 0,
                    offsetTop: viewportRoot.offsetTop || 0
                };
            }
        };
        CanvasPainter.prototype.refresh = function (paintAll) {
            var list = this.storage.getDisplayList(true);
            var prevList = this._prevDisplayList;
            var zlevelList = this._zlevelList;
            this._redrawId = Math.random();
            this._paintList(list, prevList, paintAll, this._redrawId);
            for (var i = 0; i < zlevelList.length; i++) {
                var z = zlevelList[i];
                var layer = this._layers[z];
                if (!layer.__builtin__ && layer.refresh) {
                    var clearColor = i === 0 ? this._backgroundColor : null;
                    layer.refresh(clearColor);
                }
            }
            if (this._opts.useDirtyRect) {
                this._prevDisplayList = list.slice();
            }
            return this;
        };
        CanvasPainter.prototype.refreshHover = function () {
            this._paintHoverList(this.storage.getDisplayList(false));
        };
        CanvasPainter.prototype._paintHoverList = function (list) {
            var len = list.length;
            var hoverLayer = this._hoverlayer;
            hoverLayer && hoverLayer.clear();
            if (!len) {
                return;
            }
            var scope = {
                inHover: true,
                viewWidth: this._width,
                viewHeight: this._height
            };
            var ctx;
            for (var i = 0; i < len; i++) {
                var el = list[i];
                if (el.__inHover) {
                    if (!hoverLayer) {
                        hoverLayer = this._hoverlayer = this.getLayer(HOVER_LAYER_ZLEVEL);
                    }
                    if (!ctx) {
                        ctx = hoverLayer.ctx;
                        ctx.save();
                    }
                    brush(ctx, el, scope, i === len - 1);
                }
            }
            if (ctx) {
                ctx.restore();
            }
        };
        CanvasPainter.prototype.getHoverLayer = function () {
            return this.getLayer(HOVER_LAYER_ZLEVEL);
        };
        CanvasPainter.prototype.paintOne = function (ctx, el) {
            brushSingle(ctx, el);
        };
        CanvasPainter.prototype._paintList = function (list, prevList, paintAll, redrawId) {
            if (this._redrawId !== redrawId) {
                return;
            }
            paintAll = paintAll || false;
            this._updateLayerStatus(list);
            var _a = this._doPaintList(list, prevList, paintAll), finished = _a.finished, needsRefreshHover = _a.needsRefreshHover;
            if (this._needsManuallyCompositing) {
                this._compositeManually();
            }
            if (needsRefreshHover) {
                this._paintHoverList(list);
            }
            if (!finished) {
                var self_1 = this;
                requestAnimationFrame$1(function () {
                    self_1._paintList(list, prevList, paintAll, redrawId);
                });
            }
            else {
                this.eachLayer(function (layer) {
                    layer.afterBrush && layer.afterBrush();
                });
            }
        };
        CanvasPainter.prototype._compositeManually = function () {
            var ctx = this.getLayer(CANVAS_ZLEVEL).ctx;
            var width = this._domRoot.width;
            var height = this._domRoot.height;
            ctx.clearRect(0, 0, width, height);
            this.eachBuiltinLayer(function (layer) {
                if (layer.virtual) {
                    ctx.drawImage(layer.dom, 0, 0, width, height);
                }
            });
        };
        CanvasPainter.prototype._doPaintList = function (list, prevList, paintAll) {
            var _this = this;
            var layerList = [];
            var useDirtyRect = this._opts.useDirtyRect;
            for (var zi = 0; zi < this._zlevelList.length; zi++) {
                var zlevel = this._zlevelList[zi];
                var layer = this._layers[zlevel];
                if (layer.__builtin__
                    && layer !== this._hoverlayer
                    && (layer.__dirty || paintAll)) {
                    layerList.push(layer);
                }
            }
            var finished = true;
            var needsRefreshHover = false;
            var _loop_1 = function (k) {
                var layer = layerList[k];
                var ctx = layer.ctx;
                var repaintRects = useDirtyRect
                    && layer.createRepaintRects(list, prevList, this_1._width, this_1._height);
                var start = paintAll ? layer.__startIndex : layer.__drawIndex;
                var useTimer = !paintAll && layer.incremental && Date.now;
                var startTime = useTimer && Date.now();
                var clearColor = layer.zlevel === this_1._zlevelList[0]
                    ? this_1._backgroundColor : null;
                if (layer.__startIndex === layer.__endIndex) {
                    layer.clear(false, clearColor, repaintRects);
                }
                else if (start === layer.__startIndex) {
                    var firstEl = list[start];
                    if (!firstEl.incremental || !firstEl.notClear || paintAll) {
                        layer.clear(false, clearColor, repaintRects);
                    }
                }
                if (start === -1) {
                    console.error('For some unknown reason. drawIndex is -1');
                    start = layer.__startIndex;
                }
                var i;
                var repaint = function (repaintRect) {
                    var scope = {
                        inHover: false,
                        allClipped: false,
                        prevEl: null,
                        viewWidth: _this._width,
                        viewHeight: _this._height
                    };
                    for (i = start; i < layer.__endIndex; i++) {
                        var el = list[i];
                        if (el.__inHover) {
                            needsRefreshHover = true;
                        }
                        _this._doPaintEl(el, layer, useDirtyRect, repaintRect, scope, i === layer.__endIndex - 1);
                        if (useTimer) {
                            var dTime = Date.now() - startTime;
                            if (dTime > 15) {
                                break;
                            }
                        }
                    }
                    if (scope.prevElClipPaths) {
                        ctx.restore();
                    }
                };
                if (repaintRects) {
                    if (repaintRects.length === 0) {
                        i = layer.__endIndex;
                    }
                    else {
                        var dpr = this_1.dpr;
                        for (var r = 0; r < repaintRects.length; ++r) {
                            var rect = repaintRects[r];
                            ctx.save();
                            ctx.beginPath();
                            ctx.rect(rect.x * dpr, rect.y * dpr, rect.width * dpr, rect.height * dpr);
                            ctx.clip();
                            repaint(rect);
                            ctx.restore();
                        }
                    }
                }
                else {
                    ctx.save();
                    repaint();
                    ctx.restore();
                }
                layer.__drawIndex = i;
                if (layer.__drawIndex < layer.__endIndex) {
                    finished = false;
                }
            };
            var this_1 = this;
            for (var k = 0; k < layerList.length; k++) {
                _loop_1(k);
            }
            if (env.wxa) {
                each(this._layers, function (layer) {
                    if (layer && layer.ctx && layer.ctx.draw) {
                        layer.ctx.draw();
                    }
                });
            }
            return {
                finished: finished,
                needsRefreshHover: needsRefreshHover
            };
        };
        CanvasPainter.prototype._doPaintEl = function (el, currentLayer, useDirtyRect, repaintRect, scope, isLast) {
            var ctx = currentLayer.ctx;
            if (useDirtyRect) {
                var paintRect = el.getPaintRect();
                if (!repaintRect || paintRect && paintRect.intersect(repaintRect)) {
                    brush(ctx, el, scope, isLast);
                    el.setPrevPaintRect(paintRect);
                }
            }
            else {
                brush(ctx, el, scope, isLast);
            }
        };
        CanvasPainter.prototype.getLayer = function (zlevel, virtual) {
            if (this._singleCanvas && !this._needsManuallyCompositing) {
                zlevel = CANVAS_ZLEVEL;
            }
            var layer = this._layers[zlevel];
            if (!layer) {
                layer = new Layer('zr_' + zlevel, this, this.dpr);
                layer.zlevel = zlevel;
                layer.__builtin__ = true;
                if (this._layerConfig[zlevel]) {
                    merge(layer, this._layerConfig[zlevel], true);
                }
                else if (this._layerConfig[zlevel - EL_AFTER_INCREMENTAL_INC]) {
                    merge(layer, this._layerConfig[zlevel - EL_AFTER_INCREMENTAL_INC], true);
                }
                if (virtual) {
                    layer.virtual = virtual;
                }
                this.insertLayer(zlevel, layer);
                layer.initContext();
            }
            return layer;
        };
        CanvasPainter.prototype.insertLayer = function (zlevel, layer) {
            var layersMap = this._layers;
            var zlevelList = this._zlevelList;
            var len = zlevelList.length;
            var domRoot = this._domRoot;
            var prevLayer = null;
            var i = -1;
            if (layersMap[zlevel]) {
                if ("development" !== 'production') {
                    logError('ZLevel ' + zlevel + ' has been used already');
                }
                return;
            }
            if (!isLayerValid(layer)) {
                if ("development" !== 'production') {
                    logError('Layer of zlevel ' + zlevel + ' is not valid');
                }
                return;
            }
            if (len > 0 && zlevel > zlevelList[0]) {
                for (i = 0; i < len - 1; i++) {
                    if (zlevelList[i] < zlevel
                        && zlevelList[i + 1] > zlevel) {
                        break;
                    }
                }
                prevLayer = layersMap[zlevelList[i]];
            }
            zlevelList.splice(i + 1, 0, zlevel);
            layersMap[zlevel] = layer;
            if (!layer.virtual) {
                if (prevLayer) {
                    var prevDom = prevLayer.dom;
                    if (prevDom.nextSibling) {
                        domRoot.insertBefore(layer.dom, prevDom.nextSibling);
                    }
                    else {
                        domRoot.appendChild(layer.dom);
                    }
                }
                else {
                    if (domRoot.firstChild) {
                        domRoot.insertBefore(layer.dom, domRoot.firstChild);
                    }
                    else {
                        domRoot.appendChild(layer.dom);
                    }
                }
            }
            layer.__painter = this;
        };
        CanvasPainter.prototype.eachLayer = function (cb, context) {
            var zlevelList = this._zlevelList;
            for (var i = 0; i < zlevelList.length; i++) {
                var z = zlevelList[i];
                cb.call(context, this._layers[z], z);
            }
        };
        CanvasPainter.prototype.eachBuiltinLayer = function (cb, context) {
            var zlevelList = this._zlevelList;
            for (var i = 0; i < zlevelList.length; i++) {
                var z = zlevelList[i];
                var layer = this._layers[z];
                if (layer.__builtin__) {
                    cb.call(context, layer, z);
                }
            }
        };
        CanvasPainter.prototype.eachOtherLayer = function (cb, context) {
            var zlevelList = this._zlevelList;
            for (var i = 0; i < zlevelList.length; i++) {
                var z = zlevelList[i];
                var layer = this._layers[z];
                if (!layer.__builtin__) {
                    cb.call(context, layer, z);
                }
            }
        };
        CanvasPainter.prototype.getLayers = function () {
            return this._layers;
        };
        CanvasPainter.prototype._updateLayerStatus = function (list) {
            this.eachBuiltinLayer(function (layer, z) {
                layer.__dirty = layer.__used = false;
            });
            function updatePrevLayer(idx) {
                if (prevLayer) {
                    if (prevLayer.__endIndex !== idx) {
                        prevLayer.__dirty = true;
                    }
                    prevLayer.__endIndex = idx;
                }
            }
            if (this._singleCanvas) {
                for (var i_1 = 1; i_1 < list.length; i_1++) {
                    var el = list[i_1];
                    if (el.zlevel !== list[i_1 - 1].zlevel || el.incremental) {
                        this._needsManuallyCompositing = true;
                        break;
                    }
                }
            }
            var prevLayer = null;
            var incrementalLayerCount = 0;
            var prevZlevel;
            var i;
            for (i = 0; i < list.length; i++) {
                var el = list[i];
                var zlevel = el.zlevel;
                var layer = void 0;
                if (prevZlevel !== zlevel) {
                    prevZlevel = zlevel;
                    incrementalLayerCount = 0;
                }
                if (el.incremental) {
                    layer = this.getLayer(zlevel + INCREMENTAL_INC, this._needsManuallyCompositing);
                    layer.incremental = true;
                    incrementalLayerCount = 1;
                }
                else {
                    layer = this.getLayer(zlevel + (incrementalLayerCount > 0 ? EL_AFTER_INCREMENTAL_INC : 0), this._needsManuallyCompositing);
                }
                if (!layer.__builtin__) {
                    logError('ZLevel ' + zlevel + ' has been used by unkown layer ' + layer.id);
                }
                if (layer !== prevLayer) {
                    layer.__used = true;
                    if (layer.__startIndex !== i) {
                        layer.__dirty = true;
                    }
                    layer.__startIndex = i;
                    if (!layer.incremental) {
                        layer.__drawIndex = i;
                    }
                    else {
                        layer.__drawIndex = -1;
                    }
                    updatePrevLayer(i);
                    prevLayer = layer;
                }
                if ((el.__dirty & REDRAW_BIT) && !el.__inHover) {
                    layer.__dirty = true;
                    if (layer.incremental && layer.__drawIndex < 0) {
                        layer.__drawIndex = i;
                    }
                }
            }
            updatePrevLayer(i);
            this.eachBuiltinLayer(function (layer, z) {
                if (!layer.__used && layer.getElementCount() > 0) {
                    layer.__dirty = true;
                    layer.__startIndex = layer.__endIndex = layer.__drawIndex = 0;
                }
                if (layer.__dirty && layer.__drawIndex < 0) {
                    layer.__drawIndex = layer.__startIndex;
                }
            });
        };
        CanvasPainter.prototype.clear = function () {
            this.eachBuiltinLayer(this._clearLayer);
            return this;
        };
        CanvasPainter.prototype._clearLayer = function (layer) {
            layer.clear();
        };
        CanvasPainter.prototype.setBackgroundColor = function (backgroundColor) {
            this._backgroundColor = backgroundColor;
            each(this._layers, function (layer) {
                layer.setUnpainted();
            });
        };
        CanvasPainter.prototype.configLayer = function (zlevel, config) {
            if (config) {
                var layerConfig = this._layerConfig;
                if (!layerConfig[zlevel]) {
                    layerConfig[zlevel] = config;
                }
                else {
                    merge(layerConfig[zlevel], config, true);
                }
                for (var i = 0; i < this._zlevelList.length; i++) {
                    var _zlevel = this._zlevelList[i];
                    if (_zlevel === zlevel || _zlevel === zlevel + EL_AFTER_INCREMENTAL_INC) {
                        var layer = this._layers[_zlevel];
                        merge(layer, layerConfig[zlevel], true);
                    }
                }
            }
        };
        CanvasPainter.prototype.delLayer = function (zlevel) {
            var layers = this._layers;
            var zlevelList = this._zlevelList;
            var layer = layers[zlevel];
            if (!layer) {
                return;
            }
            layer.dom.parentNode.removeChild(layer.dom);
            delete layers[zlevel];
            zlevelList.splice(indexOf(zlevelList, zlevel), 1);
        };
        CanvasPainter.prototype.resize = function (width, height) {
            if (!this._domRoot.style) {
                if (width == null || height == null) {
                    return;
                }
                this._width = width;
                this._height = height;
                this.getLayer(CANVAS_ZLEVEL).resize(width, height);
            }
            else {
                var domRoot = this._domRoot;
                domRoot.style.display = 'none';
                var opts = this._opts;
                var root = this.root;
                width != null && (opts.width = width);
                height != null && (opts.height = height);
                width = getSize(root, 0, opts);
                height = getSize(root, 1, opts);
                domRoot.style.display = '';
                if (this._width !== width || height !== this._height) {
                    domRoot.style.width = width + 'px';
                    domRoot.style.height = height + 'px';
                    for (var id in this._layers) {
                        if (this._layers.hasOwnProperty(id)) {
                            this._layers[id].resize(width, height);
                        }
                    }
                    this.refresh(true);
                }
                this._width = width;
                this._height = height;
            }
            return this;
        };
        CanvasPainter.prototype.clearLayer = function (zlevel) {
            var layer = this._layers[zlevel];
            if (layer) {
                layer.clear();
            }
        };
        CanvasPainter.prototype.dispose = function () {
            this.root.innerHTML = '';
            this.root =
                this.storage =
                    this._domRoot =
                        this._layers = null;
        };
        CanvasPainter.prototype.getRenderedCanvas = function (opts) {
            opts = opts || {};
            if (this._singleCanvas && !this._compositeManually) {
                return this._layers[CANVAS_ZLEVEL].dom;
            }
            var imageLayer = new Layer('image', this, opts.pixelRatio || this.dpr);
            imageLayer.initContext();
            imageLayer.clear(false, opts.backgroundColor || this._backgroundColor);
            var ctx = imageLayer.ctx;
            if (opts.pixelRatio <= this.dpr) {
                this.refresh();
                var width_1 = imageLayer.dom.width;
                var height_1 = imageLayer.dom.height;
                this.eachLayer(function (layer) {
                    if (layer.__builtin__) {
                        ctx.drawImage(layer.dom, 0, 0, width_1, height_1);
                    }
                    else if (layer.renderToCanvas) {
                        ctx.save();
                        layer.renderToCanvas(ctx);
                        ctx.restore();
                    }
                });
            }
            else {
                var scope = {
                    inHover: false,
                    viewWidth: this._width,
                    viewHeight: this._height
                };
                var displayList = this.storage.getDisplayList(true);
                for (var i = 0, len = displayList.length; i < len; i++) {
                    var el = displayList[i];
                    brush(ctx, el, scope, i === len - 1);
                }
            }
            return imageLayer.dom;
        };
        CanvasPainter.prototype.getWidth = function () {
            return this._width;
        };
        CanvasPainter.prototype.getHeight = function () {
            return this._height;
        };
        return CanvasPainter;
    }());

    function install$1(registers) {
      registers.registerPainter('canvas', CanvasPainter);
    }

    var LineSeriesModel =
    /** @class */
    function (_super) {
      __extends(LineSeriesModel, _super);

      function LineSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = LineSeriesModel.type;
        _this.hasSymbolVisual = true;
        return _this;
      }

      LineSeriesModel.prototype.getInitialData = function (option) {
        if ("development" !== 'production') {
          var coordSys = option.coordinateSystem;

          if (coordSys !== 'polar' && coordSys !== 'cartesian2d') {
            throw new Error('Line not support coordinateSystem besides cartesian and polar');
          }
        }

        return createSeriesData(null, this, {
          useEncodeDefaulter: true
        });
      };

      LineSeriesModel.prototype.getLegendIcon = function (opt) {
        var group = new Group();
        var line = createSymbol('line', 0, opt.itemHeight / 2, opt.itemWidth, 0, opt.lineStyle.stroke, false);
        group.add(line);
        line.setStyle(opt.lineStyle);
        var visualType = this.getData().getVisual('symbol');
        var visualRotate = this.getData().getVisual('symbolRotate');
        var symbolType = visualType === 'none' ? 'circle' : visualType; // Symbol size is 80% when there is a line

        var size = opt.itemHeight * 0.8;
        var symbol = createSymbol(symbolType, (opt.itemWidth - size) / 2, (opt.itemHeight - size) / 2, size, size, opt.itemStyle.fill);
        group.add(symbol);
        symbol.setStyle(opt.itemStyle);
        var symbolRotate = opt.iconRotate === 'inherit' ? visualRotate : opt.iconRotate || 0;
        symbol.rotation = symbolRotate * Math.PI / 180;
        symbol.setOrigin([opt.itemWidth / 2, opt.itemHeight / 2]);

        if (symbolType.indexOf('empty') > -1) {
          symbol.style.stroke = symbol.style.fill;
          symbol.style.fill = '#fff';
          symbol.style.lineWidth = 2;
        }

        return group;
      };

      LineSeriesModel.type = 'series.line';
      LineSeriesModel.dependencies = ['grid', 'polar'];
      LineSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 3,
        coordinateSystem: 'cartesian2d',
        legendHoverLink: true,
        clip: true,
        label: {
          position: 'top'
        },
        // itemStyle: {
        // },
        endLabel: {
          show: false,
          valueAnimation: true,
          distance: 8
        },
        lineStyle: {
          width: 2,
          type: 'solid'
        },
        emphasis: {
          scale: true
        },
        // areaStyle: {
        // origin of areaStyle. Valid values:
        // `'auto'/null/undefined`: from axisLine to data
        // `'start'`: from min to data
        // `'end'`: from data to max
        // origin: 'auto'
        // },
        // false, 'start', 'end', 'middle'
        step: false,
        // Disabled if step is true
        smooth: false,
        smoothMonotone: null,
        symbol: 'emptyCircle',
        symbolSize: 4,
        symbolRotate: null,
        showSymbol: true,
        // `false`: follow the label interval strategy.
        // `true`: show all symbols.
        // `'auto'`: If possible, show all symbols, otherwise
        //           follow the label interval strategy.
        showAllSymbol: 'auto',
        // Whether to connect break point.
        connectNulls: false,
        // Sampling for large data. Can be: 'average', 'max', 'min', 'sum', 'lttb'.
        sampling: 'none',
        animationEasing: 'linear',
        // Disable progressive
        progressive: 0,
        hoverLayerThreshold: Infinity,
        universalTransition: {
          divideShape: 'clone'
        },
        triggerLineEvent: false
      };
      return LineSeriesModel;
    }(SeriesModel);

    /**
     * @return label string. Not null/undefined
     */

    function getDefaultLabel(data, dataIndex) {
      var labelDims = data.mapDimensionsAll('defaultedLabel');
      var len = labelDims.length; // Simple optimization (in lots of cases, label dims length is 1)

      if (len === 1) {
        var rawVal = retrieveRawValue(data, dataIndex, labelDims[0]);
        return rawVal != null ? rawVal + '' : null;
      } else if (len) {
        var vals = [];

        for (var i = 0; i < labelDims.length; i++) {
          vals.push(retrieveRawValue(data, dataIndex, labelDims[i]));
        }

        return vals.join(' ');
      }
    }
    function getDefaultInterpolatedLabel(data, interpolatedValue) {
      var labelDims = data.mapDimensionsAll('defaultedLabel');

      if (!isArray(interpolatedValue)) {
        return interpolatedValue + '';
      }

      var vals = [];

      for (var i = 0; i < labelDims.length; i++) {
        var dimIndex = data.getDimensionIndex(labelDims[i]);

        if (dimIndex >= 0) {
          vals.push(interpolatedValue[dimIndex]);
        }
      }

      return vals.join(' ');
    }

    var Symbol =
    /** @class */
    function (_super) {
      __extends(Symbol, _super);

      function Symbol(data, idx, seriesScope, opts) {
        var _this = _super.call(this) || this;

        _this.updateData(data, idx, seriesScope, opts);

        return _this;
      }

      Symbol.prototype._createSymbol = function (symbolType, data, idx, symbolSize, keepAspect) {
        // Remove paths created before
        this.removeAll(); // let symbolPath = createSymbol(
        //     symbolType, -0.5, -0.5, 1, 1, color
        // );
        // If width/height are set too small (e.g., set to 1) on ios10
        // and macOS Sierra, a circle stroke become a rect, no matter what
        // the scale is set. So we set width/height as 2. See #4150.

        var symbolPath = createSymbol(symbolType, -1, -1, 2, 2, null, keepAspect);
        symbolPath.attr({
          z2: 100,
          culling: true,
          scaleX: symbolSize[0] / 2,
          scaleY: symbolSize[1] / 2
        }); // Rewrite drift method

        symbolPath.drift = driftSymbol;
        this._symbolType = symbolType;
        this.add(symbolPath);
      };
      /**
       * Stop animation
       * @param {boolean} toLastFrame
       */


      Symbol.prototype.stopSymbolAnimation = function (toLastFrame) {
        this.childAt(0).stopAnimation(null, toLastFrame);
      };

      Symbol.prototype.getSymbolType = function () {
        return this._symbolType;
      };
      /**
       * FIXME:
       * Caution: This method breaks the encapsulation of this module,
       * but it indeed brings convenience. So do not use the method
       * unless you detailedly know all the implements of `Symbol`,
       * especially animation.
       *
       * Get symbol path element.
       */


      Symbol.prototype.getSymbolPath = function () {
        return this.childAt(0);
      };
      /**
       * Highlight symbol
       */


      Symbol.prototype.highlight = function () {
        enterEmphasis(this.childAt(0));
      };
      /**
       * Downplay symbol
       */


      Symbol.prototype.downplay = function () {
        leaveEmphasis(this.childAt(0));
      };
      /**
       * @param {number} zlevel
       * @param {number} z
       */


      Symbol.prototype.setZ = function (zlevel, z) {
        var symbolPath = this.childAt(0);
        symbolPath.zlevel = zlevel;
        symbolPath.z = z;
      };

      Symbol.prototype.setDraggable = function (draggable, hasCursorOption) {
        var symbolPath = this.childAt(0);
        symbolPath.draggable = draggable;
        symbolPath.cursor = !hasCursorOption && draggable ? 'move' : symbolPath.cursor;
      };
      /**
       * Update symbol properties
       */


      Symbol.prototype.updateData = function (data, idx, seriesScope, opts) {
        this.silent = false;
        var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
        var seriesModel = data.hostModel;
        var symbolSize = Symbol.getSymbolSize(data, idx);
        var isInit = symbolType !== this._symbolType;
        var disableAnimation = opts && opts.disableAnimation;

        if (isInit) {
          var keepAspect = data.getItemVisual(idx, 'symbolKeepAspect');

          this._createSymbol(symbolType, data, idx, symbolSize, keepAspect);
        } else {
          var symbolPath = this.childAt(0);
          symbolPath.silent = false;
          var target = {
            scaleX: symbolSize[0] / 2,
            scaleY: symbolSize[1] / 2
          };
          disableAnimation ? symbolPath.attr(target) : updateProps(symbolPath, target, seriesModel, idx);
          saveOldStyle(symbolPath);
        }

        this._updateCommon(data, idx, symbolSize, seriesScope, opts);

        if (isInit) {
          var symbolPath = this.childAt(0);

          if (!disableAnimation) {
            var target = {
              scaleX: this._sizeX,
              scaleY: this._sizeY,
              style: {
                // Always fadeIn. Because it has fadeOut animation when symbol is removed..
                opacity: symbolPath.style.opacity
              }
            };
            symbolPath.scaleX = symbolPath.scaleY = 0;
            symbolPath.style.opacity = 0;
            initProps(symbolPath, target, seriesModel, idx);
          }
        }

        if (disableAnimation) {
          // Must stop leave transition manually if don't call initProps or updateProps.
          this.childAt(0).stopAnimation('leave');
        }
      };

      Symbol.prototype._updateCommon = function (data, idx, symbolSize, seriesScope, opts) {
        var symbolPath = this.childAt(0);
        var seriesModel = data.hostModel;
        var emphasisItemStyle;
        var blurItemStyle;
        var selectItemStyle;
        var focus;
        var blurScope;
        var emphasisDisabled;
        var labelStatesModels;
        var hoverScale;
        var cursorStyle;

        if (seriesScope) {
          emphasisItemStyle = seriesScope.emphasisItemStyle;
          blurItemStyle = seriesScope.blurItemStyle;
          selectItemStyle = seriesScope.selectItemStyle;
          focus = seriesScope.focus;
          blurScope = seriesScope.blurScope;
          labelStatesModels = seriesScope.labelStatesModels;
          hoverScale = seriesScope.hoverScale;
          cursorStyle = seriesScope.cursorStyle;
          emphasisDisabled = seriesScope.emphasisDisabled;
        }

        if (!seriesScope || data.hasItemOption) {
          var itemModel = seriesScope && seriesScope.itemModel ? seriesScope.itemModel : data.getItemModel(idx);
          var emphasisModel = itemModel.getModel('emphasis');
          emphasisItemStyle = emphasisModel.getModel('itemStyle').getItemStyle();
          selectItemStyle = itemModel.getModel(['select', 'itemStyle']).getItemStyle();
          blurItemStyle = itemModel.getModel(['blur', 'itemStyle']).getItemStyle();
          focus = emphasisModel.get('focus');
          blurScope = emphasisModel.get('blurScope');
          emphasisDisabled = emphasisModel.get('disabled');
          labelStatesModels = getLabelStatesModels(itemModel);
          hoverScale = emphasisModel.getShallow('scale');
          cursorStyle = itemModel.getShallow('cursor');
        }

        var symbolRotate = data.getItemVisual(idx, 'symbolRotate');
        symbolPath.attr('rotation', (symbolRotate || 0) * Math.PI / 180 || 0);
        var symbolOffset = normalizeSymbolOffset(data.getItemVisual(idx, 'symbolOffset'), symbolSize);

        if (symbolOffset) {
          symbolPath.x = symbolOffset[0];
          symbolPath.y = symbolOffset[1];
        }

        cursorStyle && symbolPath.attr('cursor', cursorStyle);
        var symbolStyle = data.getItemVisual(idx, 'style');
        var visualColor = symbolStyle.fill;

        if (symbolPath instanceof ZRImage) {
          var pathStyle = symbolPath.style;
          symbolPath.useStyle(extend({
            // TODO other properties like x, y ?
            image: pathStyle.image,
            x: pathStyle.x,
            y: pathStyle.y,
            width: pathStyle.width,
            height: pathStyle.height
          }, symbolStyle));
        } else {
          if (symbolPath.__isEmptyBrush) {
            // fill and stroke will be swapped if it's empty.
            // So we cloned a new style to avoid it affecting the original style in visual storage.
            // TODO Better implementation. No empty logic!
            symbolPath.useStyle(extend({}, symbolStyle));
          } else {
            symbolPath.useStyle(symbolStyle);
          } // Disable decal because symbol scale will been applied on the decal.


          symbolPath.style.decal = null;
          symbolPath.setColor(visualColor, opts && opts.symbolInnerColor);
          symbolPath.style.strokeNoScale = true;
        }

        var liftZ = data.getItemVisual(idx, 'liftZ');
        var z2Origin = this._z2;

        if (liftZ != null) {
          if (z2Origin == null) {
            this._z2 = symbolPath.z2;
            symbolPath.z2 += liftZ;
          }
        } else if (z2Origin != null) {
          symbolPath.z2 = z2Origin;
          this._z2 = null;
        }

        var useNameLabel = opts && opts.useNameLabel;
        setLabelStyle(symbolPath, labelStatesModels, {
          labelFetcher: seriesModel,
          labelDataIndex: idx,
          defaultText: getLabelDefaultText,
          inheritColor: visualColor,
          defaultOpacity: symbolStyle.opacity
        }); // Do not execute util needed.

        function getLabelDefaultText(idx) {
          return useNameLabel ? data.getName(idx) : getDefaultLabel(data, idx);
        }

        this._sizeX = symbolSize[0] / 2;
        this._sizeY = symbolSize[1] / 2;
        var emphasisState = symbolPath.ensureState('emphasis');
        emphasisState.style = emphasisItemStyle;
        symbolPath.ensureState('select').style = selectItemStyle;
        symbolPath.ensureState('blur').style = blurItemStyle; // null / undefined / true means to use default strategy.
        // 0 / false / negative number / NaN / Infinity means no scale.

        var scaleRatio = hoverScale == null || hoverScale === true ? Math.max(1.1, 3 / this._sizeY) // PENDING: restrict hoverScale > 1? It seems unreasonable to scale down
        : isFinite(hoverScale) && hoverScale > 0 ? +hoverScale : 1; // always set scale to allow resetting

        emphasisState.scaleX = this._sizeX * scaleRatio;
        emphasisState.scaleY = this._sizeY * scaleRatio;
        this.setSymbolScale(1);
        toggleHoverEmphasis(this, focus, blurScope, emphasisDisabled);
      };

      Symbol.prototype.setSymbolScale = function (scale) {
        this.scaleX = this.scaleY = scale;
      };

      Symbol.prototype.fadeOut = function (cb, seriesModel, opt) {
        var symbolPath = this.childAt(0);
        var dataIndex = getECData(this).dataIndex;
        var animationOpt = opt && opt.animation; // Avoid mistaken hover when fading out

        this.silent = symbolPath.silent = true; // Not show text when animating

        if (opt && opt.fadeLabel) {
          var textContent = symbolPath.getTextContent();

          if (textContent) {
            removeElement(textContent, {
              style: {
                opacity: 0
              }
            }, seriesModel, {
              dataIndex: dataIndex,
              removeOpt: animationOpt,
              cb: function () {
                symbolPath.removeTextContent();
              }
            });
          }
        } else {
          symbolPath.removeTextContent();
        }

        removeElement(symbolPath, {
          style: {
            opacity: 0
          },
          scaleX: 0,
          scaleY: 0
        }, seriesModel, {
          dataIndex: dataIndex,
          cb: cb,
          removeOpt: animationOpt
        });
      };

      Symbol.getSymbolSize = function (data, idx) {
        return normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
      };

      return Symbol;
    }(Group);

    function driftSymbol(dx, dy) {
      this.parent.drift(dx, dy);
    }

    function symbolNeedsDraw(data, point, idx, opt) {
      return point && !isNaN(point[0]) && !isNaN(point[1]) && !(opt.isIgnore && opt.isIgnore(idx)) // We do not set clipShape on group, because it will cut part of
      // the symbol element shape. We use the same clip shape here as
      // the line clip.
      && !(opt.clipShape && !opt.clipShape.contain(point[0], point[1])) && data.getItemVisual(idx, 'symbol') !== 'none';
    }

    function normalizeUpdateOpt(opt) {
      if (opt != null && !isObject(opt)) {
        opt = {
          isIgnore: opt
        };
      }

      return opt || {};
    }

    function makeSeriesScope(data) {
      var seriesModel = data.hostModel;
      var emphasisModel = seriesModel.getModel('emphasis');
      return {
        emphasisItemStyle: emphasisModel.getModel('itemStyle').getItemStyle(),
        blurItemStyle: seriesModel.getModel(['blur', 'itemStyle']).getItemStyle(),
        selectItemStyle: seriesModel.getModel(['select', 'itemStyle']).getItemStyle(),
        focus: emphasisModel.get('focus'),
        blurScope: emphasisModel.get('blurScope'),
        emphasisDisabled: emphasisModel.get('disabled'),
        hoverScale: emphasisModel.get('scale'),
        labelStatesModels: getLabelStatesModels(seriesModel),
        cursorStyle: seriesModel.get('cursor')
      };
    }

    var SymbolDraw =
    /** @class */
    function () {
      function SymbolDraw(SymbolCtor) {
        this.group = new Group();
        this._SymbolCtor = SymbolCtor || Symbol;
      }
      /**
       * Update symbols draw by new data
       */


      SymbolDraw.prototype.updateData = function (data, opt) {
        // Remove progressive els.
        this._progressiveEls = null;
        opt = normalizeUpdateOpt(opt);
        var group = this.group;
        var seriesModel = data.hostModel;
        var oldData = this._data;
        var SymbolCtor = this._SymbolCtor;
        var disableAnimation = opt.disableAnimation;
        var seriesScope = makeSeriesScope(data);
        var symbolUpdateOpt = {
          disableAnimation: disableAnimation
        };

        var getSymbolPoint = opt.getSymbolPoint || function (idx) {
          return data.getItemLayout(idx);
        }; // There is no oldLineData only when first rendering or switching from
        // stream mode to normal mode, where previous elements should be removed.


        if (!oldData) {
          group.removeAll();
        }

        data.diff(oldData).add(function (newIdx) {
          var point = getSymbolPoint(newIdx);

          if (symbolNeedsDraw(data, point, newIdx, opt)) {
            var symbolEl = new SymbolCtor(data, newIdx, seriesScope, symbolUpdateOpt);
            symbolEl.setPosition(point);
            data.setItemGraphicEl(newIdx, symbolEl);
            group.add(symbolEl);
          }
        }).update(function (newIdx, oldIdx) {
          var symbolEl = oldData.getItemGraphicEl(oldIdx);
          var point = getSymbolPoint(newIdx);

          if (!symbolNeedsDraw(data, point, newIdx, opt)) {
            group.remove(symbolEl);
            return;
          }

          var newSymbolType = data.getItemVisual(newIdx, 'symbol') || 'circle';
          var oldSymbolType = symbolEl && symbolEl.getSymbolType && symbolEl.getSymbolType();

          if (!symbolEl // Create a new if symbol type changed.
          || oldSymbolType && oldSymbolType !== newSymbolType) {
            group.remove(symbolEl);
            symbolEl = new SymbolCtor(data, newIdx, seriesScope, symbolUpdateOpt);
            symbolEl.setPosition(point);
          } else {
            symbolEl.updateData(data, newIdx, seriesScope, symbolUpdateOpt);
            var target = {
              x: point[0],
              y: point[1]
            };
            disableAnimation ? symbolEl.attr(target) : updateProps(symbolEl, target, seriesModel);
          } // Add back


          group.add(symbolEl);
          data.setItemGraphicEl(newIdx, symbolEl);
        }).remove(function (oldIdx) {
          var el = oldData.getItemGraphicEl(oldIdx);
          el && el.fadeOut(function () {
            group.remove(el);
          }, seriesModel);
        }).execute();
        this._getSymbolPoint = getSymbolPoint;
        this._data = data;
      };

      SymbolDraw.prototype.updateLayout = function () {
        var _this = this;

        var data = this._data;

        if (data) {
          // Not use animation
          data.eachItemGraphicEl(function (el, idx) {
            var point = _this._getSymbolPoint(idx);

            el.setPosition(point);
            el.markRedraw();
          });
        }
      };

      SymbolDraw.prototype.incrementalPrepareUpdate = function (data) {
        this._seriesScope = makeSeriesScope(data);
        this._data = null;
        this.group.removeAll();
      };
      /**
       * Update symbols draw by new data
       */

      SymbolDraw.prototype.incrementalUpdate = function (taskParams, data, opt) {
        // Clear
        this._progressiveEls = [];
        opt = normalizeUpdateOpt(opt);

        function updateIncrementalAndHover(el) {
          if (!el.isGroup) {
            el.incremental = true;
            el.ensureState('emphasis').hoverLayer = true;
          }
        }

        for (var idx = taskParams.start; idx < taskParams.end; idx++) {
          var point = data.getItemLayout(idx);

          if (symbolNeedsDraw(data, point, idx, opt)) {
            var el = new this._SymbolCtor(data, idx, this._seriesScope);
            el.traverse(updateIncrementalAndHover);
            el.setPosition(point);
            this.group.add(el);
            data.setItemGraphicEl(idx, el);

            this._progressiveEls.push(el);
          }
        }
      };

      SymbolDraw.prototype.eachRendered = function (cb) {
        traverseElements(this._progressiveEls || this.group, cb);
      };

      SymbolDraw.prototype.remove = function (enableAnimation) {
        var group = this.group;
        var data = this._data; // Incremental model do not have this._data.

        if (data && enableAnimation) {
          data.eachItemGraphicEl(function (el) {
            el.fadeOut(function () {
              group.remove(el);
            }, data.hostModel);
          });
        } else {
          group.removeAll();
        }
      };
      return SymbolDraw;
    }();

    function prepareDataCoordInfo(coordSys, data, valueOrigin) {
      var baseAxis = coordSys.getBaseAxis();
      var valueAxis = coordSys.getOtherAxis(baseAxis);
      var valueStart = getValueStart(valueAxis, valueOrigin);
      var baseAxisDim = baseAxis.dim;
      var valueAxisDim = valueAxis.dim;
      var valueDim = data.mapDimension(valueAxisDim);
      var baseDim = data.mapDimension(baseAxisDim);
      var baseDataOffset = valueAxisDim === 'x' || valueAxisDim === 'radius' ? 1 : 0;
      var dims = map(coordSys.dimensions, function (coordDim) {
        return data.mapDimension(coordDim);
      });
      var stacked = false;
      var stackResultDim = data.getCalculationInfo('stackResultDimension');

      if (isDimensionStacked(data, dims[0]
      /* , dims[1] */
      )) {
        // jshint ignore:line
        stacked = true;
        dims[0] = stackResultDim;
      }

      if (isDimensionStacked(data, dims[1]
      /* , dims[0] */
      )) {
        // jshint ignore:line
        stacked = true;
        dims[1] = stackResultDim;
      }

      return {
        dataDimsForPoint: dims,
        valueStart: valueStart,
        valueAxisDim: valueAxisDim,
        baseAxisDim: baseAxisDim,
        stacked: !!stacked,
        valueDim: valueDim,
        baseDim: baseDim,
        baseDataOffset: baseDataOffset,
        stackedOverDimension: data.getCalculationInfo('stackedOverDimension')
      };
    }

    function getValueStart(valueAxis, valueOrigin) {
      var valueStart = 0;
      var extent = valueAxis.scale.getExtent();

      if (valueOrigin === 'start') {
        valueStart = extent[0];
      } else if (valueOrigin === 'end') {
        valueStart = extent[1];
      } // If origin is specified as a number, use it as
      // valueStart directly
      else if (isNumber(valueOrigin) && !isNaN(valueOrigin)) {
          valueStart = valueOrigin;
        } // auto
        else {
            // Both positive
            if (extent[0] > 0) {
              valueStart = extent[0];
            } // Both negative
            else if (extent[1] < 0) {
                valueStart = extent[1];
              } // If is one positive, and one negative, onZero shall be true

          }

      return valueStart;
    }

    function getStackedOnPoint(dataCoordInfo, coordSys, data, idx) {
      var value = NaN;

      if (dataCoordInfo.stacked) {
        value = data.get(data.getCalculationInfo('stackedOverDimension'), idx);
      }

      if (isNaN(value)) {
        value = dataCoordInfo.valueStart;
      }

      var baseDataOffset = dataCoordInfo.baseDataOffset;
      var stackedData = [];
      stackedData[baseDataOffset] = data.get(dataCoordInfo.baseDim, idx);
      stackedData[1 - baseDataOffset] = value;
      return coordSys.dataToPoint(stackedData);
    }

    function diffData(oldData, newData) {
      var diffResult = [];
      newData.diff(oldData).add(function (idx) {
        diffResult.push({
          cmd: '+',
          idx: idx
        });
      }).update(function (newIdx, oldIdx) {
        diffResult.push({
          cmd: '=',
          idx: oldIdx,
          idx1: newIdx
        });
      }).remove(function (idx) {
        diffResult.push({
          cmd: '-',
          idx: idx
        });
      }).execute();
      return diffResult;
    }

    function lineAnimationDiff(oldData, newData, oldStackedOnPoints, newStackedOnPoints, oldCoordSys, newCoordSys, oldValueOrigin, newValueOrigin) {
      var diff = diffData(oldData, newData); // let newIdList = newData.mapArray(newData.getId);
      // let oldIdList = oldData.mapArray(oldData.getId);
      // convertToIntId(newIdList, oldIdList);
      // // FIXME One data ?
      // diff = arrayDiff(oldIdList, newIdList);

      var currPoints = [];
      var nextPoints = []; // Points for stacking base line

      var currStackedPoints = [];
      var nextStackedPoints = [];
      var status = [];
      var sortedIndices = [];
      var rawIndices = [];
      var newDataOldCoordInfo = prepareDataCoordInfo(oldCoordSys, newData, oldValueOrigin); // const oldDataNewCoordInfo = prepareDataCoordInfo(newCoordSys, oldData, newValueOrigin);

      var oldPoints = oldData.getLayout('points') || [];
      var newPoints = newData.getLayout('points') || [];

      for (var i = 0; i < diff.length; i++) {
        var diffItem = diff[i];
        var pointAdded = true;
        var oldIdx2 = void 0;
        var newIdx2 = void 0; // FIXME, animation is not so perfect when dataZoom window moves fast
        // Which is in case remvoing or add more than one data in the tail or head

        switch (diffItem.cmd) {
          case '=':
            oldIdx2 = diffItem.idx * 2;
            newIdx2 = diffItem.idx1 * 2;
            var currentX = oldPoints[oldIdx2];
            var currentY = oldPoints[oldIdx2 + 1];
            var nextX = newPoints[newIdx2];
            var nextY = newPoints[newIdx2 + 1]; // If previous data is NaN, use next point directly

            if (isNaN(currentX) || isNaN(currentY)) {
              currentX = nextX;
              currentY = nextY;
            }

            currPoints.push(currentX, currentY);
            nextPoints.push(nextX, nextY);
            currStackedPoints.push(oldStackedOnPoints[oldIdx2], oldStackedOnPoints[oldIdx2 + 1]);
            nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]);
            rawIndices.push(newData.getRawIndex(diffItem.idx1));
            break;

          case '+':
            var newIdx = diffItem.idx;
            var newDataDimsForPoint = newDataOldCoordInfo.dataDimsForPoint;
            var oldPt = oldCoordSys.dataToPoint([newData.get(newDataDimsForPoint[0], newIdx), newData.get(newDataDimsForPoint[1], newIdx)]);
            newIdx2 = newIdx * 2;
            currPoints.push(oldPt[0], oldPt[1]);
            nextPoints.push(newPoints[newIdx2], newPoints[newIdx2 + 1]);
            var stackedOnPoint = getStackedOnPoint(newDataOldCoordInfo, oldCoordSys, newData, newIdx);
            currStackedPoints.push(stackedOnPoint[0], stackedOnPoint[1]);
            nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]);
            rawIndices.push(newData.getRawIndex(newIdx));
            break;

          case '-':
            pointAdded = false;
        } // Original indices


        if (pointAdded) {
          status.push(diffItem);
          sortedIndices.push(sortedIndices.length);
        }
      } // Diff result may be crossed if all items are changed
      // Sort by data index


      sortedIndices.sort(function (a, b) {
        return rawIndices[a] - rawIndices[b];
      });
      var len = currPoints.length;
      var sortedCurrPoints = createFloat32Array(len);
      var sortedNextPoints = createFloat32Array(len);
      var sortedCurrStackedPoints = createFloat32Array(len);
      var sortedNextStackedPoints = createFloat32Array(len);
      var sortedStatus = [];

      for (var i = 0; i < sortedIndices.length; i++) {
        var idx = sortedIndices[i];
        var i2 = i * 2;
        var idx2 = idx * 2;
        sortedCurrPoints[i2] = currPoints[idx2];
        sortedCurrPoints[i2 + 1] = currPoints[idx2 + 1];
        sortedNextPoints[i2] = nextPoints[idx2];
        sortedNextPoints[i2 + 1] = nextPoints[idx2 + 1];
        sortedCurrStackedPoints[i2] = currStackedPoints[idx2];
        sortedCurrStackedPoints[i2 + 1] = currStackedPoints[idx2 + 1];
        sortedNextStackedPoints[i2] = nextStackedPoints[idx2];
        sortedNextStackedPoints[i2 + 1] = nextStackedPoints[idx2 + 1];
        sortedStatus[i] = status[idx];
      }

      return {
        current: sortedCurrPoints,
        next: sortedNextPoints,
        stackedOnCurrent: sortedCurrStackedPoints,
        stackedOnNext: sortedNextStackedPoints,
        status: sortedStatus
      };
    }

    var mathMin$5 = Math.min;
    var mathMax$5 = Math.max;

    function isPointNull(x, y) {
      return isNaN(x) || isNaN(y);
    }
    /**
     * Draw smoothed line in non-monotone, in may cause undesired curve in extreme
     * situations. This should be used when points are non-monotone neither in x or
     * y dimension.
     */


    function drawSegment(ctx, points, start, segLen, allLen, dir, smooth, smoothMonotone, connectNulls) {
      var prevX;
      var prevY;
      var cpx0;
      var cpy0;
      var cpx1;
      var cpy1;
      var idx = start;
      var k = 0;

      for (; k < segLen; k++) {
        var x = points[idx * 2];
        var y = points[idx * 2 + 1];

        if (idx >= allLen || idx < 0) {
          break;
        }

        if (isPointNull(x, y)) {
          if (connectNulls) {
            idx += dir;
            continue;
          }

          break;
        }

        if (idx === start) {
          ctx[dir > 0 ? 'moveTo' : 'lineTo'](x, y);
          cpx0 = x;
          cpy0 = y;
        } else {
          var dx = x - prevX;
          var dy = y - prevY; // Ignore tiny segment.

          if (dx * dx + dy * dy < 0.5) {
            idx += dir;
            continue;
          }

          if (smooth > 0) {
            var nextIdx = idx + dir;
            var nextX = points[nextIdx * 2];
            var nextY = points[nextIdx * 2 + 1]; // Ignore duplicate point

            while (nextX === x && nextY === y && k < segLen) {
              k++;
              nextIdx += dir;
              idx += dir;
              nextX = points[nextIdx * 2];
              nextY = points[nextIdx * 2 + 1];
              x = points[idx * 2];
              y = points[idx * 2 + 1];
              dx = x - prevX;
              dy = y - prevY;
            }

            var tmpK = k + 1;

            if (connectNulls) {
              // Find next point not null
              while (isPointNull(nextX, nextY) && tmpK < segLen) {
                tmpK++;
                nextIdx += dir;
                nextX = points[nextIdx * 2];
                nextY = points[nextIdx * 2 + 1];
              }
            }

            var ratioNextSeg = 0.5;
            var vx = 0;
            var vy = 0;
            var nextCpx0 = void 0;
            var nextCpy0 = void 0; // Is last point

            if (tmpK >= segLen || isPointNull(nextX, nextY)) {
              cpx1 = x;
              cpy1 = y;
            } else {
              vx = nextX - prevX;
              vy = nextY - prevY;
              var dx0 = x - prevX;
              var dx1 = nextX - x;
              var dy0 = y - prevY;
              var dy1 = nextY - y;
              var lenPrevSeg = void 0;
              var lenNextSeg = void 0;

              if (smoothMonotone === 'x') {
                lenPrevSeg = Math.abs(dx0);
                lenNextSeg = Math.abs(dx1);
                var dir_1 = vx > 0 ? 1 : -1;
                cpx1 = x - dir_1 * lenPrevSeg * smooth;
                cpy1 = y;
                nextCpx0 = x + dir_1 * lenNextSeg * smooth;
                nextCpy0 = y;
              } else if (smoothMonotone === 'y') {
                lenPrevSeg = Math.abs(dy0);
                lenNextSeg = Math.abs(dy1);
                var dir_2 = vy > 0 ? 1 : -1;
                cpx1 = x;
                cpy1 = y - dir_2 * lenPrevSeg * smooth;
                nextCpx0 = x;
                nextCpy0 = y + dir_2 * lenNextSeg * smooth;
              } else {
                lenPrevSeg = Math.sqrt(dx0 * dx0 + dy0 * dy0);
                lenNextSeg = Math.sqrt(dx1 * dx1 + dy1 * dy1); // Use ratio of seg length

                ratioNextSeg = lenNextSeg / (lenNextSeg + lenPrevSeg);
                cpx1 = x - vx * smooth * (1 - ratioNextSeg);
                cpy1 = y - vy * smooth * (1 - ratioNextSeg); // cp0 of next segment

                nextCpx0 = x + vx * smooth * ratioNextSeg;
                nextCpy0 = y + vy * smooth * ratioNextSeg; // Smooth constraint between point and next point.
                // Avoid exceeding extreme after smoothing.

                nextCpx0 = mathMin$5(nextCpx0, mathMax$5(nextX, x));
                nextCpy0 = mathMin$5(nextCpy0, mathMax$5(nextY, y));
                nextCpx0 = mathMax$5(nextCpx0, mathMin$5(nextX, x));
                nextCpy0 = mathMax$5(nextCpy0, mathMin$5(nextY, y)); // Reclaculate cp1 based on the adjusted cp0 of next seg.

                vx = nextCpx0 - x;
                vy = nextCpy0 - y;
                cpx1 = x - vx * lenPrevSeg / lenNextSeg;
                cpy1 = y - vy * lenPrevSeg / lenNextSeg; // Smooth constraint between point and prev point.
                // Avoid exceeding extreme after smoothing.

                cpx1 = mathMin$5(cpx1, mathMax$5(prevX, x));
                cpy1 = mathMin$5(cpy1, mathMax$5(prevY, y));
                cpx1 = mathMax$5(cpx1, mathMin$5(prevX, x));
                cpy1 = mathMax$5(cpy1, mathMin$5(prevY, y)); // Adjust next cp0 again.

                vx = x - cpx1;
                vy = y - cpy1;
                nextCpx0 = x + vx * lenNextSeg / lenPrevSeg;
                nextCpy0 = y + vy * lenNextSeg / lenPrevSeg;
              }
            }

            ctx.bezierCurveTo(cpx0, cpy0, cpx1, cpy1, x, y);
            cpx0 = nextCpx0;
            cpy0 = nextCpy0;
          } else {
            ctx.lineTo(x, y);
          }
        }

        prevX = x;
        prevY = y;
        idx += dir;
      }

      return k;
    }

    var ECPolylineShape =
    /** @class */
    function () {
      function ECPolylineShape() {
        this.smooth = 0;
        this.smoothConstraint = true;
      }

      return ECPolylineShape;
    }();

    var ECPolyline =
    /** @class */
    function (_super) {
      __extends(ECPolyline, _super);

      function ECPolyline(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'ec-polyline';
        return _this;
      }

      ECPolyline.prototype.getDefaultStyle = function () {
        return {
          stroke: '#000',
          fill: null
        };
      };

      ECPolyline.prototype.getDefaultShape = function () {
        return new ECPolylineShape();
      };

      ECPolyline.prototype.buildPath = function (ctx, shape) {
        var points = shape.points;
        var i = 0;
        var len = points.length / 2; // const result = getBoundingBox(points, shape.smoothConstraint);

        if (shape.connectNulls) {
          // Must remove first and last null values avoid draw error in polygon
          for (; len > 0; len--) {
            if (!isPointNull(points[len * 2 - 2], points[len * 2 - 1])) {
              break;
            }
          }

          for (; i < len; i++) {
            if (!isPointNull(points[i * 2], points[i * 2 + 1])) {
              break;
            }
          }
        }

        while (i < len) {
          i += drawSegment(ctx, points, i, len, len, 1, shape.smooth, shape.smoothMonotone, shape.connectNulls) + 1;
        }
      };

      ECPolyline.prototype.getPointOn = function (xOrY, dim) {
        if (!this.path) {
          this.createPathProxy();
          this.buildPath(this.path, this.shape);
        }

        var path = this.path;
        var data = path.data;
        var CMD = PathProxy.CMD;
        var x0;
        var y0;
        var isDimX = dim === 'x';
        var roots = [];

        for (var i = 0; i < data.length;) {
          var cmd = data[i++];
          var x = void 0;
          var y = void 0;
          var x2 = void 0;
          var y2 = void 0;
          var x3 = void 0;
          var y3 = void 0;
          var t = void 0;

          switch (cmd) {
            case CMD.M:
              x0 = data[i++];
              y0 = data[i++];
              break;

            case CMD.L:
              x = data[i++];
              y = data[i++];
              t = isDimX ? (xOrY - x0) / (x - x0) : (xOrY - y0) / (y - y0);

              if (t <= 1 && t >= 0) {
                var val = isDimX ? (y - y0) * t + y0 : (x - x0) * t + x0;
                return isDimX ? [xOrY, val] : [val, xOrY];
              }

              x0 = x;
              y0 = y;
              break;

            case CMD.C:
              x = data[i++];
              y = data[i++];
              x2 = data[i++];
              y2 = data[i++];
              x3 = data[i++];
              y3 = data[i++];
              var nRoot = isDimX ? cubicRootAt(x0, x, x2, x3, xOrY, roots) : cubicRootAt(y0, y, y2, y3, xOrY, roots);

              if (nRoot > 0) {
                for (var i_1 = 0; i_1 < nRoot; i_1++) {
                  var t_1 = roots[i_1];

                  if (t_1 <= 1 && t_1 >= 0) {
                    var val = isDimX ? cubicAt(y0, y, y2, y3, t_1) : cubicAt(x0, x, x2, x3, t_1);
                    return isDimX ? [xOrY, val] : [val, xOrY];
                  }
                }
              }

              x0 = x3;
              y0 = y3;
              break;
          }
        }
      };

      return ECPolyline;
    }(Path);

    var ECPolygonShape =
    /** @class */
    function (_super) {
      __extends(ECPolygonShape, _super);

      function ECPolygonShape() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      return ECPolygonShape;
    }(ECPolylineShape);

    var ECPolygon =
    /** @class */
    function (_super) {
      __extends(ECPolygon, _super);

      function ECPolygon(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'ec-polygon';
        return _this;
      }

      ECPolygon.prototype.getDefaultShape = function () {
        return new ECPolygonShape();
      };

      ECPolygon.prototype.buildPath = function (ctx, shape) {
        var points = shape.points;
        var stackedOnPoints = shape.stackedOnPoints;
        var i = 0;
        var len = points.length / 2;
        var smoothMonotone = shape.smoothMonotone;

        if (shape.connectNulls) {
          // Must remove first and last null values avoid draw error in polygon
          for (; len > 0; len--) {
            if (!isPointNull(points[len * 2 - 2], points[len * 2 - 1])) {
              break;
            }
          }

          for (; i < len; i++) {
            if (!isPointNull(points[i * 2], points[i * 2 + 1])) {
              break;
            }
          }
        }

        while (i < len) {
          var k = drawSegment(ctx, points, i, len, len, 1, shape.smooth, smoothMonotone, shape.connectNulls);
          drawSegment(ctx, stackedOnPoints, i + k - 1, k, len, -1, shape.stackedOnSmooth, smoothMonotone, shape.connectNulls);
          i += k + 1;
          ctx.closePath();
        }
      };

      return ECPolygon;
    }(Path);

    function createGridClipPath(cartesian, hasAnimation, seriesModel, done, during) {
      var rect = cartesian.getArea();
      var x = rect.x;
      var y = rect.y;
      var width = rect.width;
      var height = rect.height;
      var lineWidth = seriesModel.get(['lineStyle', 'width']) || 2; // Expand the clip path a bit to avoid the border is clipped and looks thinner

      x -= lineWidth / 2;
      y -= lineWidth / 2;
      width += lineWidth;
      height += lineWidth; // fix: https://github.com/apache/incubator-echarts/issues/11369

      x = Math.floor(x);
      width = Math.round(width);
      var clipPath = new Rect({
        shape: {
          x: x,
          y: y,
          width: width,
          height: height
        }
      });

      if (hasAnimation) {
        var baseAxis = cartesian.getBaseAxis();
        var isHorizontal = baseAxis.isHorizontal();
        var isAxisInversed = baseAxis.inverse;

        if (isHorizontal) {
          if (isAxisInversed) {
            clipPath.shape.x += width;
          }

          clipPath.shape.width = 0;
        } else {
          if (!isAxisInversed) {
            clipPath.shape.y += height;
          }

          clipPath.shape.height = 0;
        }

        var duringCb = isFunction(during) ? function (percent) {
          during(percent, clipPath);
        } : null;
        initProps(clipPath, {
          shape: {
            width: width,
            height: height,
            x: x,
            y: y
          }
        }, seriesModel, null, done, duringCb);
      }

      return clipPath;
    }

    function createPolarClipPath(polar, hasAnimation, seriesModel) {
      var sectorArea = polar.getArea(); // Avoid float number rounding error for symbol on the edge of axis extent.

      var r0 = round(sectorArea.r0, 1);
      var r = round(sectorArea.r, 1);
      var clipPath = new Sector({
        shape: {
          cx: round(polar.cx, 1),
          cy: round(polar.cy, 1),
          r0: r0,
          r: r,
          startAngle: sectorArea.startAngle,
          endAngle: sectorArea.endAngle,
          clockwise: sectorArea.clockwise
        }
      });

      if (hasAnimation) {
        var isRadial = polar.getBaseAxis().dim === 'angle';

        if (isRadial) {
          clipPath.shape.endAngle = sectorArea.startAngle;
        } else {
          clipPath.shape.r = r0;
        }

        initProps(clipPath, {
          shape: {
            endAngle: sectorArea.endAngle,
            r: r
          }
        }, seriesModel);
      }

      return clipPath;
    }

    function createClipPath(coordSys, hasAnimation, seriesModel, done, during) {
      if (!coordSys) {
        return null;
      } else if (coordSys.type === 'polar') {
        return createPolarClipPath(coordSys, hasAnimation, seriesModel);
      } else if (coordSys.type === 'cartesian2d') {
        return createGridClipPath(coordSys, hasAnimation, seriesModel, done, during);
      }

      return null;
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    function isCoordinateSystemType(coordSys, type) {
      return coordSys.type === type;
    }

    function isPointsSame(points1, points2) {
      if (points1.length !== points2.length) {
        return;
      }

      for (var i = 0; i < points1.length; i++) {
        if (points1[i] !== points2[i]) {
          return;
        }
      }

      return true;
    }

    function bboxFromPoints(points) {
      var minX = Infinity;
      var minY = Infinity;
      var maxX = -Infinity;
      var maxY = -Infinity;

      for (var i = 0; i < points.length;) {
        var x = points[i++];
        var y = points[i++];

        if (!isNaN(x)) {
          minX = Math.min(x, minX);
          maxX = Math.max(x, maxX);
        }

        if (!isNaN(y)) {
          minY = Math.min(y, minY);
          maxY = Math.max(y, maxY);
        }
      }

      return [[minX, minY], [maxX, maxY]];
    }

    function getBoundingDiff(points1, points2) {
      var _a = bboxFromPoints(points1),
          min1 = _a[0],
          max1 = _a[1];

      var _b = bboxFromPoints(points2),
          min2 = _b[0],
          max2 = _b[1]; // Get a max value from each corner of two boundings.


      return Math.max(Math.abs(min1[0] - min2[0]), Math.abs(min1[1] - min2[1]), Math.abs(max1[0] - max2[0]), Math.abs(max1[1] - max2[1]));
    }

    function getSmooth(smooth) {
      return isNumber(smooth) ? smooth : smooth ? 0.5 : 0;
    }

    function getStackedOnPoints(coordSys, data, dataCoordInfo) {
      if (!dataCoordInfo.valueDim) {
        return [];
      }

      var len = data.count();
      var points = createFloat32Array(len * 2);

      for (var idx = 0; idx < len; idx++) {
        var pt = getStackedOnPoint(dataCoordInfo, coordSys, data, idx);
        points[idx * 2] = pt[0];
        points[idx * 2 + 1] = pt[1];
      }

      return points;
    }

    function turnPointsIntoStep(points, coordSys, stepTurnAt, connectNulls) {
      var baseAxis = coordSys.getBaseAxis();
      var baseIndex = baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1;
      var stepPoints = [];
      var i = 0;
      var stepPt = [];
      var pt = [];
      var nextPt = [];
      var filteredPoints = [];

      if (connectNulls) {
        for (i = 0; i < points.length; i += 2) {
          if (!isNaN(points[i]) && !isNaN(points[i + 1])) {
            filteredPoints.push(points[i], points[i + 1]);
          }
        }

        points = filteredPoints;
      }

      for (i = 0; i < points.length - 2; i += 2) {
        nextPt[0] = points[i + 2];
        nextPt[1] = points[i + 3];
        pt[0] = points[i];
        pt[1] = points[i + 1];
        stepPoints.push(pt[0], pt[1]);

        switch (stepTurnAt) {
          case 'end':
            stepPt[baseIndex] = nextPt[baseIndex];
            stepPt[1 - baseIndex] = pt[1 - baseIndex];
            stepPoints.push(stepPt[0], stepPt[1]);
            break;

          case 'middle':
            var middle = (pt[baseIndex] + nextPt[baseIndex]) / 2;
            var stepPt2 = [];
            stepPt[baseIndex] = stepPt2[baseIndex] = middle;
            stepPt[1 - baseIndex] = pt[1 - baseIndex];
            stepPt2[1 - baseIndex] = nextPt[1 - baseIndex];
            stepPoints.push(stepPt[0], stepPt[1]);
            stepPoints.push(stepPt2[0], stepPt2[1]);
            break;

          default:
            // default is start
            stepPt[baseIndex] = pt[baseIndex];
            stepPt[1 - baseIndex] = nextPt[1 - baseIndex];
            stepPoints.push(stepPt[0], stepPt[1]);
        }
      } // Last points


      stepPoints.push(points[i++], points[i++]);
      return stepPoints;
    }
    /**
     * Clip color stops to edge. Avoid creating too large gradients.
     * Which may lead to blurry when GPU acceleration is enabled. See #15680
     *
     * The stops has been sorted from small to large.
     */


    function clipColorStops(colorStops, maxSize) {
      var newColorStops = [];
      var len = colorStops.length; // coord will always < 0 in prevOutOfRangeColorStop.

      var prevOutOfRangeColorStop;
      var prevInRangeColorStop;

      function lerpStop(stop0, stop1, clippedCoord) {
        var coord0 = stop0.coord;
        var p = (clippedCoord - coord0) / (stop1.coord - coord0);
        var color = lerp$1(p, [stop0.color, stop1.color]);
        return {
          coord: clippedCoord,
          color: color
        };
      }

      for (var i = 0; i < len; i++) {
        var stop_1 = colorStops[i];
        var coord = stop_1.coord;

        if (coord < 0) {
          prevOutOfRangeColorStop = stop_1;
        } else if (coord > maxSize) {
          if (prevInRangeColorStop) {
            newColorStops.push(lerpStop(prevInRangeColorStop, stop_1, maxSize));
          } else if (prevOutOfRangeColorStop) {
            // If there are two stops and coord range is between these two stops
            newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0), lerpStop(prevOutOfRangeColorStop, stop_1, maxSize));
          } // All following stop will be out of range. So just ignore them.


          break;
        } else {
          if (prevOutOfRangeColorStop) {
            newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0)); // Reset

            prevOutOfRangeColorStop = null;
          }

          newColorStops.push(stop_1);
          prevInRangeColorStop = stop_1;
        }
      }

      return newColorStops;
    }

    function getVisualGradient(data, coordSys, api) {
      var visualMetaList = data.getVisual('visualMeta');

      if (!visualMetaList || !visualMetaList.length || !data.count()) {
        // When data.count() is 0, gradient range can not be calculated.
        return;
      }

      if (coordSys.type !== 'cartesian2d') {
        if ("development" !== 'production') {
          console.warn('Visual map on line style is only supported on cartesian2d.');
        }

        return;
      }

      var coordDim;
      var visualMeta;

      for (var i = visualMetaList.length - 1; i >= 0; i--) {
        var dimInfo = data.getDimensionInfo(visualMetaList[i].dimension);
        coordDim = dimInfo && dimInfo.coordDim; // Can only be x or y

        if (coordDim === 'x' || coordDim === 'y') {
          visualMeta = visualMetaList[i];
          break;
        }
      }

      if (!visualMeta) {
        if ("development" !== 'production') {
          console.warn('Visual map on line style only support x or y dimension.');
        }

        return;
      } // If the area to be rendered is bigger than area defined by LinearGradient,
      // the canvas spec prescribes that the color of the first stop and the last
      // stop should be used. But if two stops are added at offset 0, in effect
      // browsers use the color of the second stop to render area outside
      // LinearGradient. So we can only infinitesimally extend area defined in
      // LinearGradient to render `outerColors`.


      var axis = coordSys.getAxis(coordDim); // dataToCoord mapping may not be linear, but must be monotonic.

      var colorStops = map(visualMeta.stops, function (stop) {
        // offset will be calculated later.
        return {
          coord: axis.toGlobalCoord(axis.dataToCoord(stop.value)),
          color: stop.color
        };
      });
      var stopLen = colorStops.length;
      var outerColors = visualMeta.outerColors.slice();

      if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) {
        colorStops.reverse();
        outerColors.reverse();
      }

      var colorStopsInRange = clipColorStops(colorStops, coordDim === 'x' ? api.getWidth() : api.getHeight());
      var inRangeStopLen = colorStopsInRange.length;

      if (!inRangeStopLen && stopLen) {
        // All stops are out of range. All will be the same color.
        return colorStops[0].coord < 0 ? outerColors[1] ? outerColors[1] : colorStops[stopLen - 1].color : outerColors[0] ? outerColors[0] : colorStops[0].color;
      }

      var tinyExtent = 10; // Arbitrary value: 10px

      var minCoord = colorStopsInRange[0].coord - tinyExtent;
      var maxCoord = colorStopsInRange[inRangeStopLen - 1].coord + tinyExtent;
      var coordSpan = maxCoord - minCoord;

      if (coordSpan < 1e-3) {
        return 'transparent';
      }

      each(colorStopsInRange, function (stop) {
        stop.offset = (stop.coord - minCoord) / coordSpan;
      });
      colorStopsInRange.push({
        // NOTE: inRangeStopLen may still be 0 if stoplen is zero.
        offset: inRangeStopLen ? colorStopsInRange[inRangeStopLen - 1].offset : 0.5,
        color: outerColors[1] || 'transparent'
      });
      colorStopsInRange.unshift({
        offset: inRangeStopLen ? colorStopsInRange[0].offset : 0.5,
        color: outerColors[0] || 'transparent'
      });
      var gradient = new LinearGradient(0, 0, 0, 0, colorStopsInRange, true);
      gradient[coordDim] = minCoord;
      gradient[coordDim + '2'] = maxCoord;
      return gradient;
    }

    function getIsIgnoreFunc(seriesModel, data, coordSys) {
      var showAllSymbol = seriesModel.get('showAllSymbol');
      var isAuto = showAllSymbol === 'auto';

      if (showAllSymbol && !isAuto) {
        return;
      }

      var categoryAxis = coordSys.getAxesByScale('ordinal')[0];

      if (!categoryAxis) {
        return;
      } // Note that category label interval strategy might bring some weird effect
      // in some scenario: users may wonder why some of the symbols are not
      // displayed. So we show all symbols as possible as we can.


      if (isAuto // Simplify the logic, do not determine label overlap here.
      && canShowAllSymbolForCategory(categoryAxis, data)) {
        return;
      } // Otherwise follow the label interval strategy on category axis.


      var categoryDataDim = data.mapDimension(categoryAxis.dim);
      var labelMap = {};
      each(categoryAxis.getViewLabels(), function (labelItem) {
        var ordinalNumber = categoryAxis.scale.getRawOrdinalNumber(labelItem.tickValue);
        labelMap[ordinalNumber] = 1;
      });
      return function (dataIndex) {
        return !labelMap.hasOwnProperty(data.get(categoryDataDim, dataIndex));
      };
    }

    function canShowAllSymbolForCategory(categoryAxis, data) {
      // In most cases, line is monotonous on category axis, and the label size
      // is close with each other. So we check the symbol size and some of the
      // label size alone with the category axis to estimate whether all symbol
      // can be shown without overlap.
      var axisExtent = categoryAxis.getExtent();
      var availSize = Math.abs(axisExtent[1] - axisExtent[0]) / categoryAxis.scale.count();
      isNaN(availSize) && (availSize = 0); // 0/0 is NaN.
      // Sampling some points, max 5.

      var dataLen = data.count();
      var step = Math.max(1, Math.round(dataLen / 5));

      for (var dataIndex = 0; dataIndex < dataLen; dataIndex += step) {
        if (Symbol.getSymbolSize(data, dataIndex // Only for cartesian, where `isHorizontal` exists.
        )[categoryAxis.isHorizontal() ? 1 : 0] // Empirical number
        * 1.5 > availSize) {
          return false;
        }
      }

      return true;
    }

    function isPointNull$1(x, y) {
      return isNaN(x) || isNaN(y);
    }

    function getLastIndexNotNull(points) {
      var len = points.length / 2;

      for (; len > 0; len--) {
        if (!isPointNull$1(points[len * 2 - 2], points[len * 2 - 1])) {
          break;
        }
      }

      return len - 1;
    }

    function getPointAtIndex(points, idx) {
      return [points[idx * 2], points[idx * 2 + 1]];
    }

    function getIndexRange(points, xOrY, dim) {
      var len = points.length / 2;
      var dimIdx = dim === 'x' ? 0 : 1;
      var a;
      var b;
      var prevIndex = 0;
      var nextIndex = -1;

      for (var i = 0; i < len; i++) {
        b = points[i * 2 + dimIdx];

        if (isNaN(b) || isNaN(points[i * 2 + 1 - dimIdx])) {
          continue;
        }

        if (i === 0) {
          a = b;
          continue;
        }

        if (a <= xOrY && b >= xOrY || a >= xOrY && b <= xOrY) {
          nextIndex = i;
          break;
        }

        prevIndex = i;
        a = b;
      }

      return {
        range: [prevIndex, nextIndex],
        t: (xOrY - a) / (b - a)
      };
    }

    function anyStateShowEndLabel(seriesModel) {
      if (seriesModel.get(['endLabel', 'show'])) {
        return true;
      }

      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        if (seriesModel.get([SPECIAL_STATES[i], 'endLabel', 'show'])) {
          return true;
        }
      }

      return false;
    }

    function createLineClipPath(lineView, coordSys, hasAnimation, seriesModel) {
      if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
        var endLabelModel_1 = seriesModel.getModel('endLabel');
        var valueAnimation_1 = endLabelModel_1.get('valueAnimation');
        var data_1 = seriesModel.getData();
        var labelAnimationRecord_1 = {
          lastFrameIndex: 0
        };
        var during = anyStateShowEndLabel(seriesModel) ? function (percent, clipRect) {
          lineView._endLabelOnDuring(percent, clipRect, data_1, labelAnimationRecord_1, valueAnimation_1, endLabelModel_1, coordSys);
        } : null;
        var isHorizontal = coordSys.getBaseAxis().isHorizontal();
        var clipPath = createGridClipPath(coordSys, hasAnimation, seriesModel, function () {
          var endLabel = lineView._endLabel;

          if (endLabel && hasAnimation) {
            if (labelAnimationRecord_1.originalX != null) {
              endLabel.attr({
                x: labelAnimationRecord_1.originalX,
                y: labelAnimationRecord_1.originalY
              });
            }
          }
        }, during); // Expand clip shape to avoid clipping when line value exceeds axis

        if (!seriesModel.get('clip', true)) {
          var rectShape = clipPath.shape;
          var expandSize = Math.max(rectShape.width, rectShape.height);

          if (isHorizontal) {
            rectShape.y -= expandSize;
            rectShape.height += expandSize * 2;
          } else {
            rectShape.x -= expandSize;
            rectShape.width += expandSize * 2;
          }
        } // Set to the final frame. To make sure label layout is right.


        if (during) {
          during(1, clipPath);
        }

        return clipPath;
      } else {
        if ("development" !== 'production') {
          if (seriesModel.get(['endLabel', 'show'])) {
            console.warn('endLabel is not supported for lines in polar systems.');
          }
        }

        return createPolarClipPath(coordSys, hasAnimation, seriesModel);
      }
    }

    function getEndLabelStateSpecified(endLabelModel, coordSys) {
      var baseAxis = coordSys.getBaseAxis();
      var isHorizontal = baseAxis.isHorizontal();
      var isBaseInversed = baseAxis.inverse;
      var align = isHorizontal ? isBaseInversed ? 'right' : 'left' : 'center';
      var verticalAlign = isHorizontal ? 'middle' : isBaseInversed ? 'top' : 'bottom';
      return {
        normal: {
          align: endLabelModel.get('align') || align,
          verticalAlign: endLabelModel.get('verticalAlign') || verticalAlign
        }
      };
    }

    var LineView =
    /** @class */
    function (_super) {
      __extends(LineView, _super);

      function LineView() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      LineView.prototype.init = function () {
        var lineGroup = new Group();
        var symbolDraw = new SymbolDraw();
        this.group.add(symbolDraw.group);
        this._symbolDraw = symbolDraw;
        this._lineGroup = lineGroup;
      };

      LineView.prototype.render = function (seriesModel, ecModel, api) {
        var _this = this;

        var coordSys = seriesModel.coordinateSystem;
        var group = this.group;
        var data = seriesModel.getData();
        var lineStyleModel = seriesModel.getModel('lineStyle');
        var areaStyleModel = seriesModel.getModel('areaStyle');
        var points = data.getLayout('points') || [];
        var isCoordSysPolar = coordSys.type === 'polar';
        var prevCoordSys = this._coordSys;
        var symbolDraw = this._symbolDraw;
        var polyline = this._polyline;
        var polygon = this._polygon;
        var lineGroup = this._lineGroup;
        var hasAnimation = seriesModel.get('animation');
        var isAreaChart = !areaStyleModel.isEmpty();
        var valueOrigin = areaStyleModel.get('origin');
        var dataCoordInfo = prepareDataCoordInfo(coordSys, data, valueOrigin);
        var stackedOnPoints = isAreaChart && getStackedOnPoints(coordSys, data, dataCoordInfo);
        var showSymbol = seriesModel.get('showSymbol');
        var connectNulls = seriesModel.get('connectNulls');
        var isIgnoreFunc = showSymbol && !isCoordSysPolar && getIsIgnoreFunc(seriesModel, data, coordSys); // Remove temporary symbols

        var oldData = this._data;
        oldData && oldData.eachItemGraphicEl(function (el, idx) {
          if (el.__temp) {
            group.remove(el);
            oldData.setItemGraphicEl(idx, null);
          }
        }); // Remove previous created symbols if showSymbol changed to false

        if (!showSymbol) {
          symbolDraw.remove();
        }

        group.add(lineGroup); // FIXME step not support polar

        var step = !isCoordSysPolar ? seriesModel.get('step') : false;
        var clipShapeForSymbol;

        if (coordSys && coordSys.getArea && seriesModel.get('clip', true)) {
          clipShapeForSymbol = coordSys.getArea(); // Avoid float number rounding error for symbol on the edge of axis extent.
          // See #7913 and `test/dataZoom-clip.html`.

          if (clipShapeForSymbol.width != null) {
            clipShapeForSymbol.x -= 0.1;
            clipShapeForSymbol.y -= 0.1;
            clipShapeForSymbol.width += 0.2;
            clipShapeForSymbol.height += 0.2;
          } else if (clipShapeForSymbol.r0) {
            clipShapeForSymbol.r0 -= 0.5;
            clipShapeForSymbol.r += 0.5;
          }
        }

        this._clipShapeForSymbol = clipShapeForSymbol;
        var visualColor = getVisualGradient(data, coordSys, api) || data.getVisual('style')[data.getVisual('drawType')]; // Initialization animation or coordinate system changed

        if (!(polyline && prevCoordSys.type === coordSys.type && step === this._step)) {
          showSymbol && symbolDraw.updateData(data, {
            isIgnore: isIgnoreFunc,
            clipShape: clipShapeForSymbol,
            disableAnimation: true,
            getSymbolPoint: function (idx) {
              return [points[idx * 2], points[idx * 2 + 1]];
            }
          });
          hasAnimation && this._initSymbolLabelAnimation(data, coordSys, clipShapeForSymbol);

          if (step) {
            // TODO If stacked series is not step
            points = turnPointsIntoStep(points, coordSys, step, connectNulls);

            if (stackedOnPoints) {
              stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls);
            }
          }

          polyline = this._newPolyline(points);

          if (isAreaChart) {
            polygon = this._newPolygon(points, stackedOnPoints);
          } // If areaStyle is removed
          else if (polygon) {
              lineGroup.remove(polygon);
              polygon = this._polygon = null;
            } // NOTE: Must update _endLabel before setClipPath.


          if (!isCoordSysPolar) {
            this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor));
          }

          lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel));
        } else {
          if (isAreaChart && !polygon) {
            // If areaStyle is added
            polygon = this._newPolygon(points, stackedOnPoints);
          } else if (polygon && !isAreaChart) {
            // If areaStyle is removed
            lineGroup.remove(polygon);
            polygon = this._polygon = null;
          } // NOTE: Must update _endLabel before setClipPath.


          if (!isCoordSysPolar) {
            this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor));
          } // Update clipPath


          var oldClipPath = lineGroup.getClipPath();

          if (oldClipPath) {
            var newClipPath = createLineClipPath(this, coordSys, false, seriesModel);
            initProps(oldClipPath, {
              shape: newClipPath.shape
            }, seriesModel);
          } else {
            lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel));
          } // Always update, or it is wrong in the case turning on legend
          // because points are not changed.


          showSymbol && symbolDraw.updateData(data, {
            isIgnore: isIgnoreFunc,
            clipShape: clipShapeForSymbol,
            disableAnimation: true,
            getSymbolPoint: function (idx) {
              return [points[idx * 2], points[idx * 2 + 1]];
            }
          }); // In the case data zoom triggered refreshing frequently
          // Data may not change if line has a category axis. So it should animate nothing.

          if (!isPointsSame(this._stackedOnPoints, stackedOnPoints) || !isPointsSame(this._points, points)) {
            if (hasAnimation) {
              this._doUpdateAnimation(data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls);
            } else {
              // Not do it in update with animation
              if (step) {
                // TODO If stacked series is not step
                points = turnPointsIntoStep(points, coordSys, step, connectNulls);

                if (stackedOnPoints) {
                  stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls);
                }
              }

              polyline.setShape({
                points: points
              });
              polygon && polygon.setShape({
                points: points,
                stackedOnPoints: stackedOnPoints
              });
            }
          }
        }

        var emphasisModel = seriesModel.getModel('emphasis');
        var focus = emphasisModel.get('focus');
        var blurScope = emphasisModel.get('blurScope');
        var emphasisDisabled = emphasisModel.get('disabled');
        polyline.useStyle(defaults( // Use color in lineStyle first
        lineStyleModel.getLineStyle(), {
          fill: 'none',
          stroke: visualColor,
          lineJoin: 'bevel'
        }));
        setStatesStylesFromModel(polyline, seriesModel, 'lineStyle');

        if (polyline.style.lineWidth > 0 && seriesModel.get(['emphasis', 'lineStyle', 'width']) === 'bolder') {
          var emphasisLineStyle = polyline.getState('emphasis').style;
          emphasisLineStyle.lineWidth = +polyline.style.lineWidth + 1;
        } // Needs seriesIndex for focus


        getECData(polyline).seriesIndex = seriesModel.seriesIndex;
        toggleHoverEmphasis(polyline, focus, blurScope, emphasisDisabled);
        var smooth = getSmooth(seriesModel.get('smooth'));
        var smoothMonotone = seriesModel.get('smoothMonotone');
        polyline.setShape({
          smooth: smooth,
          smoothMonotone: smoothMonotone,
          connectNulls: connectNulls
        });

        if (polygon) {
          var stackedOnSeries = data.getCalculationInfo('stackedOnSeries');
          var stackedOnSmooth = 0;
          polygon.useStyle(defaults(areaStyleModel.getAreaStyle(), {
            fill: visualColor,
            opacity: 0.7,
            lineJoin: 'bevel',
            decal: data.getVisual('style').decal
          }));

          if (stackedOnSeries) {
            stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));
          }

          polygon.setShape({
            smooth: smooth,
            stackedOnSmooth: stackedOnSmooth,
            smoothMonotone: smoothMonotone,
            connectNulls: connectNulls
          });
          setStatesStylesFromModel(polygon, seriesModel, 'areaStyle'); // Needs seriesIndex for focus

          getECData(polygon).seriesIndex = seriesModel.seriesIndex;
          toggleHoverEmphasis(polygon, focus, blurScope, emphasisDisabled);
        }

        var changePolyState = function (toState) {
          _this._changePolyState(toState);
        };

        data.eachItemGraphicEl(function (el) {
          // Switch polyline / polygon state if element changed its state.
          el && (el.onHoverStateChange = changePolyState);
        });
        this._polyline.onHoverStateChange = changePolyState;
        this._data = data; // Save the coordinate system for transition animation when data changed

        this._coordSys = coordSys;
        this._stackedOnPoints = stackedOnPoints;
        this._points = points;
        this._step = step;
        this._valueOrigin = valueOrigin;

        if (seriesModel.get('triggerLineEvent')) {
          this.packEventData(seriesModel, polyline);
          polygon && this.packEventData(seriesModel, polygon);
        }
      };

      LineView.prototype.packEventData = function (seriesModel, el) {
        getECData(el).eventData = {
          componentType: 'series',
          componentSubType: 'line',
          componentIndex: seriesModel.componentIndex,
          seriesIndex: seriesModel.seriesIndex,
          seriesName: seriesModel.name,
          seriesType: 'line'
        };
      };

      LineView.prototype.highlight = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData();
        var dataIndex = queryDataIndex(data, payload);

        this._changePolyState('emphasis');

        if (!(dataIndex instanceof Array) && dataIndex != null && dataIndex >= 0) {
          var points = data.getLayout('points');
          var symbol = data.getItemGraphicEl(dataIndex);

          if (!symbol) {
            // Create a temporary symbol if it is not exists
            var x = points[dataIndex * 2];
            var y = points[dataIndex * 2 + 1];

            if (isNaN(x) || isNaN(y)) {
              // Null data
              return;
            } // fix #11360: shouldn't draw symbol outside clipShapeForSymbol


            if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(x, y)) {
              return;
            }

            var zlevel = seriesModel.get('zlevel') || 0;
            var z = seriesModel.get('z') || 0;
            symbol = new Symbol(data, dataIndex);
            symbol.x = x;
            symbol.y = y;
            symbol.setZ(zlevel, z); // ensure label text of the temporary symbol is in front of line and area polygon

            var symbolLabel = symbol.getSymbolPath().getTextContent();

            if (symbolLabel) {
              symbolLabel.zlevel = zlevel;
              symbolLabel.z = z;
              symbolLabel.z2 = this._polyline.z2 + 1;
            }

            symbol.__temp = true;
            data.setItemGraphicEl(dataIndex, symbol); // Stop scale animation

            symbol.stopSymbolAnimation(true);
            this.group.add(symbol);
          }

          symbol.highlight();
        } else {
          // Highlight whole series
          ChartView.prototype.highlight.call(this, seriesModel, ecModel, api, payload);
        }
      };

      LineView.prototype.downplay = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData();
        var dataIndex = queryDataIndex(data, payload);

        this._changePolyState('normal');

        if (dataIndex != null && dataIndex >= 0) {
          var symbol = data.getItemGraphicEl(dataIndex);

          if (symbol) {
            if (symbol.__temp) {
              data.setItemGraphicEl(dataIndex, null);
              this.group.remove(symbol);
            } else {
              symbol.downplay();
            }
          }
        } else {
          // FIXME
          // can not downplay completely.
          // Downplay whole series
          ChartView.prototype.downplay.call(this, seriesModel, ecModel, api, payload);
        }
      };

      LineView.prototype._changePolyState = function (toState) {
        var polygon = this._polygon;
        setStatesFlag(this._polyline, toState);
        polygon && setStatesFlag(polygon, toState);
      };

      LineView.prototype._newPolyline = function (points) {
        var polyline = this._polyline; // Remove previous created polyline

        if (polyline) {
          this._lineGroup.remove(polyline);
        }

        polyline = new ECPolyline({
          shape: {
            points: points
          },
          segmentIgnoreThreshold: 2,
          z2: 10
        });

        this._lineGroup.add(polyline);

        this._polyline = polyline;
        return polyline;
      };

      LineView.prototype._newPolygon = function (points, stackedOnPoints) {
        var polygon = this._polygon; // Remove previous created polygon

        if (polygon) {
          this._lineGroup.remove(polygon);
        }

        polygon = new ECPolygon({
          shape: {
            points: points,
            stackedOnPoints: stackedOnPoints
          },
          segmentIgnoreThreshold: 2
        });

        this._lineGroup.add(polygon);

        this._polygon = polygon;
        return polygon;
      };

      LineView.prototype._initSymbolLabelAnimation = function (data, coordSys, clipShape) {
        var isHorizontalOrRadial;
        var isCoordSysPolar;
        var baseAxis = coordSys.getBaseAxis();
        var isAxisInverse = baseAxis.inverse;

        if (coordSys.type === 'cartesian2d') {
          isHorizontalOrRadial = baseAxis.isHorizontal();
          isCoordSysPolar = false;
        } else if (coordSys.type === 'polar') {
          isHorizontalOrRadial = baseAxis.dim === 'angle';
          isCoordSysPolar = true;
        }

        var seriesModel = data.hostModel;
        var seriesDuration = seriesModel.get('animationDuration');

        if (isFunction(seriesDuration)) {
          seriesDuration = seriesDuration(null);
        }

        var seriesDalay = seriesModel.get('animationDelay') || 0;
        var seriesDalayValue = isFunction(seriesDalay) ? seriesDalay(null) : seriesDalay;
        data.eachItemGraphicEl(function (symbol, idx) {
          var el = symbol;

          if (el) {
            var point = [symbol.x, symbol.y];
            var start = void 0;
            var end = void 0;
            var current = void 0;

            if (clipShape) {
              if (isCoordSysPolar) {
                var polarClip = clipShape;
                var coord = coordSys.pointToCoord(point);

                if (isHorizontalOrRadial) {
                  start = polarClip.startAngle;
                  end = polarClip.endAngle;
                  current = -coord[1] / 180 * Math.PI;
                } else {
                  start = polarClip.r0;
                  end = polarClip.r;
                  current = coord[0];
                }
              } else {
                var gridClip = clipShape;

                if (isHorizontalOrRadial) {
                  start = gridClip.x;
                  end = gridClip.x + gridClip.width;
                  current = symbol.x;
                } else {
                  start = gridClip.y + gridClip.height;
                  end = gridClip.y;
                  current = symbol.y;
                }
              }
            }

            var ratio = end === start ? 0 : (current - start) / (end - start);

            if (isAxisInverse) {
              ratio = 1 - ratio;
            }

            var delay = isFunction(seriesDalay) ? seriesDalay(idx) : seriesDuration * ratio + seriesDalayValue;
            var symbolPath = el.getSymbolPath();
            var text = symbolPath.getTextContent();
            el.attr({
              scaleX: 0,
              scaleY: 0
            });
            el.animateTo({
              scaleX: 1,
              scaleY: 1
            }, {
              duration: 200,
              setToFinal: true,
              delay: delay
            });

            if (text) {
              text.animateFrom({
                style: {
                  opacity: 0
                }
              }, {
                duration: 300,
                delay: delay
              });
            }

            symbolPath.disableLabelAnimation = true;
          }
        });
      };

      LineView.prototype._initOrUpdateEndLabel = function (seriesModel, coordSys, inheritColor) {
        var endLabelModel = seriesModel.getModel('endLabel');

        if (anyStateShowEndLabel(seriesModel)) {
          var data_2 = seriesModel.getData();
          var polyline = this._polyline; // series may be filtered.

          var points = data_2.getLayout('points');

          if (!points) {
            polyline.removeTextContent();
            this._endLabel = null;
            return;
          }

          var endLabel = this._endLabel;

          if (!endLabel) {
            endLabel = this._endLabel = new ZRText({
              z2: 200 // should be higher than item symbol

            });
            endLabel.ignoreClip = true;
            polyline.setTextContent(this._endLabel);
            polyline.disableLabelAnimation = true;
          } // Find last non-NaN data to display data


          var dataIndex = getLastIndexNotNull(points);

          if (dataIndex >= 0) {
            setLabelStyle(polyline, getLabelStatesModels(seriesModel, 'endLabel'), {
              inheritColor: inheritColor,
              labelFetcher: seriesModel,
              labelDataIndex: dataIndex,
              defaultText: function (dataIndex, opt, interpolatedValue) {
                return interpolatedValue != null ? getDefaultInterpolatedLabel(data_2, interpolatedValue) : getDefaultLabel(data_2, dataIndex);
              },
              enableTextSetter: true
            }, getEndLabelStateSpecified(endLabelModel, coordSys));
            polyline.textConfig.position = null;
          }
        } else if (this._endLabel) {
          this._polyline.removeTextContent();

          this._endLabel = null;
        }
      };

      LineView.prototype._endLabelOnDuring = function (percent, clipRect, data, animationRecord, valueAnimation, endLabelModel, coordSys) {
        var endLabel = this._endLabel;
        var polyline = this._polyline;

        if (endLabel) {
          // NOTE: Don't remove percent < 1. percent === 1 means the first frame during render.
          // The label is not prepared at this time.
          if (percent < 1 && animationRecord.originalX == null) {
            animationRecord.originalX = endLabel.x;
            animationRecord.originalY = endLabel.y;
          }

          var points = data.getLayout('points');
          var seriesModel = data.hostModel;
          var connectNulls = seriesModel.get('connectNulls');
          var precision = endLabelModel.get('precision');
          var distance = endLabelModel.get('distance') || 0;
          var baseAxis = coordSys.getBaseAxis();
          var isHorizontal = baseAxis.isHorizontal();
          var isBaseInversed = baseAxis.inverse;
          var clipShape = clipRect.shape;
          var xOrY = isBaseInversed ? isHorizontal ? clipShape.x : clipShape.y + clipShape.height : isHorizontal ? clipShape.x + clipShape.width : clipShape.y;
          var distanceX = (isHorizontal ? distance : 0) * (isBaseInversed ? -1 : 1);
          var distanceY = (isHorizontal ? 0 : -distance) * (isBaseInversed ? -1 : 1);
          var dim = isHorizontal ? 'x' : 'y';
          var dataIndexRange = getIndexRange(points, xOrY, dim);
          var indices = dataIndexRange.range;
          var diff = indices[1] - indices[0];
          var value = void 0;

          if (diff >= 1) {
            // diff > 1 && connectNulls, which is on the null data.
            if (diff > 1 && !connectNulls) {
              var pt = getPointAtIndex(points, indices[0]);
              endLabel.attr({
                x: pt[0] + distanceX,
                y: pt[1] + distanceY
              });
              valueAnimation && (value = seriesModel.getRawValue(indices[0]));
            } else {
              var pt = polyline.getPointOn(xOrY, dim);
              pt && endLabel.attr({
                x: pt[0] + distanceX,
                y: pt[1] + distanceY
              });
              var startValue = seriesModel.getRawValue(indices[0]);
              var endValue = seriesModel.getRawValue(indices[1]);
              valueAnimation && (value = interpolateRawValues(data, precision, startValue, endValue, dataIndexRange.t));
            }

            animationRecord.lastFrameIndex = indices[0];
          } else {
            // If diff <= 0, which is the range is not found(Include NaN)
            // Choose the first point or last point.
            var idx = percent === 1 || animationRecord.lastFrameIndex > 0 ? indices[0] : 0;
            var pt = getPointAtIndex(points, idx);
            valueAnimation && (value = seriesModel.getRawValue(idx));
            endLabel.attr({
              x: pt[0] + distanceX,
              y: pt[1] + distanceY
            });
          }

          if (valueAnimation) {
            labelInner(endLabel).setLabelText(value);
          }
        }
      };
      /**
       * @private
       */
      // FIXME Two value axis


      LineView.prototype._doUpdateAnimation = function (data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls) {
        var polyline = this._polyline;
        var polygon = this._polygon;
        var seriesModel = data.hostModel;
        var diff = lineAnimationDiff(this._data, data, this._stackedOnPoints, stackedOnPoints, this._coordSys, coordSys, this._valueOrigin);
        var current = diff.current;
        var stackedOnCurrent = diff.stackedOnCurrent;
        var next = diff.next;
        var stackedOnNext = diff.stackedOnNext;

        if (step) {
          // TODO If stacked series is not step
          current = turnPointsIntoStep(diff.current, coordSys, step, connectNulls);
          stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step, connectNulls);
          next = turnPointsIntoStep(diff.next, coordSys, step, connectNulls);
          stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step, connectNulls);
        } // Don't apply animation if diff is large.
        // For better result and avoid memory explosion problems like
        // https://github.com/apache/incubator-echarts/issues/12229


        if (getBoundingDiff(current, next) > 3000 || polygon && getBoundingDiff(stackedOnCurrent, stackedOnNext) > 3000) {
          polyline.stopAnimation();
          polyline.setShape({
            points: next
          });

          if (polygon) {
            polygon.stopAnimation();
            polygon.setShape({
              points: next,
              stackedOnPoints: stackedOnNext
            });
          }

          return;
        }

        polyline.shape.__points = diff.current;
        polyline.shape.points = current;
        var target = {
          shape: {
            points: next
          }
        }; // Also animate the original points.
        // If points reference is changed when turning into step line.

        if (diff.current !== current) {
          target.shape.__points = diff.next;
        } // Stop previous animation.


        polyline.stopAnimation();
        updateProps(polyline, target, seriesModel);

        if (polygon) {
          polygon.setShape({
            // Reuse the points with polyline.
            points: current,
            stackedOnPoints: stackedOnCurrent
          });
          polygon.stopAnimation();
          updateProps(polygon, {
            shape: {
              stackedOnPoints: stackedOnNext
            }
          }, seriesModel); // If use attr directly in updateProps.

          if (polyline.shape.points !== polygon.shape.points) {
            polygon.shape.points = polyline.shape.points;
          }
        }

        var updatedDataInfo = [];
        var diffStatus = diff.status;

        for (var i = 0; i < diffStatus.length; i++) {
          var cmd = diffStatus[i].cmd;

          if (cmd === '=') {
            var el = data.getItemGraphicEl(diffStatus[i].idx1);

            if (el) {
              updatedDataInfo.push({
                el: el,
                ptIdx: i // Index of points

              });
            }
          }
        }

        if (polyline.animators && polyline.animators.length) {
          polyline.animators[0].during(function () {
            polygon && polygon.dirtyShape();
            var points = polyline.shape.__points;

            for (var i = 0; i < updatedDataInfo.length; i++) {
              var el = updatedDataInfo[i].el;
              var offset = updatedDataInfo[i].ptIdx * 2;
              el.x = points[offset];
              el.y = points[offset + 1];
              el.markRedraw();
            }
          });
        }
      };

      LineView.prototype.remove = function (ecModel) {
        var group = this.group;
        var oldData = this._data;

        this._lineGroup.removeAll();

        this._symbolDraw.remove(true); // Remove temporary created elements when highlighting


        oldData && oldData.eachItemGraphicEl(function (el, idx) {
          if (el.__temp) {
            group.remove(el);
            oldData.setItemGraphicEl(idx, null);
          }
        });
        this._polyline = this._polygon = this._coordSys = this._points = this._stackedOnPoints = this._endLabel = this._data = null;
      };

      LineView.type = 'line';
      return LineView;
    }(ChartView);

    function pointsLayout(seriesType, forceStoreInTypedArray) {
      return {
        seriesType: seriesType,
        plan: createRenderPlanner(),
        reset: function (seriesModel) {
          var data = seriesModel.getData();
          var coordSys = seriesModel.coordinateSystem;
          var pipelineContext = seriesModel.pipelineContext;
          var useTypedArray = forceStoreInTypedArray || pipelineContext.large;

          if (!coordSys) {
            return;
          }

          var dims = map(coordSys.dimensions, function (dim) {
            return data.mapDimension(dim);
          }).slice(0, 2);
          var dimLen = dims.length;
          var stackResultDim = data.getCalculationInfo('stackResultDimension');

          if (isDimensionStacked(data, dims[0])) {
            dims[0] = stackResultDim;
          }

          if (isDimensionStacked(data, dims[1])) {
            dims[1] = stackResultDim;
          }

          var store = data.getStore();
          var dimIdx0 = data.getDimensionIndex(dims[0]);
          var dimIdx1 = data.getDimensionIndex(dims[1]);
          return dimLen && {
            progress: function (params, data) {
              var segCount = params.end - params.start;
              var points = useTypedArray && createFloat32Array(segCount * dimLen);
              var tmpIn = [];
              var tmpOut = [];

              for (var i = params.start, offset = 0; i < params.end; i++) {
                var point = void 0;

                if (dimLen === 1) {
                  var x = store.get(dimIdx0, i); // NOTE: Make sure the second parameter is null to use default strategy.

                  point = coordSys.dataToPoint(x, null, tmpOut);
                } else {
                  tmpIn[0] = store.get(dimIdx0, i);
                  tmpIn[1] = store.get(dimIdx1, i); // Let coordinate system to handle the NaN data.

                  point = coordSys.dataToPoint(tmpIn, null, tmpOut);
                }

                if (useTypedArray) {
                  points[offset++] = point[0];
                  points[offset++] = point[1];
                } else {
                  data.setItemLayout(i, point.slice());
                }
              }

              useTypedArray && data.setLayout('points', points);
            }
          };
        }
      };
    }

    var samplers = {
      average: function (frame) {
        var sum = 0;
        var count = 0;

        for (var i = 0; i < frame.length; i++) {
          if (!isNaN(frame[i])) {
            sum += frame[i];
            count++;
          }
        } // Return NaN if count is 0


        return count === 0 ? NaN : sum / count;
      },
      sum: function (frame) {
        var sum = 0;

        for (var i = 0; i < frame.length; i++) {
          // Ignore NaN
          sum += frame[i] || 0;
        }

        return sum;
      },
      max: function (frame) {
        var max = -Infinity;

        for (var i = 0; i < frame.length; i++) {
          frame[i] > max && (max = frame[i]);
        } // NaN will cause illegal axis extent.


        return isFinite(max) ? max : NaN;
      },
      min: function (frame) {
        var min = Infinity;

        for (var i = 0; i < frame.length; i++) {
          frame[i] < min && (min = frame[i]);
        } // NaN will cause illegal axis extent.


        return isFinite(min) ? min : NaN;
      },
      // TODO
      // Median
      nearest: function (frame) {
        return frame[0];
      }
    };

    var indexSampler = function (frame) {
      return Math.round(frame.length / 2);
    };

    function dataSample(seriesType) {
      return {
        seriesType: seriesType,
        // FIXME:TS never used, so comment it
        // modifyOutputEnd: true,
        reset: function (seriesModel, ecModel, api) {
          var data = seriesModel.getData();
          var sampling = seriesModel.get('sampling');
          var coordSys = seriesModel.coordinateSystem;
          var count = data.count(); // Only cartesian2d support down sampling. Disable it when there is few data.

          if (count > 10 && coordSys.type === 'cartesian2d' && sampling) {
            var baseAxis = coordSys.getBaseAxis();
            var valueAxis = coordSys.getOtherAxis(baseAxis);
            var extent = baseAxis.getExtent();
            var dpr = api.getDevicePixelRatio(); // Coordinste system has been resized

            var size = Math.abs(extent[1] - extent[0]) * (dpr || 1);
            var rate = Math.round(count / size);

            if (isFinite(rate) && rate > 1) {
              if (sampling === 'lttb') {
                seriesModel.setData(data.lttbDownSample(data.mapDimension(valueAxis.dim), 1 / rate));
              }

              var sampler = void 0;

              if (isString(sampling)) {
                sampler = samplers[sampling];
              } else if (isFunction(sampling)) {
                sampler = sampling;
              }

              if (sampler) {
                // Only support sample the first dim mapped from value axis.
                seriesModel.setData(data.downSample(data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler));
              }
            }
          }
        }
      };
    }

    function install$2(registers) {
      registers.registerChartView(LineView);
      registers.registerSeriesModel(LineSeriesModel);
      registers.registerLayout(pointsLayout('line', true));
      registers.registerVisual({
        seriesType: 'line',
        reset: function (seriesModel) {
          var data = seriesModel.getData(); // Visual coding for legend

          var lineStyle = seriesModel.getModel('lineStyle').getLineStyle();

          if (lineStyle && !lineStyle.stroke) {
            // Fill in visual should be palette color if
            // has color callback
            lineStyle.stroke = data.getVisual('style').fill;
          }

          data.setVisual('legendLineStyle', lineStyle);
        }
      }); // Down sample after filter

      registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, dataSample('line'));
    }

    var BaseBarSeriesModel =
    /** @class */
    function (_super) {
      __extends(BaseBarSeriesModel, _super);

      function BaseBarSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = BaseBarSeriesModel.type;
        return _this;
      }

      BaseBarSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createSeriesData(null, this, {
          useEncodeDefaulter: true
        });
      };

      BaseBarSeriesModel.prototype.getMarkerPosition = function (value, dims, startingAtTick) {
        var coordSys = this.coordinateSystem;

        if (coordSys && coordSys.clampData) {
          // PENDING if clamp ?
          var pt_1 = coordSys.dataToPoint(coordSys.clampData(value));

          if (startingAtTick) {
            each(coordSys.getAxes(), function (axis, idx) {
              // If axis type is category, use tick coords instead
              if (axis.type === 'category') {
                var tickCoords = axis.getTicksCoords();
                var tickIdx = coordSys.clampData(value)[idx]; // The index of rightmost tick of markArea is 1 larger than x1/y1 index

                if (dims && (dims[idx] === 'x1' || dims[idx] === 'y1')) {
                  tickIdx += 1;
                }

                tickIdx > tickCoords.length - 1 && (tickIdx = tickCoords.length - 1);
                tickIdx < 0 && (tickIdx = 0);
                tickCoords[tickIdx] && (pt_1[idx] = axis.toGlobalCoord(tickCoords[tickIdx].coord));
              }
            });
          } else {
            var data = this.getData();
            var offset = data.getLayout('offset');
            var size = data.getLayout('size');
            var offsetIndex = coordSys.getBaseAxis().isHorizontal() ? 0 : 1;
            pt_1[offsetIndex] += offset + size / 2;
          }

          return pt_1;
        }

        return [NaN, NaN];
      };

      BaseBarSeriesModel.type = 'series.__base_bar__';
      BaseBarSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        coordinateSystem: 'cartesian2d',
        legendHoverLink: true,
        // stack: null
        // Cartesian coordinate system
        // xAxisIndex: 0,
        // yAxisIndex: 0,
        barMinHeight: 0,
        barMinAngle: 0,
        // cursor: null,
        large: false,
        largeThreshold: 400,
        progressive: 3e3,
        progressiveChunkMode: 'mod'
      };
      return BaseBarSeriesModel;
    }(SeriesModel);

    SeriesModel.registerClass(BaseBarSeriesModel);

    var BarSeriesModel =
    /** @class */
    function (_super) {
      __extends(BarSeriesModel, _super);

      function BarSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = BarSeriesModel.type;
        return _this;
      }

      BarSeriesModel.prototype.getInitialData = function () {
        return createSeriesData(null, this, {
          useEncodeDefaulter: true,
          createInvertedIndices: !!this.get('realtimeSort', true) || null
        });
      };
      /**
       * @override
       */


      BarSeriesModel.prototype.getProgressive = function () {
        // Do not support progressive in normal mode.
        return this.get('large') ? this.get('progressive') : false;
      };
      /**
       * @override
       */


      BarSeriesModel.prototype.getProgressiveThreshold = function () {
        // Do not support progressive in normal mode.
        var progressiveThreshold = this.get('progressiveThreshold');
        var largeThreshold = this.get('largeThreshold');

        if (largeThreshold > progressiveThreshold) {
          progressiveThreshold = largeThreshold;
        }

        return progressiveThreshold;
      };

      BarSeriesModel.prototype.brushSelector = function (dataIndex, data, selectors) {
        return selectors.rect(data.getItemLayout(dataIndex));
      };

      BarSeriesModel.type = 'series.bar';
      BarSeriesModel.dependencies = ['grid', 'polar'];
      BarSeriesModel.defaultOption = inheritDefaultOption(BaseBarSeriesModel.defaultOption, {
        // If clipped
        // Only available on cartesian2d
        clip: true,
        roundCap: false,
        showBackground: false,
        backgroundStyle: {
          color: 'rgba(180, 180, 180, 0.2)',
          borderColor: null,
          borderWidth: 0,
          borderType: 'solid',
          borderRadius: 0,
          shadowBlur: 0,
          shadowColor: null,
          shadowOffsetX: 0,
          shadowOffsetY: 0,
          opacity: 1
        },
        select: {
          itemStyle: {
            borderColor: '#212121'
          }
        },
        realtimeSort: false
      });
      return BarSeriesModel;
    }(BaseBarSeriesModel);

    /**
     * Sausage: similar to sector, but have half circle on both sides
     */

    var SausageShape =
    /** @class */
    function () {
      function SausageShape() {
        this.cx = 0;
        this.cy = 0;
        this.r0 = 0;
        this.r = 0;
        this.startAngle = 0;
        this.endAngle = Math.PI * 2;
        this.clockwise = true;
      }

      return SausageShape;
    }();

    var SausagePath =
    /** @class */
    function (_super) {
      __extends(SausagePath, _super);

      function SausagePath(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'sausage';
        return _this;
      }

      SausagePath.prototype.getDefaultShape = function () {
        return new SausageShape();
      };

      SausagePath.prototype.buildPath = function (ctx, shape) {
        var cx = shape.cx;
        var cy = shape.cy;
        var r0 = Math.max(shape.r0 || 0, 0);
        var r = Math.max(shape.r, 0);
        var dr = (r - r0) * 0.5;
        var rCenter = r0 + dr;
        var startAngle = shape.startAngle;
        var endAngle = shape.endAngle;
        var clockwise = shape.clockwise;
        var PI2 = Math.PI * 2;
        var lessThanCircle = clockwise ? endAngle - startAngle < PI2 : startAngle - endAngle < PI2;

        if (!lessThanCircle) {
          // Normalize angles
          startAngle = endAngle - (clockwise ? PI2 : -PI2);
        }

        var unitStartX = Math.cos(startAngle);
        var unitStartY = Math.sin(startAngle);
        var unitEndX = Math.cos(endAngle);
        var unitEndY = Math.sin(endAngle);

        if (lessThanCircle) {
          ctx.moveTo(unitStartX * r0 + cx, unitStartY * r0 + cy);
          ctx.arc(unitStartX * rCenter + cx, unitStartY * rCenter + cy, dr, -Math.PI + startAngle, startAngle, !clockwise);
        } else {
          ctx.moveTo(unitStartX * r + cx, unitStartY * r + cy);
        }

        ctx.arc(cx, cy, r, startAngle, endAngle, !clockwise);
        ctx.arc(unitEndX * rCenter + cx, unitEndY * rCenter + cy, dr, endAngle - Math.PI * 2, endAngle - Math.PI, !clockwise);

        if (r0 !== 0) {
          ctx.arc(cx, cy, r0, endAngle, startAngle, clockwise);
        } // ctx.closePath();

      };

      return SausagePath;
    }(Path);

    function createSectorCalculateTextPosition(positionMapping, opts) {
      opts = opts || {};
      var isRoundCap = opts.isRoundCap;
      return function (out, opts, boundingRect) {
        var textPosition = opts.position;

        if (!textPosition || textPosition instanceof Array) {
          return calculateTextPosition(out, opts, boundingRect);
        }

        var mappedSectorPosition = positionMapping(textPosition);
        var distance = opts.distance != null ? opts.distance : 5;
        var sector = this.shape;
        var cx = sector.cx;
        var cy = sector.cy;
        var r = sector.r;
        var r0 = sector.r0;
        var middleR = (r + r0) / 2;
        var startAngle = sector.startAngle;
        var endAngle = sector.endAngle;
        var middleAngle = (startAngle + endAngle) / 2;
        var extraDist = isRoundCap ? Math.abs(r - r0) / 2 : 0;
        var mathCos = Math.cos;
        var mathSin = Math.sin; // base position: top-left

        var x = cx + r * mathCos(startAngle);
        var y = cy + r * mathSin(startAngle);
        var textAlign = 'left';
        var textVerticalAlign = 'top';

        switch (mappedSectorPosition) {
          case 'startArc':
            x = cx + (r0 - distance) * mathCos(middleAngle);
            y = cy + (r0 - distance) * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'top';
            break;

          case 'insideStartArc':
            x = cx + (r0 + distance) * mathCos(middleAngle);
            y = cy + (r0 + distance) * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'bottom';
            break;

          case 'startAngle':
            x = cx + middleR * mathCos(startAngle) + adjustAngleDistanceX(startAngle, distance + extraDist, false);
            y = cy + middleR * mathSin(startAngle) + adjustAngleDistanceY(startAngle, distance + extraDist, false);
            textAlign = 'right';
            textVerticalAlign = 'middle';
            break;

          case 'insideStartAngle':
            x = cx + middleR * mathCos(startAngle) + adjustAngleDistanceX(startAngle, -distance + extraDist, false);
            y = cy + middleR * mathSin(startAngle) + adjustAngleDistanceY(startAngle, -distance + extraDist, false);
            textAlign = 'left';
            textVerticalAlign = 'middle';
            break;

          case 'middle':
            x = cx + middleR * mathCos(middleAngle);
            y = cy + middleR * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'middle';
            break;

          case 'endArc':
            x = cx + (r + distance) * mathCos(middleAngle);
            y = cy + (r + distance) * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'bottom';
            break;

          case 'insideEndArc':
            x = cx + (r - distance) * mathCos(middleAngle);
            y = cy + (r - distance) * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'top';
            break;

          case 'endAngle':
            x = cx + middleR * mathCos(endAngle) + adjustAngleDistanceX(endAngle, distance + extraDist, true);
            y = cy + middleR * mathSin(endAngle) + adjustAngleDistanceY(endAngle, distance + extraDist, true);
            textAlign = 'left';
            textVerticalAlign = 'middle';
            break;

          case 'insideEndAngle':
            x = cx + middleR * mathCos(endAngle) + adjustAngleDistanceX(endAngle, -distance + extraDist, true);
            y = cy + middleR * mathSin(endAngle) + adjustAngleDistanceY(endAngle, -distance + extraDist, true);
            textAlign = 'right';
            textVerticalAlign = 'middle';
            break;

          default:
            return calculateTextPosition(out, opts, boundingRect);
        }

        out = out || {};
        out.x = x;
        out.y = y;
        out.align = textAlign;
        out.verticalAlign = textVerticalAlign;
        return out;
      };
    }
    function setSectorTextRotation(sector, textPosition, positionMapping, rotateType) {
      if (isNumber(rotateType)) {
        // user-set rotation
        sector.setTextConfig({
          rotation: rotateType
        });
        return;
      } else if (isArray(textPosition)) {
        // user-set position, use 0 as auto rotation
        sector.setTextConfig({
          rotation: 0
        });
        return;
      }

      var shape = sector.shape;
      var startAngle = shape.clockwise ? shape.startAngle : shape.endAngle;
      var endAngle = shape.clockwise ? shape.endAngle : shape.startAngle;
      var middleAngle = (startAngle + endAngle) / 2;
      var anchorAngle;
      var mappedSectorPosition = positionMapping(textPosition);

      switch (mappedSectorPosition) {
        case 'startArc':
        case 'insideStartArc':
        case 'middle':
        case 'insideEndArc':
        case 'endArc':
          anchorAngle = middleAngle;
          break;

        case 'startAngle':
        case 'insideStartAngle':
          anchorAngle = startAngle;
          break;

        case 'endAngle':
        case 'insideEndAngle':
          anchorAngle = endAngle;
          break;

        default:
          sector.setTextConfig({
            rotation: 0
          });
          return;
      }

      var rotate = Math.PI * 1.5 - anchorAngle;
      /**
       * TODO: labels with rotate > Math.PI / 2 should be rotate another
       * half round flipped to increase readability. However, only middle
       * position supports this for now, because in other positions, the
       * anchor point is not at the center of the text, so the positions
       * after rotating is not as expected.
       */

      if (mappedSectorPosition === 'middle' && rotate > Math.PI / 2 && rotate < Math.PI * 1.5) {
        rotate -= Math.PI;
      }

      sector.setTextConfig({
        rotation: rotate
      });
    }

    function adjustAngleDistanceX(angle, distance, isEnd) {
      return distance * Math.sin(angle) * (isEnd ? -1 : 1);
    }

    function adjustAngleDistanceY(angle, distance, isEnd) {
      return distance * Math.cos(angle) * (isEnd ? 1 : -1);
    }

    var mathMax$6 = Math.max;
    var mathMin$6 = Math.min;

    function getClipArea(coord, data) {
      var coordSysClipArea = coord.getArea && coord.getArea();

      if (isCoordinateSystemType(coord, 'cartesian2d')) {
        var baseAxis = coord.getBaseAxis(); // When boundaryGap is false or using time axis. bar may exceed the grid.
        // We should not clip this part.
        // See test/bar2.html

        if (baseAxis.type !== 'category' || !baseAxis.onBand) {
          var expandWidth = data.getLayout('bandWidth');

          if (baseAxis.isHorizontal()) {
            coordSysClipArea.x -= expandWidth;
            coordSysClipArea.width += expandWidth * 2;
          } else {
            coordSysClipArea.y -= expandWidth;
            coordSysClipArea.height += expandWidth * 2;
          }
        }
      }

      return coordSysClipArea;
    }

    var BarView =
    /** @class */
    function (_super) {
      __extends(BarView, _super);

      function BarView() {
        var _this = _super.call(this) || this;

        _this.type = BarView.type;
        _this._isFirstFrame = true;
        return _this;
      }

      BarView.prototype.render = function (seriesModel, ecModel, api, payload) {
        this._model = seriesModel;

        this._removeOnRenderedListener(api);

        this._updateDrawMode(seriesModel);

        var coordinateSystemType = seriesModel.get('coordinateSystem');

        if (coordinateSystemType === 'cartesian2d' || coordinateSystemType === 'polar') {
          // Clear previously rendered progressive elements.
          this._progressiveEls = null;
          this._isLargeDraw ? this._renderLarge(seriesModel, ecModel, api) : this._renderNormal(seriesModel, ecModel, api, payload);
        } else if ("development" !== 'production') {
          warn('Only cartesian2d and polar supported for bar.');
        }
      };

      BarView.prototype.incrementalPrepareRender = function (seriesModel) {
        this._clear();

        this._updateDrawMode(seriesModel); // incremental also need to clip, otherwise might be overlow.
        // But must not set clip in each frame, otherwise all of the children will be marked redraw.


        this._updateLargeClip(seriesModel);
      };

      BarView.prototype.incrementalRender = function (params, seriesModel) {
        // Reset
        this._progressiveEls = []; // Do not support progressive in normal mode.

        this._incrementalRenderLarge(params, seriesModel);
      };

      BarView.prototype.eachRendered = function (cb) {
        traverseElements(this._progressiveEls || this.group, cb);
      };

      BarView.prototype._updateDrawMode = function (seriesModel) {
        var isLargeDraw = seriesModel.pipelineContext.large;

        if (this._isLargeDraw == null || isLargeDraw !== this._isLargeDraw) {
          this._isLargeDraw = isLargeDraw;

          this._clear();
        }
      };

      BarView.prototype._renderNormal = function (seriesModel, ecModel, api, payload) {
        var group = this.group;
        var data = seriesModel.getData();
        var oldData = this._data;
        var coord = seriesModel.coordinateSystem;
        var baseAxis = coord.getBaseAxis();
        var isHorizontalOrRadial;

        if (coord.type === 'cartesian2d') {
          isHorizontalOrRadial = baseAxis.isHorizontal();
        } else if (coord.type === 'polar') {
          isHorizontalOrRadial = baseAxis.dim === 'angle';
        }

        var animationModel = seriesModel.isAnimationEnabled() ? seriesModel : null;
        var realtimeSortCfg = shouldRealtimeSort(seriesModel, coord);

        if (realtimeSortCfg) {
          this._enableRealtimeSort(realtimeSortCfg, data, api);
        }

        var needsClip = seriesModel.get('clip', true) || realtimeSortCfg;
        var coordSysClipArea = getClipArea(coord, data); // If there is clipPath created in large mode. Remove it.

        group.removeClipPath(); // We don't use clipPath in normal mode because we needs a perfect animation
        // And don't want the label are clipped.

        var roundCap = seriesModel.get('roundCap', true);
        var drawBackground = seriesModel.get('showBackground', true);
        var backgroundModel = seriesModel.getModel('backgroundStyle');
        var barBorderRadius = backgroundModel.get('borderRadius') || 0;
        var bgEls = [];
        var oldBgEls = this._backgroundEls;
        var isInitSort = payload && payload.isInitSort;
        var isChangeOrder = payload && payload.type === 'changeAxisOrder';

        function createBackground(dataIndex) {
          var bgLayout = getLayout[coord.type](data, dataIndex);
          var bgEl = createBackgroundEl(coord, isHorizontalOrRadial, bgLayout);
          bgEl.useStyle(backgroundModel.getItemStyle()); // Only cartesian2d support borderRadius.

          if (coord.type === 'cartesian2d') {
            bgEl.setShape('r', barBorderRadius);
          }

          bgEls[dataIndex] = bgEl;
          return bgEl;
        }
        data.diff(oldData).add(function (dataIndex) {
          var itemModel = data.getItemModel(dataIndex);
          var layout = getLayout[coord.type](data, dataIndex, itemModel);

          if (drawBackground) {
            createBackground(dataIndex);
          } // If dataZoom in filteMode: 'empty', the baseValue can be set as NaN in "axisProxy".


          if (!data.hasValue(dataIndex) || !isValidLayout[coord.type](layout)) {
            return;
          }

          var isClipped = false;

          if (needsClip) {
            // Clip will modify the layout params.
            // And return a boolean to determine if the shape are fully clipped.
            isClipped = clip[coord.type](coordSysClipArea, layout);
          }

          var el = elementCreator[coord.type](seriesModel, data, dataIndex, layout, isHorizontalOrRadial, animationModel, baseAxis.model, false, roundCap);

          if (realtimeSortCfg) {
            /**
             * Force label animation because even if the element is
             * ignored because it's clipped, it may not be clipped after
             * changing order. Then, if not using forceLabelAnimation,
             * the label animation was never started, in which case,
             * the label will be the final value and doesn't have label
             * animation.
             */
            el.forceLabelAnimation = true;
          }

          updateStyle(el, data, dataIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, coord.type === 'polar');

          if (isInitSort) {
            el.attr({
              shape: layout
            });
          } else if (realtimeSortCfg) {
            updateRealtimeAnimation(realtimeSortCfg, animationModel, el, layout, dataIndex, isHorizontalOrRadial, false, false);
          } else {
            initProps(el, {
              shape: layout
            }, seriesModel, dataIndex);
          }

          data.setItemGraphicEl(dataIndex, el);
          group.add(el);
          el.ignore = isClipped;
        }).update(function (newIndex, oldIndex) {
          var itemModel = data.getItemModel(newIndex);
          var layout = getLayout[coord.type](data, newIndex, itemModel);

          if (drawBackground) {
            var bgEl = void 0;

            if (oldBgEls.length === 0) {
              bgEl = createBackground(oldIndex);
            } else {
              bgEl = oldBgEls[oldIndex];
              bgEl.useStyle(backgroundModel.getItemStyle()); // Only cartesian2d support borderRadius.

              if (coord.type === 'cartesian2d') {
                bgEl.setShape('r', barBorderRadius);
              }

              bgEls[newIndex] = bgEl;
            }

            var bgLayout = getLayout[coord.type](data, newIndex);
            var shape = createBackgroundShape(isHorizontalOrRadial, bgLayout, coord);
            updateProps(bgEl, {
              shape: shape
            }, animationModel, newIndex);
          }

          var el = oldData.getItemGraphicEl(oldIndex);

          if (!data.hasValue(newIndex) || !isValidLayout[coord.type](layout)) {
            group.remove(el);
            return;
          }

          var isClipped = false;

          if (needsClip) {
            isClipped = clip[coord.type](coordSysClipArea, layout);

            if (isClipped) {
              group.remove(el);
            }
          }

          if (!el) {
            el = elementCreator[coord.type](seriesModel, data, newIndex, layout, isHorizontalOrRadial, animationModel, baseAxis.model, !!el, roundCap);
          } else {
            saveOldStyle(el);
          }

          if (realtimeSortCfg) {
            el.forceLabelAnimation = true;
          }

          if (isChangeOrder) {
            var textEl = el.getTextContent();

            if (textEl) {
              var labelInnerStore = labelInner(textEl);

              if (labelInnerStore.prevValue != null) {
                /**
                 * Set preValue to be value so that no new label
                 * should be started, otherwise, it will take a full
                 * `animationDurationUpdate` time to finish the
                 * animation, which is not expected.
                 */
                labelInnerStore.prevValue = labelInnerStore.value;
              }
            }
          } // Not change anything if only order changed.
          // Especially not change label.
          else {
              updateStyle(el, data, newIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, coord.type === 'polar');
            }

          if (isInitSort) {
            el.attr({
              shape: layout
            });
          } else if (realtimeSortCfg) {
            updateRealtimeAnimation(realtimeSortCfg, animationModel, el, layout, newIndex, isHorizontalOrRadial, true, isChangeOrder);
          } else {
            updateProps(el, {
              shape: layout
            }, seriesModel, newIndex, null);
          }

          data.setItemGraphicEl(newIndex, el);
          el.ignore = isClipped;
          group.add(el);
        }).remove(function (dataIndex) {
          var el = oldData.getItemGraphicEl(dataIndex);
          el && removeElementWithFadeOut(el, seriesModel, dataIndex);
        }).execute();
        var bgGroup = this._backgroundGroup || (this._backgroundGroup = new Group());
        bgGroup.removeAll();

        for (var i = 0; i < bgEls.length; ++i) {
          bgGroup.add(bgEls[i]);
        }

        group.add(bgGroup);
        this._backgroundEls = bgEls;
        this._data = data;
      };

      BarView.prototype._renderLarge = function (seriesModel, ecModel, api) {
        this._clear();

        createLarge(seriesModel, this.group);

        this._updateLargeClip(seriesModel);
      };

      BarView.prototype._incrementalRenderLarge = function (params, seriesModel) {
        this._removeBackground();

        createLarge(seriesModel, this.group, this._progressiveEls, true);
      };

      BarView.prototype._updateLargeClip = function (seriesModel) {
        // Use clipPath in large mode.
        var clipPath = seriesModel.get('clip', true) && createClipPath(seriesModel.coordinateSystem, false, seriesModel);
        var group = this.group;

        if (clipPath) {
          group.setClipPath(clipPath);
        } else {
          group.removeClipPath();
        }
      };

      BarView.prototype._enableRealtimeSort = function (realtimeSortCfg, data, api) {
        var _this = this; // If no data in the first frame, wait for data to initSort


        if (!data.count()) {
          return;
        }

        var baseAxis = realtimeSortCfg.baseAxis;

        if (this._isFirstFrame) {
          this._dispatchInitSort(data, realtimeSortCfg, api);

          this._isFirstFrame = false;
        } else {
          var orderMapping_1 = function (idx) {
            var el = data.getItemGraphicEl(idx);
            var shape = el && el.shape;
            return shape && // The result should be consistent with the initial sort by data value.
            // Do not support the case that both positive and negative exist.
            Math.abs(baseAxis.isHorizontal() ? shape.height : shape.width) // If data is NaN, shape.xxx may be NaN, so use || 0 here in case
            || 0;
          };

          this._onRendered = function () {
            _this._updateSortWithinSameData(data, orderMapping_1, baseAxis, api);
          };

          api.getZr().on('rendered', this._onRendered);
        }
      };

      BarView.prototype._dataSort = function (data, baseAxis, orderMapping) {
        var info = [];
        data.each(data.mapDimension(baseAxis.dim), function (ordinalNumber, dataIdx) {
          var mappedValue = orderMapping(dataIdx);
          mappedValue = mappedValue == null ? NaN : mappedValue;
          info.push({
            dataIndex: dataIdx,
            mappedValue: mappedValue,
            ordinalNumber: ordinalNumber
          });
        });
        info.sort(function (a, b) {
          // If NaN, it will be treated as min val.
          return b.mappedValue - a.mappedValue;
        });
        return {
          ordinalNumbers: map(info, function (item) {
            return item.ordinalNumber;
          })
        };
      };

      BarView.prototype._isOrderChangedWithinSameData = function (data, orderMapping, baseAxis) {
        var scale = baseAxis.scale;
        var ordinalDataDim = data.mapDimension(baseAxis.dim);
        var lastValue = Number.MAX_VALUE;

        for (var tickNum = 0, len = scale.getOrdinalMeta().categories.length; tickNum < len; ++tickNum) {
          var rawIdx = data.rawIndexOf(ordinalDataDim, scale.getRawOrdinalNumber(tickNum));
          var value = rawIdx < 0 // If some tick have no bar, the tick will be treated as min.
          ? Number.MIN_VALUE // PENDING: if dataZoom on baseAxis exits, is it a performance issue?
          : orderMapping(data.indexOfRawIndex(rawIdx));

          if (value > lastValue) {
            return true;
          }

          lastValue = value;
        }

        return false;
      };
      /*
       * Consider the case when A and B changed order, whose representing
       * bars are both out of sight, we don't wish to trigger reorder action
       * as long as the order in the view doesn't change.
       */


      BarView.prototype._isOrderDifferentInView = function (orderInfo, baseAxis) {
        var scale = baseAxis.scale;
        var extent = scale.getExtent();
        var tickNum = Math.max(0, extent[0]);
        var tickMax = Math.min(extent[1], scale.getOrdinalMeta().categories.length - 1);

        for (; tickNum <= tickMax; ++tickNum) {
          if (orderInfo.ordinalNumbers[tickNum] !== scale.getRawOrdinalNumber(tickNum)) {
            return true;
          }
        }
      };

      BarView.prototype._updateSortWithinSameData = function (data, orderMapping, baseAxis, api) {
        if (!this._isOrderChangedWithinSameData(data, orderMapping, baseAxis)) {
          return;
        }

        var sortInfo = this._dataSort(data, baseAxis, orderMapping);

        if (this._isOrderDifferentInView(sortInfo, baseAxis)) {
          this._removeOnRenderedListener(api);

          api.dispatchAction({
            type: 'changeAxisOrder',
            componentType: baseAxis.dim + 'Axis',
            axisId: baseAxis.index,
            sortInfo: sortInfo
          });
        }
      };

      BarView.prototype._dispatchInitSort = function (data, realtimeSortCfg, api) {
        var baseAxis = realtimeSortCfg.baseAxis;

        var sortResult = this._dataSort(data, baseAxis, function (dataIdx) {
          return data.get(data.mapDimension(realtimeSortCfg.otherAxis.dim), dataIdx);
        });

        api.dispatchAction({
          type: 'changeAxisOrder',
          componentType: baseAxis.dim + 'Axis',
          isInitSort: true,
          axisId: baseAxis.index,
          sortInfo: sortResult
        });
      };

      BarView.prototype.remove = function (ecModel, api) {
        this._clear(this._model);

        this._removeOnRenderedListener(api);
      };

      BarView.prototype.dispose = function (ecModel, api) {
        this._removeOnRenderedListener(api);
      };

      BarView.prototype._removeOnRenderedListener = function (api) {
        if (this._onRendered) {
          api.getZr().off('rendered', this._onRendered);
          this._onRendered = null;
        }
      };

      BarView.prototype._clear = function (model) {
        var group = this.group;
        var data = this._data;

        if (model && model.isAnimationEnabled() && data && !this._isLargeDraw) {
          this._removeBackground();

          this._backgroundEls = [];
          data.eachItemGraphicEl(function (el) {
            removeElementWithFadeOut(el, model, getECData(el).dataIndex);
          });
        } else {
          group.removeAll();
        }

        this._data = null;
        this._isFirstFrame = true;
      };

      BarView.prototype._removeBackground = function () {
        this.group.remove(this._backgroundGroup);
        this._backgroundGroup = null;
      };

      BarView.type = 'bar';
      return BarView;
    }(ChartView);

    var clip = {
      cartesian2d: function (coordSysBoundingRect, layout) {
        var signWidth = layout.width < 0 ? -1 : 1;
        var signHeight = layout.height < 0 ? -1 : 1; // Needs positive width and height

        if (signWidth < 0) {
          layout.x += layout.width;
          layout.width = -layout.width;
        }

        if (signHeight < 0) {
          layout.y += layout.height;
          layout.height = -layout.height;
        }

        var coordSysX2 = coordSysBoundingRect.x + coordSysBoundingRect.width;
        var coordSysY2 = coordSysBoundingRect.y + coordSysBoundingRect.height;
        var x = mathMax$6(layout.x, coordSysBoundingRect.x);
        var x2 = mathMin$6(layout.x + layout.width, coordSysX2);
        var y = mathMax$6(layout.y, coordSysBoundingRect.y);
        var y2 = mathMin$6(layout.y + layout.height, coordSysY2);
        var xClipped = x2 < x;
        var yClipped = y2 < y; // When xClipped or yClipped, the element will be marked as `ignore`.
        // But we should also place the element at the edge of the coord sys bounding rect.
        // Because if data changed and the bar shows again, its transition animation
        // will begin at this place.

        layout.x = xClipped && x > coordSysX2 ? x2 : x;
        layout.y = yClipped && y > coordSysY2 ? y2 : y;
        layout.width = xClipped ? 0 : x2 - x;
        layout.height = yClipped ? 0 : y2 - y; // Reverse back

        if (signWidth < 0) {
          layout.x += layout.width;
          layout.width = -layout.width;
        }

        if (signHeight < 0) {
          layout.y += layout.height;
          layout.height = -layout.height;
        }

        return xClipped || yClipped;
      },
      polar: function (coordSysClipArea, layout) {
        var signR = layout.r0 <= layout.r ? 1 : -1; // Make sure r is larger than r0

        if (signR < 0) {
          var tmp = layout.r;
          layout.r = layout.r0;
          layout.r0 = tmp;
        }

        var r = mathMin$6(layout.r, coordSysClipArea.r);
        var r0 = mathMax$6(layout.r0, coordSysClipArea.r0);
        layout.r = r;
        layout.r0 = r0;
        var clipped = r - r0 < 0; // Reverse back

        if (signR < 0) {
          var tmp = layout.r;
          layout.r = layout.r0;
          layout.r0 = tmp;
        }

        return clipped;
      }
    };
    var elementCreator = {
      cartesian2d: function (seriesModel, data, newIndex, layout, isHorizontal, animationModel, axisModel, isUpdate, roundCap) {
        var rect = new Rect({
          shape: extend({}, layout),
          z2: 1
        });
        rect.__dataIndex = newIndex;
        rect.name = 'item';

        if (animationModel) {
          var rectShape = rect.shape;
          var animateProperty = isHorizontal ? 'height' : 'width';
          rectShape[animateProperty] = 0;
        }

        return rect;
      },
      polar: function (seriesModel, data, newIndex, layout, isRadial, animationModel, axisModel, isUpdate, roundCap) {
        var ShapeClass = !isRadial && roundCap ? SausagePath : Sector;
        var sector = new ShapeClass({
          shape: layout,
          z2: 1
        });
        sector.name = 'item';
        var positionMap = createPolarPositionMapping(isRadial);
        sector.calculateTextPosition = createSectorCalculateTextPosition(positionMap, {
          isRoundCap: ShapeClass === SausagePath
        }); // Animation

        if (animationModel) {
          var sectorShape = sector.shape;
          var animateProperty = isRadial ? 'r' : 'endAngle';
          var animateTarget = {};
          sectorShape[animateProperty] = isRadial ? 0 : layout.startAngle;
          animateTarget[animateProperty] = layout[animateProperty];
          (isUpdate ? updateProps : initProps)(sector, {
            shape: animateTarget // __value: typeof dataValue === 'string' ? parseInt(dataValue, 10) : dataValue

          }, animationModel);
        }

        return sector;
      }
    };

    function shouldRealtimeSort(seriesModel, coordSys) {
      var realtimeSortOption = seriesModel.get('realtimeSort', true);
      var baseAxis = coordSys.getBaseAxis();

      if ("development" !== 'production') {
        if (realtimeSortOption) {
          if (baseAxis.type !== 'category') {
            warn('`realtimeSort` will not work because this bar series is not based on a category axis.');
          }

          if (coordSys.type !== 'cartesian2d') {
            warn('`realtimeSort` will not work because this bar series is not on cartesian2d.');
          }
        }
      }

      if (realtimeSortOption && baseAxis.type === 'category' && coordSys.type === 'cartesian2d') {
        return {
          baseAxis: baseAxis,
          otherAxis: coordSys.getOtherAxis(baseAxis)
        };
      }
    }

    function updateRealtimeAnimation(realtimeSortCfg, seriesAnimationModel, el, layout, newIndex, isHorizontal, isUpdate, isChangeOrder) {
      var seriesTarget;
      var axisTarget;

      if (isHorizontal) {
        axisTarget = {
          x: layout.x,
          width: layout.width
        };
        seriesTarget = {
          y: layout.y,
          height: layout.height
        };
      } else {
        axisTarget = {
          y: layout.y,
          height: layout.height
        };
        seriesTarget = {
          x: layout.x,
          width: layout.width
        };
      }

      if (!isChangeOrder) {
        // Keep the original growth animation if only axis order changed.
        // Not start a new animation.
        (isUpdate ? updateProps : initProps)(el, {
          shape: seriesTarget
        }, seriesAnimationModel, newIndex, null);
      }

      var axisAnimationModel = seriesAnimationModel ? realtimeSortCfg.baseAxis.model : null;
      (isUpdate ? updateProps : initProps)(el, {
        shape: axisTarget
      }, axisAnimationModel, newIndex);
    }

    function checkPropertiesNotValid(obj, props) {
      for (var i = 0; i < props.length; i++) {
        if (!isFinite(obj[props[i]])) {
          return true;
        }
      }

      return false;
    }

    var rectPropties = ['x', 'y', 'width', 'height'];
    var polarPropties = ['cx', 'cy', 'r', 'startAngle', 'endAngle'];
    var isValidLayout = {
      cartesian2d: function (layout) {
        return !checkPropertiesNotValid(layout, rectPropties);
      },
      polar: function (layout) {
        return !checkPropertiesNotValid(layout, polarPropties);
      }
    };
    var getLayout = {
      // itemModel is only used to get borderWidth, which is not needed
      // when calculating bar background layout.
      cartesian2d: function (data, dataIndex, itemModel) {
        var layout = data.getItemLayout(dataIndex);
        var fixedLineWidth = itemModel ? getLineWidth(itemModel, layout) : 0; // fix layout with lineWidth

        var signX = layout.width > 0 ? 1 : -1;
        var signY = layout.height > 0 ? 1 : -1;
        return {
          x: layout.x + signX * fixedLineWidth / 2,
          y: layout.y + signY * fixedLineWidth / 2,
          width: layout.width - signX * fixedLineWidth,
          height: layout.height - signY * fixedLineWidth
        };
      },
      polar: function (data, dataIndex, itemModel) {
        var layout = data.getItemLayout(dataIndex);
        return {
          cx: layout.cx,
          cy: layout.cy,
          r0: layout.r0,
          r: layout.r,
          startAngle: layout.startAngle,
          endAngle: layout.endAngle,
          clockwise: layout.clockwise
        };
      }
    };

    function isZeroOnPolar(layout) {
      return layout.startAngle != null && layout.endAngle != null && layout.startAngle === layout.endAngle;
    }

    function createPolarPositionMapping(isRadial) {
      return function (isRadial) {
        var arcOrAngle = isRadial ? 'Arc' : 'Angle';
        return function (position) {
          switch (position) {
            case 'start':
            case 'insideStart':
            case 'end':
            case 'insideEnd':
              return position + arcOrAngle;

            default:
              return position;
          }
        };
      }(isRadial);
    }

    function updateStyle(el, data, dataIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, isPolar) {
      var style = data.getItemVisual(dataIndex, 'style');

      if (!isPolar) {
        el.setShape('r', itemModel.get(['itemStyle', 'borderRadius']) || 0);
      }

      el.useStyle(style);
      var cursorStyle = itemModel.getShallow('cursor');
      cursorStyle && el.attr('cursor', cursorStyle);
      var labelPositionOutside = isPolar ? isHorizontalOrRadial ? layout.r >= layout.r0 ? 'endArc' : 'startArc' : layout.endAngle >= layout.startAngle ? 'endAngle' : 'startAngle' : isHorizontalOrRadial ? layout.height >= 0 ? 'bottom' : 'top' : layout.width >= 0 ? 'right' : 'left';
      var labelStatesModels = getLabelStatesModels(itemModel);
      setLabelStyle(el, labelStatesModels, {
        labelFetcher: seriesModel,
        labelDataIndex: dataIndex,
        defaultText: getDefaultLabel(seriesModel.getData(), dataIndex),
        inheritColor: style.fill,
        defaultOpacity: style.opacity,
        defaultOutsidePosition: labelPositionOutside
      });
      var label = el.getTextContent();

      if (isPolar && label) {
        var position = itemModel.get(['label', 'position']);
        el.textConfig.inside = position === 'middle' ? true : null;
        setSectorTextRotation(el, position === 'outside' ? labelPositionOutside : position, createPolarPositionMapping(isHorizontalOrRadial), itemModel.get(['label', 'rotate']));
      }

      setLabelValueAnimation(label, labelStatesModels, seriesModel.getRawValue(dataIndex), function (value) {
        return getDefaultInterpolatedLabel(data, value);
      });
      var emphasisModel = itemModel.getModel(['emphasis']);
      toggleHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
      setStatesStylesFromModel(el, itemModel);

      if (isZeroOnPolar(layout)) {
        el.style.fill = 'none';
        el.style.stroke = 'none';
        each(el.states, function (state) {
          if (state.style) {
            state.style.fill = state.style.stroke = 'none';
          }
        });
      }
    } // In case width or height are too small.


    function getLineWidth(itemModel, rawLayout) {
      // Has no border.
      var borderColor = itemModel.get(['itemStyle', 'borderColor']);

      if (!borderColor || borderColor === 'none') {
        return 0;
      }

      var lineWidth = itemModel.get(['itemStyle', 'borderWidth']) || 0; // width or height may be NaN for empty data

      var width = isNaN(rawLayout.width) ? Number.MAX_VALUE : Math.abs(rawLayout.width);
      var height = isNaN(rawLayout.height) ? Number.MAX_VALUE : Math.abs(rawLayout.height);
      return Math.min(lineWidth, width, height);
    }

    var LagePathShape =
    /** @class */
    function () {
      function LagePathShape() {}

      return LagePathShape;
    }();

    var LargePath =
    /** @class */
    function (_super) {
      __extends(LargePath, _super);

      function LargePath(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'largeBar';
        return _this;
      }

      LargePath.prototype.getDefaultShape = function () {
        return new LagePathShape();
      };

      LargePath.prototype.buildPath = function (ctx, shape) {
        // Drawing lines is more efficient than drawing
        // a whole line or drawing rects.
        var points = shape.points;
        var baseDimIdx = this.baseDimIdx;
        var valueDimIdx = 1 - this.baseDimIdx;
        var startPoint = [];
        var size = [];
        var barWidth = this.barWidth;

        for (var i = 0; i < points.length; i += 3) {
          size[baseDimIdx] = barWidth;
          size[valueDimIdx] = points[i + 2];
          startPoint[baseDimIdx] = points[i + baseDimIdx];
          startPoint[valueDimIdx] = points[i + valueDimIdx];
          ctx.rect(startPoint[0], startPoint[1], size[0], size[1]);
        }
      };

      return LargePath;
    }(Path);

    function createLarge(seriesModel, group, progressiveEls, incremental) {
      // TODO support polar
      var data = seriesModel.getData();
      var baseDimIdx = data.getLayout('valueAxisHorizontal') ? 1 : 0;
      var largeDataIndices = data.getLayout('largeDataIndices');
      var barWidth = data.getLayout('size');
      var backgroundModel = seriesModel.getModel('backgroundStyle');
      var bgPoints = data.getLayout('largeBackgroundPoints');

      if (bgPoints) {
        var bgEl = new LargePath({
          shape: {
            points: bgPoints
          },
          incremental: !!incremental,
          silent: true,
          z2: 0
        });
        bgEl.baseDimIdx = baseDimIdx;
        bgEl.largeDataIndices = largeDataIndices;
        bgEl.barWidth = barWidth;
        bgEl.useStyle(backgroundModel.getItemStyle());
        group.add(bgEl);
        progressiveEls && progressiveEls.push(bgEl);
      }

      var el = new LargePath({
        shape: {
          points: data.getLayout('largePoints')
        },
        incremental: !!incremental,
        ignoreCoarsePointer: true,
        z2: 1
      });
      el.baseDimIdx = baseDimIdx;
      el.largeDataIndices = largeDataIndices;
      el.barWidth = barWidth;
      group.add(el);
      el.useStyle(data.getVisual('style')); // Enable tooltip and user mouse/touch event handlers.

      getECData(el).seriesIndex = seriesModel.seriesIndex;

      if (!seriesModel.get('silent')) {
        el.on('mousedown', largePathUpdateDataIndex);
        el.on('mousemove', largePathUpdateDataIndex);
      }

      progressiveEls && progressiveEls.push(el);
    } // Use throttle to avoid frequently traverse to find dataIndex.


    var largePathUpdateDataIndex = throttle(function (event) {
      var largePath = this;
      var dataIndex = largePathFindDataIndex(largePath, event.offsetX, event.offsetY);
      getECData(largePath).dataIndex = dataIndex >= 0 ? dataIndex : null;
    }, 30, false);

    function largePathFindDataIndex(largePath, x, y) {
      var baseDimIdx = largePath.baseDimIdx;
      var valueDimIdx = 1 - baseDimIdx;
      var points = largePath.shape.points;
      var largeDataIndices = largePath.largeDataIndices;
      var startPoint = [];
      var size = [];
      var barWidth = largePath.barWidth;

      for (var i = 0, len = points.length / 3; i < len; i++) {
        var ii = i * 3;
        size[baseDimIdx] = barWidth;
        size[valueDimIdx] = points[ii + 2];
        startPoint[baseDimIdx] = points[ii + baseDimIdx];
        startPoint[valueDimIdx] = points[ii + valueDimIdx];

        if (size[valueDimIdx] < 0) {
          startPoint[valueDimIdx] += size[valueDimIdx];
          size[valueDimIdx] = -size[valueDimIdx];
        }

        if (x >= startPoint[0] && x <= startPoint[0] + size[0] && y >= startPoint[1] && y <= startPoint[1] + size[1]) {
          return largeDataIndices[i];
        }
      }

      return -1;
    }

    function createBackgroundShape(isHorizontalOrRadial, layout, coord) {
      if (isCoordinateSystemType(coord, 'cartesian2d')) {
        var rectShape = layout;
        var coordLayout = coord.getArea();
        return {
          x: isHorizontalOrRadial ? rectShape.x : coordLayout.x,
          y: isHorizontalOrRadial ? coordLayout.y : rectShape.y,
          width: isHorizontalOrRadial ? rectShape.width : coordLayout.width,
          height: isHorizontalOrRadial ? coordLayout.height : rectShape.height
        };
      } else {
        var coordLayout = coord.getArea();
        var sectorShape = layout;
        return {
          cx: coordLayout.cx,
          cy: coordLayout.cy,
          r0: isHorizontalOrRadial ? coordLayout.r0 : sectorShape.r0,
          r: isHorizontalOrRadial ? coordLayout.r : sectorShape.r,
          startAngle: isHorizontalOrRadial ? sectorShape.startAngle : 0,
          endAngle: isHorizontalOrRadial ? sectorShape.endAngle : Math.PI * 2
        };
      }
    }

    function createBackgroundEl(coord, isHorizontalOrRadial, layout) {
      var ElementClz = coord.type === 'polar' ? Sector : Rect;
      return new ElementClz({
        shape: createBackgroundShape(isHorizontalOrRadial, layout, coord),
        silent: true,
        z2: 0
      });
    }

    function install$3(registers) {
      registers.registerChartView(BarView);
      registers.registerSeriesModel(BarSeriesModel);
      registers.registerLayout(registers.PRIORITY.VISUAL.LAYOUT, curry(layout, 'bar')); // Do layout after other overall layout, which can prepare some information.

      registers.registerLayout(registers.PRIORITY.VISUAL.PROGRESSIVE_LAYOUT, createProgressiveLayout('bar')); // Down sample after filter

      registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, dataSample('bar'));
      /**
       * @payload
       * @property {string} [componentType=series]
       * @property {number} [dx]
       * @property {number} [dy]
       * @property {number} [zoom]
       * @property {number} [originX]
       * @property {number} [originY]
       */

      registers.registerAction({
        type: 'changeAxisOrder',
        event: 'changeAxisOrder',
        update: 'update'
      }, function (payload, ecModel) {
        var componentType = payload.componentType || 'series';
        ecModel.eachComponent({
          mainType: componentType,
          query: payload
        }, function (componentModel) {
          if (payload.sortInfo) {
            componentModel.axis.setCategorySortInfo(payload.sortInfo);
          }
        });
      });
    }

    var PI2$7 = Math.PI * 2;
    var RADIAN = Math.PI / 180;

    function getViewRect(seriesModel, api) {
      return getLayoutRect(seriesModel.getBoxLayoutParams(), {
        width: api.getWidth(),
        height: api.getHeight()
      });
    }

    function getBasicPieLayout(seriesModel, api) {
      var viewRect = getViewRect(seriesModel, api); // center can be string or number when coordinateSystem is specified

      var center = seriesModel.get('center');
      var radius = seriesModel.get('radius');

      if (!isArray(radius)) {
        radius = [0, radius];
      }

      var width = parsePercent$1(viewRect.width, api.getWidth());
      var height = parsePercent$1(viewRect.height, api.getHeight());
      var size = Math.min(width, height);
      var r0 = parsePercent$1(radius[0], size / 2);
      var r = parsePercent$1(radius[1], size / 2);
      var cx;
      var cy;
      var coordSys = seriesModel.coordinateSystem;

      if (coordSys) {
        // percentage is not allowed when coordinate system is specified
        var point = coordSys.dataToPoint(center);
        cx = point[0] || 0;
        cy = point[1] || 0;
      } else {
        if (!isArray(center)) {
          center = [center, center];
        }

        cx = parsePercent$1(center[0], width) + viewRect.x;
        cy = parsePercent$1(center[1], height) + viewRect.y;
      }

      return {
        cx: cx,
        cy: cy,
        r0: r0,
        r: r
      };
    }
    function pieLayout(seriesType, ecModel, api) {
      ecModel.eachSeriesByType(seriesType, function (seriesModel) {
        var data = seriesModel.getData();
        var valueDim = data.mapDimension('value');
        var viewRect = getViewRect(seriesModel, api);

        var _a = getBasicPieLayout(seriesModel, api),
            cx = _a.cx,
            cy = _a.cy,
            r = _a.r,
            r0 = _a.r0;

        var startAngle = -seriesModel.get('startAngle') * RADIAN;
        var minAngle = seriesModel.get('minAngle') * RADIAN;
        var validDataCount = 0;
        data.each(valueDim, function (value) {
          !isNaN(value) && validDataCount++;
        });
        var sum = data.getSum(valueDim); // Sum may be 0

        var unitRadian = Math.PI / (sum || validDataCount) * 2;
        var clockwise = seriesModel.get('clockwise');
        var roseType = seriesModel.get('roseType');
        var stillShowZeroSum = seriesModel.get('stillShowZeroSum'); // [0...max]

        var extent = data.getDataExtent(valueDim);
        extent[0] = 0; // In the case some sector angle is smaller than minAngle

        var restAngle = PI2$7;
        var valueSumLargerThanMinAngle = 0;
        var currentAngle = startAngle;
        var dir = clockwise ? 1 : -1;
        data.setLayout({
          viewRect: viewRect,
          r: r
        });
        data.each(valueDim, function (value, idx) {
          var angle;

          if (isNaN(value)) {
            data.setItemLayout(idx, {
              angle: NaN,
              startAngle: NaN,
              endAngle: NaN,
              clockwise: clockwise,
              cx: cx,
              cy: cy,
              r0: r0,
              r: roseType ? NaN : r
            });
            return;
          } // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样？


          if (roseType !== 'area') {
            angle = sum === 0 && stillShowZeroSum ? unitRadian : value * unitRadian;
          } else {
            angle = PI2$7 / validDataCount;
          }

          if (angle < minAngle) {
            angle = minAngle;
            restAngle -= minAngle;
          } else {
            valueSumLargerThanMinAngle += value;
          }

          var endAngle = currentAngle + dir * angle;
          data.setItemLayout(idx, {
            angle: angle,
            startAngle: currentAngle,
            endAngle: endAngle,
            clockwise: clockwise,
            cx: cx,
            cy: cy,
            r0: r0,
            r: roseType ? linearMap(value, extent, [r0, r]) : r
          });
          currentAngle = endAngle;
        }); // Some sector is constrained by minAngle
        // Rest sectors needs recalculate angle

        if (restAngle < PI2$7 && validDataCount) {
          // Average the angle if rest angle is not enough after all angles is
          // Constrained by minAngle
          if (restAngle <= 1e-3) {
            var angle_1 = PI2$7 / validDataCount;
            data.each(valueDim, function (value, idx) {
              if (!isNaN(value)) {
                var layout_1 = data.getItemLayout(idx);
                layout_1.angle = angle_1;
                layout_1.startAngle = startAngle + dir * idx * angle_1;
                layout_1.endAngle = startAngle + dir * (idx + 1) * angle_1;
              }
            });
          } else {
            unitRadian = restAngle / valueSumLargerThanMinAngle;
            currentAngle = startAngle;
            data.each(valueDim, function (value, idx) {
              if (!isNaN(value)) {
                var layout_2 = data.getItemLayout(idx);
                var angle = layout_2.angle === minAngle ? minAngle : value * unitRadian;
                layout_2.startAngle = currentAngle;
                layout_2.endAngle = currentAngle + dir * angle;
                currentAngle += dir * angle;
              }
            });
          }
        }
      });
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    function dataFilter(seriesType) {
      return {
        seriesType: seriesType,
        reset: function (seriesModel, ecModel) {
          var legendModels = ecModel.findComponents({
            mainType: 'legend'
          });

          if (!legendModels || !legendModels.length) {
            return;
          }

          var data = seriesModel.getData();
          data.filterSelf(function (idx) {
            var name = data.getName(idx); // If in any legend component the status is not selected.

            for (var i = 0; i < legendModels.length; i++) {
              // @ts-ignore FIXME: LegendModel
              if (!legendModels[i].isSelected(name)) {
                return false;
              }
            }

            return true;
          });
        }
      };
    }

    var RADIAN$1 = Math.PI / 180;

    function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight, viewLeft, viewTop, farthestX) {
      if (list.length < 2) {
        return;
      }

      function recalculateXOnSemiToAlignOnEllipseCurve(semi) {
        var rB = semi.rB;
        var rB2 = rB * rB;

        for (var i = 0; i < semi.list.length; i++) {
          var item = semi.list[i];
          var dy = Math.abs(item.label.y - cy); // horizontal r is always same with original r because x is not changed.

          var rA = r + item.len;
          var rA2 = rA * rA; // Use ellipse implicit function to calculate x

          var dx = Math.sqrt((1 - Math.abs(dy * dy / rB2)) * rA2);
          var newX = cx + (dx + item.len2) * dir;
          var deltaX = newX - item.label.x;
          var newTargetWidth = item.targetTextWidth - deltaX * dir; // text x is changed, so need to recalculate width.

          constrainTextWidth(item, newTargetWidth, true);
          item.label.x = newX;
        }
      } // Adjust X based on the shifted y. Make tight labels aligned on an ellipse curve.


      function recalculateX(items) {
        // Extremes of
        var topSemi = {
          list: [],
          maxY: 0
        };
        var bottomSemi = {
          list: [],
          maxY: 0
        };

        for (var i = 0; i < items.length; i++) {
          if (items[i].labelAlignTo !== 'none') {
            continue;
          }

          var item = items[i];
          var semi = item.label.y > cy ? bottomSemi : topSemi;
          var dy = Math.abs(item.label.y - cy);

          if (dy >= semi.maxY) {
            var dx = item.label.x - cx - item.len2 * dir; // horizontal r is always same with original r because x is not changed.

            var rA = r + item.len; // Canculate rB based on the topest / bottemest label.

            var rB = Math.abs(dx) < rA ? Math.sqrt(dy * dy / (1 - dx * dx / rA / rA)) : rA;
            semi.rB = rB;
            semi.maxY = dy;
          }

          semi.list.push(item);
        }

        recalculateXOnSemiToAlignOnEllipseCurve(topSemi);
        recalculateXOnSemiToAlignOnEllipseCurve(bottomSemi);
      }

      var len = list.length;

      for (var i = 0; i < len; i++) {
        if (list[i].position === 'outer' && list[i].labelAlignTo === 'labelLine') {
          var dx = list[i].label.x - farthestX;
          list[i].linePoints[1][0] += dx;
          list[i].label.x = farthestX;
        }
      }

      if (shiftLayoutOnY(list, viewTop, viewTop + viewHeight)) {
        recalculateX(list);
      }
    }

    function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop) {
      var leftList = [];
      var rightList = [];
      var leftmostX = Number.MAX_VALUE;
      var rightmostX = -Number.MAX_VALUE;

      for (var i = 0; i < labelLayoutList.length; i++) {
        var label = labelLayoutList[i].label;

        if (isPositionCenter(labelLayoutList[i])) {
          continue;
        }

        if (label.x < cx) {
          leftmostX = Math.min(leftmostX, label.x);
          leftList.push(labelLayoutList[i]);
        } else {
          rightmostX = Math.max(rightmostX, label.x);
          rightList.push(labelLayoutList[i]);
        }
      }

      for (var i = 0; i < labelLayoutList.length; i++) {
        var layout = labelLayoutList[i];

        if (!isPositionCenter(layout) && layout.linePoints) {
          if (layout.labelStyleWidth != null) {
            continue;
          }

          var label = layout.label;
          var linePoints = layout.linePoints;
          var targetTextWidth = void 0;

          if (layout.labelAlignTo === 'edge') {
            if (label.x < cx) {
              targetTextWidth = linePoints[2][0] - layout.labelDistance - viewLeft - layout.edgeDistance;
            } else {
              targetTextWidth = viewLeft + viewWidth - layout.edgeDistance - linePoints[2][0] - layout.labelDistance;
            }
          } else if (layout.labelAlignTo === 'labelLine') {
            if (label.x < cx) {
              targetTextWidth = leftmostX - viewLeft - layout.bleedMargin;
            } else {
              targetTextWidth = viewLeft + viewWidth - rightmostX - layout.bleedMargin;
            }
          } else {
            if (label.x < cx) {
              targetTextWidth = label.x - viewLeft - layout.bleedMargin;
            } else {
              targetTextWidth = viewLeft + viewWidth - label.x - layout.bleedMargin;
            }
          }

          layout.targetTextWidth = targetTextWidth;
          constrainTextWidth(layout, targetTextWidth);
        }
      }

      adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight, viewLeft, viewTop, rightmostX);
      adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight, viewLeft, viewTop, leftmostX);

      for (var i = 0; i < labelLayoutList.length; i++) {
        var layout = labelLayoutList[i];

        if (!isPositionCenter(layout) && layout.linePoints) {
          var label = layout.label;
          var linePoints = layout.linePoints;
          var isAlignToEdge = layout.labelAlignTo === 'edge';
          var padding = label.style.padding;
          var paddingH = padding ? padding[1] + padding[3] : 0; // textRect.width already contains paddingH if bgColor is set

          var extraPaddingH = label.style.backgroundColor ? 0 : paddingH;
          var realTextWidth = layout.rect.width + extraPaddingH;
          var dist = linePoints[1][0] - linePoints[2][0];

          if (isAlignToEdge) {
            if (label.x < cx) {
              linePoints[2][0] = viewLeft + layout.edgeDistance + realTextWidth + layout.labelDistance;
            } else {
              linePoints[2][0] = viewLeft + viewWidth - layout.edgeDistance - realTextWidth - layout.labelDistance;
            }
          } else {
            if (label.x < cx) {
              linePoints[2][0] = label.x + layout.labelDistance;
            } else {
              linePoints[2][0] = label.x - layout.labelDistance;
            }

            linePoints[1][0] = linePoints[2][0] + dist;
          }

          linePoints[1][1] = linePoints[2][1] = label.y;
        }
      }
    }
    /**
     * Set max width of each label, and then wrap each label to the max width.
     *
     * @param layout label layout
     * @param availableWidth max width for the label to display
     * @param forceRecalculate recaculate the text layout even if the current width
     * is smaller than `availableWidth`. This is useful when the text was previously
     * wrapped by calling `constrainTextWidth` but now `availableWidth` changed, in
     * which case, previous wrapping should be redo.
     */


    function constrainTextWidth(layout, availableWidth, forceRecalculate) {
      if (forceRecalculate === void 0) {
        forceRecalculate = false;
      }

      if (layout.labelStyleWidth != null) {
        // User-defined style.width has the highest priority.
        return;
      }

      var label = layout.label;
      var style = label.style;
      var textRect = layout.rect;
      var bgColor = style.backgroundColor;
      var padding = style.padding;
      var paddingH = padding ? padding[1] + padding[3] : 0;
      var overflow = style.overflow; // textRect.width already contains paddingH if bgColor is set

      var oldOuterWidth = textRect.width + (bgColor ? 0 : paddingH);

      if (availableWidth < oldOuterWidth || forceRecalculate) {
        var oldHeight = textRect.height;

        if (overflow && overflow.match('break')) {
          // Temporarily set background to be null to calculate
          // the bounding box without background.
          label.setStyle('backgroundColor', null); // Set constraining width

          label.setStyle('width', availableWidth - paddingH); // This is the real bounding box of the text without padding.

          var innerRect = label.getBoundingRect();
          label.setStyle('width', Math.ceil(innerRect.width));
          label.setStyle('backgroundColor', bgColor);
        } else {
          var availableInnerWidth = availableWidth - paddingH;
          var newWidth = availableWidth < oldOuterWidth // Current text is too wide, use `availableWidth` as max width.
          ? availableInnerWidth : // Current available width is enough, but the text may have
          // already been wrapped with a smaller available width.
          forceRecalculate ? availableInnerWidth > layout.unconstrainedWidth // Current available is larger than text width,
          // so don't constrain width (otherwise it may have
          // empty space in the background).
          ? null // Current available is smaller than text width, so
          // use the current available width as constraining
          // width.
          : availableInnerWidth : // Current available width is enough, so no need to
          // constrain.
          null;
          label.setStyle('width', newWidth);
        }

        var newRect = label.getBoundingRect();
        textRect.width = newRect.width;
        var margin = (label.style.margin || 0) + 2.1;
        textRect.height = newRect.height + margin;
        textRect.y -= (textRect.height - oldHeight) / 2;
      }
    }

    function isPositionCenter(sectorShape) {
      // Not change x for center label
      return sectorShape.position === 'center';
    }

    function pieLabelLayout(seriesModel) {
      var data = seriesModel.getData();
      var labelLayoutList = [];
      var cx;
      var cy;
      var hasLabelRotate = false;
      var minShowLabelRadian = (seriesModel.get('minShowLabelAngle') || 0) * RADIAN$1;
      var viewRect = data.getLayout('viewRect');
      var r = data.getLayout('r');
      var viewWidth = viewRect.width;
      var viewLeft = viewRect.x;
      var viewTop = viewRect.y;
      var viewHeight = viewRect.height;

      function setNotShow(el) {
        el.ignore = true;
      }

      function isLabelShown(label) {
        if (!label.ignore) {
          return true;
        }

        for (var key in label.states) {
          if (label.states[key].ignore === false) {
            return true;
          }
        }

        return false;
      }

      data.each(function (idx) {
        var sector = data.getItemGraphicEl(idx);
        var sectorShape = sector.shape;
        var label = sector.getTextContent();
        var labelLine = sector.getTextGuideLine();
        var itemModel = data.getItemModel(idx);
        var labelModel = itemModel.getModel('label'); // Use position in normal or emphasis

        var labelPosition = labelModel.get('position') || itemModel.get(['emphasis', 'label', 'position']);
        var labelDistance = labelModel.get('distanceToLabelLine');
        var labelAlignTo = labelModel.get('alignTo');
        var edgeDistance = parsePercent$1(labelModel.get('edgeDistance'), viewWidth);
        var bleedMargin = labelModel.get('bleedMargin');
        var labelLineModel = itemModel.getModel('labelLine');
        var labelLineLen = labelLineModel.get('length');
        labelLineLen = parsePercent$1(labelLineLen, viewWidth);
        var labelLineLen2 = labelLineModel.get('length2');
        labelLineLen2 = parsePercent$1(labelLineLen2, viewWidth);

        if (Math.abs(sectorShape.endAngle - sectorShape.startAngle) < minShowLabelRadian) {
          each(label.states, setNotShow);
          label.ignore = true;

          if (labelLine) {
            each(labelLine.states, setNotShow);
            labelLine.ignore = true;
          }

          return;
        }

        if (!isLabelShown(label)) {
          return;
        }

        var midAngle = (sectorShape.startAngle + sectorShape.endAngle) / 2;
        var nx = Math.cos(midAngle);
        var ny = Math.sin(midAngle);
        var textX;
        var textY;
        var linePoints;
        var textAlign;
        cx = sectorShape.cx;
        cy = sectorShape.cy;
        var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';

        if (labelPosition === 'center') {
          textX = sectorShape.cx;
          textY = sectorShape.cy;
          textAlign = 'center';
        } else {
          var x1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * nx : sectorShape.r * nx) + cx;
          var y1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * ny : sectorShape.r * ny) + cy;
          textX = x1 + nx * 3;
          textY = y1 + ny * 3;

          if (!isLabelInside) {
            // For roseType
            var x2 = x1 + nx * (labelLineLen + r - sectorShape.r);
            var y2 = y1 + ny * (labelLineLen + r - sectorShape.r);
            var x3 = x2 + (nx < 0 ? -1 : 1) * labelLineLen2;
            var y3 = y2;

            if (labelAlignTo === 'edge') {
              // Adjust textX because text align of edge is opposite
              textX = nx < 0 ? viewLeft + edgeDistance : viewLeft + viewWidth - edgeDistance;
            } else {
              textX = x3 + (nx < 0 ? -labelDistance : labelDistance);
            }

            textY = y3;
            linePoints = [[x1, y1], [x2, y2], [x3, y3]];
          }

          textAlign = isLabelInside ? 'center' : labelAlignTo === 'edge' ? nx > 0 ? 'right' : 'left' : nx > 0 ? 'left' : 'right';
        }

        var PI = Math.PI;
        var labelRotate = 0;
        var rotate = labelModel.get('rotate');

        if (isNumber(rotate)) {
          labelRotate = rotate * (PI / 180);
        } else if (labelPosition === 'center') {
          labelRotate = 0;
        } else if (rotate === 'radial' || rotate === true) {
          var radialAngle = nx < 0 ? -midAngle + PI : -midAngle;
          labelRotate = radialAngle;
        } else if (rotate === 'tangential' && labelPosition !== 'outside' && labelPosition !== 'outer') {
          var rad = Math.atan2(nx, ny);

          if (rad < 0) {
            rad = PI * 2 + rad;
          }

          var isDown = ny > 0;

          if (isDown) {
            rad = PI + rad;
          }

          labelRotate = rad - PI;
        }

        hasLabelRotate = !!labelRotate;
        label.x = textX;
        label.y = textY;
        label.rotation = labelRotate;
        label.setStyle({
          verticalAlign: 'middle'
        }); // Not sectorShape the inside label

        if (!isLabelInside) {
          var textRect = label.getBoundingRect().clone();
          textRect.applyTransform(label.getComputedTransform()); // Text has a default 1px stroke. Exclude this.

          var margin = (label.style.margin || 0) + 2.1;
          textRect.y -= margin / 2;
          textRect.height += margin;
          labelLayoutList.push({
            label: label,
            labelLine: labelLine,
            position: labelPosition,
            len: labelLineLen,
            len2: labelLineLen2,
            minTurnAngle: labelLineModel.get('minTurnAngle'),
            maxSurfaceAngle: labelLineModel.get('maxSurfaceAngle'),
            surfaceNormal: new Point(nx, ny),
            linePoints: linePoints,
            textAlign: textAlign,
            labelDistance: labelDistance,
            labelAlignTo: labelAlignTo,
            edgeDistance: edgeDistance,
            bleedMargin: bleedMargin,
            rect: textRect,
            unconstrainedWidth: textRect.width,
            labelStyleWidth: label.style.width
          });
        } else {
          label.setStyle({
            align: textAlign
          });
          var selectState = label.states.select;

          if (selectState) {
            selectState.x += label.x;
            selectState.y += label.y;
          }
        }

        sector.setTextConfig({
          inside: isLabelInside
        });
      });

      if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) {
        avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop);
      }

      for (var i = 0; i < labelLayoutList.length; i++) {
        var layout = labelLayoutList[i];
        var label = layout.label;
        var labelLine = layout.labelLine;
        var notShowLabel = isNaN(label.x) || isNaN(label.y);

        if (label) {
          label.setStyle({
            align: layout.textAlign
          });

          if (notShowLabel) {
            each(label.states, setNotShow);
            label.ignore = true;
          }

          var selectState = label.states.select;

          if (selectState) {
            selectState.x += label.x;
            selectState.y += label.y;
          }
        }

        if (labelLine) {
          var linePoints = layout.linePoints;

          if (notShowLabel || !linePoints) {
            each(labelLine.states, setNotShow);
            labelLine.ignore = true;
          } else {
            limitTurnAngle(linePoints, layout.minTurnAngle);
            limitSurfaceAngle(linePoints, layout.surfaceNormal, layout.maxSurfaceAngle);
            labelLine.setShape({
              points: linePoints
            }); // Set the anchor to the midpoint of sector

            label.__hostTarget.textGuideLineConfig = {
              anchor: new Point(linePoints[0][0], linePoints[0][1])
            };
          }
        }
      }
    }

    function getSectorCornerRadius(model, shape, zeroIfNull) {
      var cornerRadius = model.get('borderRadius');

      if (cornerRadius == null) {
        return zeroIfNull ? {
          cornerRadius: 0
        } : null;
      }

      if (!isArray(cornerRadius)) {
        cornerRadius = [cornerRadius, cornerRadius, cornerRadius, cornerRadius];
      }

      var dr = Math.abs(shape.r || 0 - shape.r0 || 0);
      return {
        cornerRadius: map(cornerRadius, function (cr) {
          return parsePercent(cr, dr);
        })
      };
    }

    /**
     * Piece of pie including Sector, Label, LabelLine
     */

    var PiePiece =
    /** @class */
    function (_super) {
      __extends(PiePiece, _super);

      function PiePiece(data, idx, startAngle) {
        var _this = _super.call(this) || this;

        _this.z2 = 2;
        var text = new ZRText();

        _this.setTextContent(text);

        _this.updateData(data, idx, startAngle, true);

        return _this;
      }

      PiePiece.prototype.updateData = function (data, idx, startAngle, firstCreate) {
        var sector = this;
        var seriesModel = data.hostModel;
        var itemModel = data.getItemModel(idx);
        var emphasisModel = itemModel.getModel('emphasis');
        var layout = data.getItemLayout(idx); // cornerRadius & innerCornerRadius doesn't exist in the item layout. Use `0` if null value is specified.
        // see `setItemLayout` in `pieLayout.ts`.

        var sectorShape = extend(getSectorCornerRadius(itemModel.getModel('itemStyle'), layout, true), layout); // Ignore NaN data.

        if (isNaN(sectorShape.startAngle)) {
          // Use NaN shape to avoid drawing shape.
          sector.setShape(sectorShape);
          return;
        }

        if (firstCreate) {
          sector.setShape(sectorShape);
          var animationType = seriesModel.getShallow('animationType');

          if (seriesModel.ecModel.ssr) {
            // Use scale animation in SSR mode(opacity?)
            // Because CSS SVG animation doesn't support very customized shape animation.
            initProps(sector, {
              scaleX: 0,
              scaleY: 0
            }, seriesModel, {
              dataIndex: idx,
              isFrom: true
            });
            sector.originX = sectorShape.cx;
            sector.originY = sectorShape.cy;
          } else if (animationType === 'scale') {
            sector.shape.r = layout.r0;
            initProps(sector, {
              shape: {
                r: layout.r
              }
            }, seriesModel, idx);
          } // Expansion
          else {
              if (startAngle != null) {
                sector.setShape({
                  startAngle: startAngle,
                  endAngle: startAngle
                });
                initProps(sector, {
                  shape: {
                    startAngle: layout.startAngle,
                    endAngle: layout.endAngle
                  }
                }, seriesModel, idx);
              } else {
                sector.shape.endAngle = layout.startAngle;
                updateProps(sector, {
                  shape: {
                    endAngle: layout.endAngle
                  }
                }, seriesModel, idx);
              }
            }
        } else {
          saveOldStyle(sector); // Transition animation from the old shape

          updateProps(sector, {
            shape: sectorShape
          }, seriesModel, idx);
        }

        sector.useStyle(data.getItemVisual(idx, 'style'));
        setStatesStylesFromModel(sector, itemModel);
        var midAngle = (layout.startAngle + layout.endAngle) / 2;
        var offset = seriesModel.get('selectedOffset');
        var dx = Math.cos(midAngle) * offset;
        var dy = Math.sin(midAngle) * offset;
        var cursorStyle = itemModel.getShallow('cursor');
        cursorStyle && sector.attr('cursor', cursorStyle);

        this._updateLabel(seriesModel, data, idx);

        sector.ensureState('emphasis').shape = extend({
          r: layout.r + (emphasisModel.get('scale') ? emphasisModel.get('scaleSize') || 0 : 0)
        }, getSectorCornerRadius(emphasisModel.getModel('itemStyle'), layout));
        extend(sector.ensureState('select'), {
          x: dx,
          y: dy,
          shape: getSectorCornerRadius(itemModel.getModel(['select', 'itemStyle']), layout)
        });
        extend(sector.ensureState('blur'), {
          shape: getSectorCornerRadius(itemModel.getModel(['blur', 'itemStyle']), layout)
        });
        var labelLine = sector.getTextGuideLine();
        var labelText = sector.getTextContent();
        labelLine && extend(labelLine.ensureState('select'), {
          x: dx,
          y: dy
        }); // TODO: needs dx, dy in zrender?

        extend(labelText.ensureState('select'), {
          x: dx,
          y: dy
        });
        toggleHoverEmphasis(this, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
      };

      PiePiece.prototype._updateLabel = function (seriesModel, data, idx) {
        var sector = this;
        var itemModel = data.getItemModel(idx);
        var labelLineModel = itemModel.getModel('labelLine');
        var style = data.getItemVisual(idx, 'style');
        var visualColor = style && style.fill;
        var visualOpacity = style && style.opacity;
        setLabelStyle(sector, getLabelStatesModels(itemModel), {
          labelFetcher: data.hostModel,
          labelDataIndex: idx,
          inheritColor: visualColor,
          defaultOpacity: visualOpacity,
          defaultText: seriesModel.getFormattedLabel(idx, 'normal') || data.getName(idx)
        });
        var labelText = sector.getTextContent(); // Set textConfig on sector.

        sector.setTextConfig({
          // reset position, rotation
          position: null,
          rotation: null
        }); // Make sure update style on labelText after setLabelStyle.
        // Because setLabelStyle will replace a new style on it.

        labelText.attr({
          z2: 10
        });
        var labelPosition = seriesModel.get(['label', 'position']);

        if (labelPosition !== 'outside' && labelPosition !== 'outer') {
          sector.removeTextGuideLine();
        } else {
          var polyline = this.getTextGuideLine();

          if (!polyline) {
            polyline = new Polyline();
            this.setTextGuideLine(polyline);
          } // Default use item visual color


          setLabelLineStyle(this, getLabelLineStatesModels(itemModel), {
            stroke: visualColor,
            opacity: retrieve3(labelLineModel.get(['lineStyle', 'opacity']), visualOpacity, 1)
          });
        }
      };

      return PiePiece;
    }(Sector); // Pie view


    var PieView =
    /** @class */
    function (_super) {
      __extends(PieView, _super);

      function PieView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.ignoreLabelLineUpdate = true;
        return _this;
      }

      PieView.prototype.render = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData();
        var oldData = this._data;
        var group = this.group;
        var startAngle; // First render

        if (!oldData && data.count() > 0) {
          var shape = data.getItemLayout(0);

          for (var s = 1; isNaN(shape && shape.startAngle) && s < data.count(); ++s) {
            shape = data.getItemLayout(s);
          }

          if (shape) {
            startAngle = shape.startAngle;
          }
        } // remove empty-circle if it exists


        if (this._emptyCircleSector) {
          group.remove(this._emptyCircleSector);
        } // when all data are filtered, show lightgray empty circle


        if (data.count() === 0 && seriesModel.get('showEmptyCircle')) {
          var sector = new Sector({
            shape: getBasicPieLayout(seriesModel, api)
          });
          sector.useStyle(seriesModel.getModel('emptyCircleStyle').getItemStyle());
          this._emptyCircleSector = sector;
          group.add(sector);
        }

        data.diff(oldData).add(function (idx) {
          var piePiece = new PiePiece(data, idx, startAngle);
          data.setItemGraphicEl(idx, piePiece);
          group.add(piePiece);
        }).update(function (newIdx, oldIdx) {
          var piePiece = oldData.getItemGraphicEl(oldIdx);
          piePiece.updateData(data, newIdx, startAngle);
          piePiece.off('click');
          group.add(piePiece);
          data.setItemGraphicEl(newIdx, piePiece);
        }).remove(function (idx) {
          var piePiece = oldData.getItemGraphicEl(idx);
          removeElementWithFadeOut(piePiece, seriesModel, idx);
        }).execute();
        pieLabelLayout(seriesModel); // Always use initial animation.

        if (seriesModel.get('animationTypeUpdate') !== 'expansion') {
          this._data = data;
        }
      };

      PieView.prototype.dispose = function () {};

      PieView.prototype.containPoint = function (point, seriesModel) {
        var data = seriesModel.getData();
        var itemLayout = data.getItemLayout(0);

        if (itemLayout) {
          var dx = point[0] - itemLayout.cx;
          var dy = point[1] - itemLayout.cy;
          var radius = Math.sqrt(dx * dx + dy * dy);
          return radius <= itemLayout.r && radius >= itemLayout.r0;
        }
      };

      PieView.type = 'pie';
      return PieView;
    }(ChartView);

    /**
     * [Usage]:
     * (1)
     * createListSimply(seriesModel, ['value']);
     * (2)
     * createListSimply(seriesModel, {
     *     coordDimensions: ['value'],
     *     dimensionsCount: 5
     * });
     */

    function createSeriesDataSimply(seriesModel, opt, nameList) {
      opt = isArray(opt) && {
        coordDimensions: opt
      } || extend({
        encodeDefine: seriesModel.getEncode()
      }, opt);
      var source = seriesModel.getSource();
      var dimensions = prepareSeriesDataSchema(source, opt).dimensions;
      var list = new SeriesData(dimensions, seriesModel);
      list.initData(source, nameList);
      return list;
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */

    /**
     * LegendVisualProvider is an bridge that pick encoded color from data and
     * provide to the legend component.
     */
    var LegendVisualProvider =
    /** @class */
    function () {
      function LegendVisualProvider( // Function to get data after filtered. It stores all the encoding info
      getDataWithEncodedVisual, // Function to get raw data before filtered.
      getRawData) {
        this._getDataWithEncodedVisual = getDataWithEncodedVisual;
        this._getRawData = getRawData;
      }

      LegendVisualProvider.prototype.getAllNames = function () {
        var rawData = this._getRawData(); // We find the name from the raw data. In case it's filtered by the legend component.
        // Normally, the name can be found in rawData, but can't be found in filtered data will display as gray.


        return rawData.mapArray(rawData.getName);
      };

      LegendVisualProvider.prototype.containName = function (name) {
        var rawData = this._getRawData();

        return rawData.indexOfName(name) >= 0;
      };

      LegendVisualProvider.prototype.indexOfName = function (name) {
        // Only get data when necessary.
        // Because LegendVisualProvider constructor may be new in the stage that data is not prepared yet.
        // Invoking Series#getData immediately will throw an error.
        var dataWithEncodedVisual = this._getDataWithEncodedVisual();

        return dataWithEncodedVisual.indexOfName(name);
      };

      LegendVisualProvider.prototype.getItemVisual = function (dataIndex, key) {
        // Get encoded visual properties from final filtered data.
        var dataWithEncodedVisual = this._getDataWithEncodedVisual();

        return dataWithEncodedVisual.getItemVisual(dataIndex, key);
      };

      return LegendVisualProvider;
    }();

    var innerData = makeInner();

    var PieSeriesModel =
    /** @class */
    function (_super) {
      __extends(PieSeriesModel, _super);

      function PieSeriesModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.init = function (option) {
        _super.prototype.init.apply(this, arguments); // Enable legend selection for each data item
        // Use a function instead of direct access because data reference may changed


        this.legendVisualProvider = new LegendVisualProvider(bind(this.getData, this), bind(this.getRawData, this));

        this._defaultLabelLine(option);
      };
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.mergeOption = function () {
        _super.prototype.mergeOption.apply(this, arguments);
      };
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.getInitialData = function () {
        return createSeriesDataSimply(this, {
          coordDimensions: ['value'],
          encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
        });
      };
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.getDataParams = function (dataIndex) {
        var data = this.getData(); // update seats when data is changed

        var dataInner = innerData(data);
        var seats = dataInner.seats;

        if (!seats) {
          var valueList_1 = [];
          data.each(data.mapDimension('value'), function (value) {
            valueList_1.push(value);
          });
          seats = dataInner.seats = getPercentSeats(valueList_1, data.hostModel.get('percentPrecision'));
        }

        var params = _super.prototype.getDataParams.call(this, dataIndex); // seats may be empty when sum is 0


        params.percent = seats[dataIndex] || 0;
        params.$vars.push('percent');
        return params;
      };

      PieSeriesModel.prototype._defaultLabelLine = function (option) {
        // Extend labelLine emphasis
        defaultEmphasis(option, 'labelLine', ['show']);
        var labelLineNormalOpt = option.labelLine;
        var labelLineEmphasisOpt = option.emphasis.labelLine; // Not show label line if `label.normal.show = false`

        labelLineNormalOpt.show = labelLineNormalOpt.show && option.label.show;
        labelLineEmphasisOpt.show = labelLineEmphasisOpt.show && option.emphasis.label.show;
      };

      PieSeriesModel.type = 'series.pie';
      PieSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        legendHoverLink: true,
        colorBy: 'data',
        // 默认全局居中
        center: ['50%', '50%'],
        radius: [0, '75%'],
        // 默认顺时针
        clockwise: true,
        startAngle: 90,
        // 最小角度改为0
        minAngle: 0,
        // If the angle of a sector less than `minShowLabelAngle`,
        // the label will not be displayed.
        minShowLabelAngle: 0,
        // 选中时扇区偏移量
        selectedOffset: 10,
        // 选择模式，默认关闭，可选single，multiple
        // selectedMode: false,
        // 南丁格尔玫瑰图模式，'radius'（半径） | 'area'（面积）
        // roseType: null,
        percentPrecision: 2,
        // If still show when all data zero.
        stillShowZeroSum: true,
        // cursor: null,
        left: 0,
        top: 0,
        right: 0,
        bottom: 0,
        width: null,
        height: null,
        label: {
          // color: 'inherit',
          // If rotate around circle
          rotate: 0,
          show: true,
          overflow: 'truncate',
          // 'outer', 'inside', 'center'
          position: 'outer',
          // 'none', 'labelLine', 'edge'. Works only when position is 'outer'
          alignTo: 'none',
          // Closest distance between label and chart edge.
          // Works only position is 'outer' and alignTo is 'edge'.
          edgeDistance: '25%',
          // Works only position is 'outer' and alignTo is not 'edge'.
          bleedMargin: 10,
          // Distance between text and label line.
          distanceToLabelLine: 5 // formatter: 标签文本格式器，同 tooltip.formatter，不支持异步回调
          // 默认使用全局文本样式，详见 textStyle
          // distance: 当position为inner时有效，为label位置到圆心的距离与圆半径(环状图为内外半径和)的比例系数

        },
        // Enabled when label.normal.position is 'outer'
        labelLine: {
          show: true,
          // 引导线两段中的第一段长度
          length: 15,
          // 引导线两段中的第二段长度
          length2: 15,
          smooth: false,
          minTurnAngle: 90,
          maxSurfaceAngle: 90,
          lineStyle: {
            // color: 各异,
            width: 1,
            type: 'solid'
          }
        },
        itemStyle: {
          borderWidth: 1,
          borderJoin: 'round'
        },
        showEmptyCircle: true,
        emptyCircleStyle: {
          color: 'lightgray',
          opacity: 1
        },
        labelLayout: {
          // Hide the overlapped label.
          hideOverlap: true
        },
        emphasis: {
          scale: true,
          scaleSize: 5
        },
        // If use strategy to avoid label overlapping
        avoidLabelOverlap: true,
        // Animation type. Valid values: expansion, scale
        animationType: 'expansion',
        animationDuration: 1000,
        // Animation type when update. Valid values: transition, expansion
        animationTypeUpdate: 'transition',
        animationEasingUpdate: 'cubicInOut',
        animationDurationUpdate: 500,
        animationEasing: 'cubicInOut'
      };
      return PieSeriesModel;
    }(SeriesModel);

    function negativeDataFilter(seriesType) {
      return {
        seriesType: seriesType,
        reset: function (seriesModel, ecModel) {
          var data = seriesModel.getData();
          data.filterSelf(function (idx) {
            // handle negative value condition
            var valueDim = data.mapDimension('value');
            var curValue = data.get(valueDim, idx);

            if (isNumber(curValue) && !isNaN(curValue) && curValue < 0) {
              return false;
            }

            return true;
          });
        }
      };
    }

    function install$4(registers) {
      registers.registerChartView(PieView);
      registers.registerSeriesModel(PieSeriesModel);
      createLegacyDataSelectAction('pie', registers.registerAction);
      registers.registerLayout(curry(pieLayout, 'pie'));
      registers.registerProcessor(dataFilter('pie'));
      registers.registerProcessor(negativeDataFilter('pie'));
    }

    var ScatterSeriesModel =
    /** @class */
    function (_super) {
      __extends(ScatterSeriesModel, _super);

      function ScatterSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ScatterSeriesModel.type;
        _this.hasSymbolVisual = true;
        return _this;
      }

      ScatterSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createSeriesData(null, this, {
          useEncodeDefaulter: true
        });
      };

      ScatterSeriesModel.prototype.getProgressive = function () {
        var progressive = this.option.progressive;

        if (progressive == null) {
          // PENDING
          return this.option.large ? 5e3 : this.get('progressive');
        }

        return progressive;
      };

      ScatterSeriesModel.prototype.getProgressiveThreshold = function () {
        var progressiveThreshold = this.option.progressiveThreshold;

        if (progressiveThreshold == null) {
          // PENDING
          return this.option.large ? 1e4 : this.get('progressiveThreshold');
        }

        return progressiveThreshold;
      };

      ScatterSeriesModel.prototype.brushSelector = function (dataIndex, data, selectors) {
        return selectors.point(data.getItemLayout(dataIndex));
      };

      ScatterSeriesModel.prototype.getZLevelKey = function () {
        // Each progressive series has individual key.
        return this.getData().count() > this.getProgressiveThreshold() ? this.id : '';
      };

      ScatterSeriesModel.type = 'series.scatter';
      ScatterSeriesModel.dependencies = ['grid', 'polar', 'geo', 'singleAxis', 'calendar'];
      ScatterSeriesModel.defaultOption = {
        coordinateSystem: 'cartesian2d',
        // zlevel: 0,
        z: 2,
        legendHoverLink: true,
        symbolSize: 10,
        // symbolRotate: null,  // 图形旋转控制
        large: false,
        // Available when large is true
        largeThreshold: 2000,
        // cursor: null,
        itemStyle: {
          opacity: 0.8 // color: 各异

        },
        emphasis: {
          scale: true
        },
        // If clip the overflow graphics
        // Works on cartesian / polar series
        clip: true,
        select: {
          itemStyle: {
            borderColor: '#212121'
          }
        },
        universalTransition: {
          divideShape: 'clone'
        } // progressive: null

      };
      return ScatterSeriesModel;
    }(SeriesModel);

    var BOOST_SIZE_THRESHOLD = 4;

    var LargeSymbolPathShape =
    /** @class */
    function () {
      function LargeSymbolPathShape() {}

      return LargeSymbolPathShape;
    }();

    var LargeSymbolPath =
    /** @class */
    function (_super) {
      __extends(LargeSymbolPath, _super);

      function LargeSymbolPath(opts) {
        var _this = _super.call(this, opts) || this;

        _this._off = 0;
        _this.hoverDataIdx = -1;
        return _this;
      }

      LargeSymbolPath.prototype.getDefaultShape = function () {
        return new LargeSymbolPathShape();
      };

      LargeSymbolPath.prototype.reset = function () {
        this.notClear = false;
        this._off = 0;
      };

      LargeSymbolPath.prototype.buildPath = function (path, shape) {
        var points = shape.points;
        var size = shape.size;
        var symbolProxy = this.symbolProxy;
        var symbolProxyShape = symbolProxy.shape;
        var ctx = path.getContext ? path.getContext() : path;
        var canBoost = ctx && size[0] < BOOST_SIZE_THRESHOLD;
        var softClipShape = this.softClipShape;
        var i; // Do draw in afterBrush.

        if (canBoost) {
          this._ctx = ctx;
          return;
        }

        this._ctx = null;

        for (i = this._off; i < points.length;) {
          var x = points[i++];
          var y = points[i++];

          if (isNaN(x) || isNaN(y)) {
            continue;
          }

          if (softClipShape && !softClipShape.contain(x, y)) {
            continue;
          }

          symbolProxyShape.x = x - size[0] / 2;
          symbolProxyShape.y = y - size[1] / 2;
          symbolProxyShape.width = size[0];
          symbolProxyShape.height = size[1];
          symbolProxy.buildPath(path, symbolProxyShape, true);
        }

        if (this.incremental) {
          this._off = i;
          this.notClear = true;
        }
      };

      LargeSymbolPath.prototype.afterBrush = function () {
        var shape = this.shape;
        var points = shape.points;
        var size = shape.size;
        var ctx = this._ctx;
        var softClipShape = this.softClipShape;
        var i;

        if (!ctx) {
          return;
        } // PENDING If style or other canvas status changed?


        for (i = this._off; i < points.length;) {
          var x = points[i++];
          var y = points[i++];

          if (isNaN(x) || isNaN(y)) {
            continue;
          }

          if (softClipShape && !softClipShape.contain(x, y)) {
            continue;
          } // fillRect is faster than building a rect path and draw.
          // And it support light globalCompositeOperation.


          ctx.fillRect(x - size[0] / 2, y - size[1] / 2, size[0], size[1]);
        }

        if (this.incremental) {
          this._off = i;
          this.notClear = true;
        }
      };

      LargeSymbolPath.prototype.findDataIndex = function (x, y) {
        // TODO ???
        // Consider transform
        var shape = this.shape;
        var points = shape.points;
        var size = shape.size;
        var w = Math.max(size[0], 4);
        var h = Math.max(size[1], 4); // Not consider transform
        // Treat each element as a rect
        // top down traverse

        for (var idx = points.length / 2 - 1; idx >= 0; idx--) {
          var i = idx * 2;
          var x0 = points[i] - w / 2;
          var y0 = points[i + 1] - h / 2;

          if (x >= x0 && y >= y0 && x <= x0 + w && y <= y0 + h) {
            return idx;
          }
        }

        return -1;
      };

      LargeSymbolPath.prototype.contain = function (x, y) {
        var localPos = this.transformCoordToLocal(x, y);
        var rect = this.getBoundingRect();
        x = localPos[0];
        y = localPos[1];

        if (rect.contain(x, y)) {
          // Cache found data index.
          var dataIdx = this.hoverDataIdx = this.findDataIndex(x, y);
          return dataIdx >= 0;
        }

        this.hoverDataIdx = -1;
        return false;
      };

      LargeSymbolPath.prototype.getBoundingRect = function () {
        // Ignore stroke for large symbol draw.
        var rect = this._rect;

        if (!rect) {
          var shape = this.shape;
          var points = shape.points;
          var size = shape.size;
          var w = size[0];
          var h = size[1];
          var minX = Infinity;
          var minY = Infinity;
          var maxX = -Infinity;
          var maxY = -Infinity;

          for (var i = 0; i < points.length;) {
            var x = points[i++];
            var y = points[i++];
            minX = Math.min(x, minX);
            maxX = Math.max(x, maxX);
            minY = Math.min(y, minY);
            maxY = Math.max(y, maxY);
          }

          rect = this._rect = new BoundingRect(minX - w / 2, minY - h / 2, maxX - minX + w, maxY - minY + h);
        }

        return rect;
      };

      return LargeSymbolPath;
    }(Path);

    var LargeSymbolDraw =
    /** @class */
    function () {
      function LargeSymbolDraw() {
        this.group = new Group();
      }
      /**
       * Update symbols draw by new data
       */


      LargeSymbolDraw.prototype.updateData = function (data, opt) {
        this._clear();

        var symbolEl = this._create();

        symbolEl.setShape({
          points: data.getLayout('points')
        });

        this._setCommon(symbolEl, data, opt);
      };

      LargeSymbolDraw.prototype.updateLayout = function (data) {
        var points = data.getLayout('points');
        this.group.eachChild(function (child) {
          if (child.startIndex != null) {
            var len = (child.endIndex - child.startIndex) * 2;
            var byteOffset = child.startIndex * 4 * 2;
            points = new Float32Array(points.buffer, byteOffset, len);
          }

          child.setShape('points', points); // Reset draw cursor.

          child.reset();
        });
      };

      LargeSymbolDraw.prototype.incrementalPrepareUpdate = function (data) {
        this._clear();
      };

      LargeSymbolDraw.prototype.incrementalUpdate = function (taskParams, data, opt) {
        var lastAdded = this._newAdded[0];
        var points = data.getLayout('points');
        var oldPoints = lastAdded && lastAdded.shape.points; // Merging the exists. Each element has 1e4 points.
        // Consider the performance balance between too much elements and too much points in one shape(may affect hover optimization)

        if (oldPoints && oldPoints.length < 2e4) {
          var oldLen = oldPoints.length;
          var newPoints = new Float32Array(oldLen + points.length); // Concat two array

          newPoints.set(oldPoints);
          newPoints.set(points, oldLen); // Update endIndex

          lastAdded.endIndex = taskParams.end;
          lastAdded.setShape({
            points: newPoints
          });
        } else {
          // Clear
          this._newAdded = [];

          var symbolEl = this._create();

          symbolEl.startIndex = taskParams.start;
          symbolEl.endIndex = taskParams.end;
          symbolEl.incremental = true;
          symbolEl.setShape({
            points: points
          });

          this._setCommon(symbolEl, data, opt);
        }
      };

      LargeSymbolDraw.prototype.eachRendered = function (cb) {
        this._newAdded[0] && cb(this._newAdded[0]);
      };

      LargeSymbolDraw.prototype._create = function () {
        var symbolEl = new LargeSymbolPath({
          cursor: 'default'
        });
        symbolEl.ignoreCoarsePointer = true;
        this.group.add(symbolEl);

        this._newAdded.push(symbolEl);

        return symbolEl;
      };

      LargeSymbolDraw.prototype._setCommon = function (symbolEl, data, opt) {
        var hostModel = data.hostModel;
        opt = opt || {};
        var size = data.getVisual('symbolSize');
        symbolEl.setShape('size', size instanceof Array ? size : [size, size]);
        symbolEl.softClipShape = opt.clipShape || null; // Create symbolProxy to build path for each data

        symbolEl.symbolProxy = createSymbol(data.getVisual('symbol'), 0, 0, 0, 0); // Use symbolProxy setColor method

        symbolEl.setColor = symbolEl.symbolProxy.setColor;
        var extrudeShadow = symbolEl.shape.size[0] < BOOST_SIZE_THRESHOLD;
        symbolEl.useStyle( // Draw shadow when doing fillRect is extremely slow.
        hostModel.getModel('itemStyle').getItemStyle(extrudeShadow ? ['color', 'shadowBlur', 'shadowColor'] : ['color']));
        var globalStyle = data.getVisual('style');
        var visualColor = globalStyle && globalStyle.fill;

        if (visualColor) {
          symbolEl.setColor(visualColor);
        }

        var ecData = getECData(symbolEl); // Enable tooltip
        // PENDING May have performance issue when path is extremely large

        ecData.seriesIndex = hostModel.seriesIndex;
        symbolEl.on('mousemove', function (e) {
          ecData.dataIndex = null;
          var dataIndex = symbolEl.hoverDataIdx;

          if (dataIndex >= 0) {
            // Provide dataIndex for tooltip
            ecData.dataIndex = dataIndex + (symbolEl.startIndex || 0);
          }
        });
      };

      LargeSymbolDraw.prototype.remove = function () {
        this._clear();
      };

      LargeSymbolDraw.prototype._clear = function () {
        this._newAdded = [];
        this.group.removeAll();
      };

      return LargeSymbolDraw;
    }();

    var ScatterView =
    /** @class */
    function (_super) {
      __extends(ScatterView, _super);

      function ScatterView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ScatterView.type;
        return _this;
      }

      ScatterView.prototype.render = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();

        var symbolDraw = this._updateSymbolDraw(data, seriesModel);

        symbolDraw.updateData(data, {
          // TODO
          // If this parameter should be a shape or a bounding volume
          // shape will be more general.
          // But bounding volume like bounding rect will be much faster in the contain calculation
          clipShape: this._getClipShape(seriesModel)
        });
        this._finished = true;
      };

      ScatterView.prototype.incrementalPrepareRender = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();

        var symbolDraw = this._updateSymbolDraw(data, seriesModel);

        symbolDraw.incrementalPrepareUpdate(data);
        this._finished = false;
      };

      ScatterView.prototype.incrementalRender = function (taskParams, seriesModel, ecModel) {
        this._symbolDraw.incrementalUpdate(taskParams, seriesModel.getData(), {
          clipShape: this._getClipShape(seriesModel)
        });

        this._finished = taskParams.end === seriesModel.getData().count();
      };

      ScatterView.prototype.updateTransform = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData(); // Must mark group dirty and make sure the incremental layer will be cleared
        // PENDING

        this.group.dirty();

        if (!this._finished || data.count() > 1e4) {
          return {
            update: true
          };
        } else {
          var res = pointsLayout('').reset(seriesModel, ecModel, api);

          if (res.progress) {
            res.progress({
              start: 0,
              end: data.count(),
              count: data.count()
            }, data);
          }

          this._symbolDraw.updateLayout(data);
        }
      };

      ScatterView.prototype.eachRendered = function (cb) {
        this._symbolDraw && this._symbolDraw.eachRendered(cb);
      };

      ScatterView.prototype._getClipShape = function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;
        var clipArea = coordSys && coordSys.getArea && coordSys.getArea();
        return seriesModel.get('clip', true) ? clipArea : null;
      };

      ScatterView.prototype._updateSymbolDraw = function (data, seriesModel) {
        var symbolDraw = this._symbolDraw;
        var pipelineContext = seriesModel.pipelineContext;
        var isLargeDraw = pipelineContext.large;

        if (!symbolDraw || isLargeDraw !== this._isLargeDraw) {
          symbolDraw && symbolDraw.remove();
          symbolDraw = this._symbolDraw = isLargeDraw ? new LargeSymbolDraw() : new SymbolDraw();
          this._isLargeDraw = isLargeDraw;
          this.group.removeAll();
        }

        this.group.add(symbolDraw.group);
        return symbolDraw;
      };

      ScatterView.prototype.remove = function (ecModel, api) {
        this._symbolDraw && this._symbolDraw.remove(true);
        this._symbolDraw = null;
      };

      ScatterView.prototype.dispose = function () {};

      ScatterView.type = 'scatter';
      return ScatterView;
    }(ChartView);

    var GridModel =
    /** @class */
    function (_super) {
      __extends(GridModel, _super);

      function GridModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      GridModel.type = 'grid';
      GridModel.dependencies = ['xAxis', 'yAxis'];
      GridModel.layoutMode = 'box';
      GridModel.defaultOption = {
        show: false,
        // zlevel: 0,
        z: 0,
        left: '10%',
        top: 60,
        right: '10%',
        bottom: 70,
        // If grid size contain label
        containLabel: false,
        // width: {totalWidth} - left - right,
        // height: {totalHeight} - top - bottom,
        backgroundColor: 'rgba(0,0,0,0)',
        borderWidth: 1,
        borderColor: '#ccc'
      };
      return GridModel;
    }(ComponentModel);

    var CartesianAxisModel =
    /** @class */
    function (_super) {
      __extends(CartesianAxisModel, _super);

      function CartesianAxisModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      CartesianAxisModel.prototype.getCoordSysModel = function () {
        return this.getReferringComponents('grid', SINGLE_REFERRING).models[0];
      };

      CartesianAxisModel.type = 'cartesian2dAxis';
      return CartesianAxisModel;
    }(ComponentModel);
    mixin(CartesianAxisModel, AxisModelCommonMixin);

    var defaultOption = {
      show: true,
      // zlevel: 0,
      z: 0,
      // Inverse the axis.
      inverse: false,
      // Axis name displayed.
      name: '',
      // 'start' | 'middle' | 'end'
      nameLocation: 'end',
      // By degree. By default auto rotate by nameLocation.
      nameRotate: null,
      nameTruncate: {
        maxWidth: null,
        ellipsis: '...',
        placeholder: '.'
      },
      // Use global text style by default.
      nameTextStyle: {},
      // The gap between axisName and axisLine.
      nameGap: 15,
      // Default `false` to support tooltip.
      silent: false,
      // Default `false` to avoid legacy user event listener fail.
      triggerEvent: false,
      tooltip: {
        show: false
      },
      axisPointer: {},
      axisLine: {
        show: true,
        onZero: true,
        onZeroAxisIndex: null,
        lineStyle: {
          color: '#6E7079',
          width: 1,
          type: 'solid'
        },
        // The arrow at both ends the the axis.
        symbol: ['none', 'none'],
        symbolSize: [10, 15]
      },
      axisTick: {
        show: true,
        // Whether axisTick is inside the grid or outside the grid.
        inside: false,
        // The length of axisTick.
        length: 5,
        lineStyle: {
          width: 1
        }
      },
      axisLabel: {
        show: true,
        // Whether axisLabel is inside the grid or outside the grid.
        inside: false,
        rotate: 0,
        // true | false | null/undefined (auto)
        showMinLabel: null,
        // true | false | null/undefined (auto)
        showMaxLabel: null,
        margin: 8,
        // formatter: null,
        fontSize: 12
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: ['#E0E6F1'],
          width: 1,
          type: 'solid'
        }
      },
      splitArea: {
        show: false,
        areaStyle: {
          color: ['rgba(250,250,250,0.2)', 'rgba(210,219,238,0.2)']
        }
      }
    };
    var categoryAxis = merge({
      // The gap at both ends of the axis. For categoryAxis, boolean.
      boundaryGap: true,
      // Set false to faster category collection.
      deduplication: null,
      // splitArea: {
      // show: false
      // },
      splitLine: {
        show: false
      },
      axisTick: {
        // If tick is align with label when boundaryGap is true
        alignWithLabel: false,
        interval: 'auto'
      },
      axisLabel: {
        interval: 'auto'
      }
    }, defaultOption);
    var valueAxis = merge({
      boundaryGap: [0, 0],
      axisLine: {
        // Not shown when other axis is categoryAxis in cartesian
        show: 'auto'
      },
      axisTick: {
        // Not shown when other axis is categoryAxis in cartesian
        show: 'auto'
      },
      // TODO
      // min/max: [30, datamin, 60] or [20, datamin] or [datamin, 60]
      splitNumber: 5,
      minorTick: {
        // Minor tick, not available for cateogry axis.
        show: false,
        // Split number of minor ticks. The value should be in range of (0, 100)
        splitNumber: 5,
        // Length of minor tick
        length: 3,
        // Line style
        lineStyle: {// Default to be same with axisTick
        }
      },
      minorSplitLine: {
        show: false,
        lineStyle: {
          color: '#F4F7FD',
          width: 1
        }
      }
    }, defaultOption);
    var timeAxis = merge({
      splitNumber: 6,
      axisLabel: {
        // To eliminate labels that are not nice
        showMinLabel: false,
        showMaxLabel: false,
        rich: {
          primary: {
            fontWeight: 'bold'
          }
        }
      },
      splitLine: {
        show: false
      }
    }, valueAxis);
    var logAxis = defaults({
      logBase: 10
    }, valueAxis);
    var axisDefault = {
      category: categoryAxis,
      value: valueAxis,
      time: timeAxis,
      log: logAxis
    };

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var AXIS_TYPES = {
      value: 1,
      category: 1,
      time: 1,
      log: 1
    };

    /**
     * Generate sub axis model class
     * @param axisName 'x' 'y' 'radius' 'angle' 'parallel' ...
     */

    function axisModelCreator(registers, axisName, BaseAxisModelClass, extraDefaultOption) {
      each(AXIS_TYPES, function (v, axisType) {
        var defaultOption = merge(merge({}, axisDefault[axisType], true), extraDefaultOption, true);

        var AxisModel =
        /** @class */
        function (_super) {
          __extends(AxisModel, _super);

          function AxisModel() {
            var _this = _super !== null && _super.apply(this, arguments) || this;

            _this.type = axisName + 'Axis.' + axisType;
            return _this;
          }

          AxisModel.prototype.mergeDefaultAndTheme = function (option, ecModel) {
            var layoutMode = fetchLayoutMode(this);
            var inputPositionParams = layoutMode ? getLayoutParams(option) : {};
            var themeModel = ecModel.getTheme();
            merge(option, themeModel.get(axisType + 'Axis'));
            merge(option, this.getDefaultOption());
            option.type = getAxisType(option);

            if (layoutMode) {
              mergeLayoutParam(option, inputPositionParams, layoutMode);
            }
          };

          AxisModel.prototype.optionUpdated = function () {
            var thisOption = this.option;

            if (thisOption.type === 'category') {
              this.__ordinalMeta = OrdinalMeta.createByAxisModel(this);
            }
          };
          /**
           * Should not be called before all of 'getInitailData' finished.
           * Because categories are collected during initializing data.
           */


          AxisModel.prototype.getCategories = function (rawData) {
            var option = this.option; // FIXME
            // warning if called before all of 'getInitailData' finished.

            if (option.type === 'category') {
              if (rawData) {
                return option.data;
              }

              return this.__ordinalMeta.categories;
            }
          };

          AxisModel.prototype.getOrdinalMeta = function () {
            return this.__ordinalMeta;
          };

          AxisModel.type = axisName + 'Axis.' + axisType;
          AxisModel.defaultOption = defaultOption;
          return AxisModel;
        }(BaseAxisModelClass);

        registers.registerComponentModel(AxisModel);
      });
      registers.registerSubTypeDefaulter(axisName + 'Axis', getAxisType);
    }

    function getAxisType(option) {
      // Default axis with data is category axis
      return option.type || (option.data ? 'category' : 'value');
    }

    var Cartesian =
    /** @class */
    function () {
      function Cartesian(name) {
        this.type = 'cartesian';
        this._dimList = [];
        this._axes = {};
        this.name = name || '';
      }

      Cartesian.prototype.getAxis = function (dim) {
        return this._axes[dim];
      };

      Cartesian.prototype.getAxes = function () {
        return map(this._dimList, function (dim) {
          return this._axes[dim];
        }, this);
      };

      Cartesian.prototype.getAxesByScale = function (scaleType) {
        scaleType = scaleType.toLowerCase();
        return filter(this.getAxes(), function (axis) {
          return axis.scale.type === scaleType;
        });
      };

      Cartesian.prototype.addAxis = function (axis) {
        var dim = axis.dim;
        this._axes[dim] = axis;

        this._dimList.push(dim);
      };

      return Cartesian;
    }();

    var cartesian2DDimensions = ['x', 'y'];

    function canCalculateAffineTransform(scale) {
      return scale.type === 'interval' || scale.type === 'time';
    }

    var Cartesian2D =
    /** @class */
    function (_super) {
      __extends(Cartesian2D, _super);

      function Cartesian2D() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'cartesian2d';
        _this.dimensions = cartesian2DDimensions;
        return _this;
      }
      /**
       * Calculate an affine transform matrix if two axes are time or value.
       * It's mainly for accelartion on the large time series data.
       */


      Cartesian2D.prototype.calcAffineTransform = function () {
        this._transform = this._invTransform = null;
        var xAxisScale = this.getAxis('x').scale;
        var yAxisScale = this.getAxis('y').scale;

        if (!canCalculateAffineTransform(xAxisScale) || !canCalculateAffineTransform(yAxisScale)) {
          return;
        }

        var xScaleExtent = xAxisScale.getExtent();
        var yScaleExtent = yAxisScale.getExtent();
        var start = this.dataToPoint([xScaleExtent[0], yScaleExtent[0]]);
        var end = this.dataToPoint([xScaleExtent[1], yScaleExtent[1]]);
        var xScaleSpan = xScaleExtent[1] - xScaleExtent[0];
        var yScaleSpan = yScaleExtent[1] - yScaleExtent[0];

        if (!xScaleSpan || !yScaleSpan) {
          return;
        } // Accelerate data to point calculation on the special large time series data.


        var scaleX = (end[0] - start[0]) / xScaleSpan;
        var scaleY = (end[1] - start[1]) / yScaleSpan;
        var translateX = start[0] - xScaleExtent[0] * scaleX;
        var translateY = start[1] - yScaleExtent[0] * scaleY;
        var m = this._transform = [scaleX, 0, 0, scaleY, translateX, translateY];
        this._invTransform = invert([], m);
      };
      /**
       * Base axis will be used on stacking.
       */


      Cartesian2D.prototype.getBaseAxis = function () {
        return this.getAxesByScale('ordinal')[0] || this.getAxesByScale('time')[0] || this.getAxis('x');
      };

      Cartesian2D.prototype.containPoint = function (point) {
        var axisX = this.getAxis('x');
        var axisY = this.getAxis('y');
        return axisX.contain(axisX.toLocalCoord(point[0])) && axisY.contain(axisY.toLocalCoord(point[1]));
      };

      Cartesian2D.prototype.containData = function (data) {
        return this.getAxis('x').containData(data[0]) && this.getAxis('y').containData(data[1]);
      };

      Cartesian2D.prototype.containZone = function (data1, data2) {
        var zoneDiag1 = this.dataToPoint(data1);
        var zoneDiag2 = this.dataToPoint(data2);
        var area = this.getArea();
        var zone = new BoundingRect(zoneDiag1[0], zoneDiag1[1], zoneDiag2[0] - zoneDiag1[0], zoneDiag2[1] - zoneDiag1[1]);
        return area.intersect(zone);
      };

      Cartesian2D.prototype.dataToPoint = function (data, clamp, out) {
        out = out || [];
        var xVal = data[0];
        var yVal = data[1]; // Fast path

        if (this._transform // It's supported that if data is like `[Inifity, 123]`, where only Y pixel calculated.
        && xVal != null && isFinite(xVal) && yVal != null && isFinite(yVal)) {
          return applyTransform(out, data, this._transform);
        }

        var xAxis = this.getAxis('x');
        var yAxis = this.getAxis('y');
        out[0] = xAxis.toGlobalCoord(xAxis.dataToCoord(xVal, clamp));
        out[1] = yAxis.toGlobalCoord(yAxis.dataToCoord(yVal, clamp));
        return out;
      };

      Cartesian2D.prototype.clampData = function (data, out) {
        var xScale = this.getAxis('x').scale;
        var yScale = this.getAxis('y').scale;
        var xAxisExtent = xScale.getExtent();
        var yAxisExtent = yScale.getExtent();
        var x = xScale.parse(data[0]);
        var y = yScale.parse(data[1]);
        out = out || [];
        out[0] = Math.min(Math.max(Math.min(xAxisExtent[0], xAxisExtent[1]), x), Math.max(xAxisExtent[0], xAxisExtent[1]));
        out[1] = Math.min(Math.max(Math.min(yAxisExtent[0], yAxisExtent[1]), y), Math.max(yAxisExtent[0], yAxisExtent[1]));
        return out;
      };

      Cartesian2D.prototype.pointToData = function (point, clamp) {
        var out = [];

        if (this._invTransform) {
          return applyTransform(out, point, this._invTransform);
        }

        var xAxis = this.getAxis('x');
        var yAxis = this.getAxis('y');
        out[0] = xAxis.coordToData(xAxis.toLocalCoord(point[0]), clamp);
        out[1] = yAxis.coordToData(yAxis.toLocalCoord(point[1]), clamp);
        return out;
      };

      Cartesian2D.prototype.getOtherAxis = function (axis) {
        return this.getAxis(axis.dim === 'x' ? 'y' : 'x');
      };
      /**
       * Get rect area of cartesian.
       * Area will have a contain function to determine if a point is in the coordinate system.
       */


      Cartesian2D.prototype.getArea = function () {
        var xExtent = this.getAxis('x').getGlobalExtent();
        var yExtent = this.getAxis('y').getGlobalExtent();
        var x = Math.min(xExtent[0], xExtent[1]);
        var y = Math.min(yExtent[0], yExtent[1]);
        var width = Math.max(xExtent[0], xExtent[1]) - x;
        var height = Math.max(yExtent[0], yExtent[1]) - y;
        return new BoundingRect(x, y, width, height);
      };

      return Cartesian2D;
    }(Cartesian);

    var Axis2D =
    /** @class */
    function (_super) {
      __extends(Axis2D, _super);

      function Axis2D(dim, scale, coordExtent, axisType, position) {
        var _this = _super.call(this, dim, scale, coordExtent) || this;
        /**
         * Index of axis, can be used as key
         * Injected outside.
         */


        _this.index = 0;
        _this.type = axisType || 'value';
        _this.position = position || 'bottom';
        return _this;
      }

      Axis2D.prototype.isHorizontal = function () {
        var position = this.position;
        return position === 'top' || position === 'bottom';
      };
      /**
       * Each item cooresponds to this.getExtent(), which
       * means globalExtent[0] may greater than globalExtent[1],
       * unless `asc` is input.
       *
       * @param {boolean} [asc]
       * @return {Array.<number>}
       */


      Axis2D.prototype.getGlobalExtent = function (asc) {
        var ret = this.getExtent();
        ret[0] = this.toGlobalCoord(ret[0]);
        ret[1] = this.toGlobalCoord(ret[1]);
        asc && ret[0] > ret[1] && ret.reverse();
        return ret;
      };

      Axis2D.prototype.pointToData = function (point, clamp) {
        return this.coordToData(this.toLocalCoord(point[this.dim === 'x' ? 0 : 1]), clamp);
      };
      /**
       * Set ordinalSortInfo
       * @param info new OrdinalSortInfo
       */


      Axis2D.prototype.setCategorySortInfo = function (info) {
        if (this.type !== 'category') {
          return false;
        }

        this.model.option.categorySortInfo = info;
        this.scale.setSortInfo(info);
      };

      return Axis2D;
    }(Axis);

    /**
     * Can only be called after coordinate system creation stage.
     * (Can be called before coordinate system update stage).
     */

    function layout$1(gridModel, axisModel, opt) {
      opt = opt || {};
      var grid = gridModel.coordinateSystem;
      var axis = axisModel.axis;
      var layout = {};
      var otherAxisOnZeroOf = axis.getAxesOnZeroOf()[0];
      var rawAxisPosition = axis.position;
      var axisPosition = otherAxisOnZeroOf ? 'onZero' : rawAxisPosition;
      var axisDim = axis.dim;
      var rect = grid.getRect();
      var rectBound = [rect.x, rect.x + rect.width, rect.y, rect.y + rect.height];
      var idx = {
        left: 0,
        right: 1,
        top: 0,
        bottom: 1,
        onZero: 2
      };
      var axisOffset = axisModel.get('offset') || 0;
      var posBound = axisDim === 'x' ? [rectBound[2] - axisOffset, rectBound[3] + axisOffset] : [rectBound[0] - axisOffset, rectBound[1] + axisOffset];

      if (otherAxisOnZeroOf) {
        var onZeroCoord = otherAxisOnZeroOf.toGlobalCoord(otherAxisOnZeroOf.dataToCoord(0));
        posBound[idx.onZero] = Math.max(Math.min(onZeroCoord, posBound[1]), posBound[0]);
      } // Axis position


      layout.position = [axisDim === 'y' ? posBound[idx[axisPosition]] : rectBound[0], axisDim === 'x' ? posBound[idx[axisPosition]] : rectBound[3]]; // Axis rotation

      layout.rotation = Math.PI / 2 * (axisDim === 'x' ? 0 : 1); // Tick and label direction, x y is axisDim

      var dirMap = {
        top: -1,
        bottom: 1,
        left: -1,
        right: 1
      };
      layout.labelDirection = layout.tickDirection = layout.nameDirection = dirMap[rawAxisPosition];
      layout.labelOffset = otherAxisOnZeroOf ? posBound[idx[rawAxisPosition]] - posBound[idx.onZero] : 0;

      if (axisModel.get(['axisTick', 'inside'])) {
        layout.tickDirection = -layout.tickDirection;
      }

      if (retrieve(opt.labelInside, axisModel.get(['axisLabel', 'inside']))) {
        layout.labelDirection = -layout.labelDirection;
      } // Special label rotation


      var labelRotate = axisModel.get(['axisLabel', 'rotate']);
      layout.labelRotate = axisPosition === 'top' ? -labelRotate : labelRotate; // Over splitLine and splitArea

      layout.z2 = 1;
      return layout;
    }
    function isCartesian2DSeries(seriesModel) {
      return seriesModel.get('coordinateSystem') === 'cartesian2d';
    }
    function findAxisModels(seriesModel) {
      var axisModelMap = {
        xAxisModel: null,
        yAxisModel: null
      };
      each(axisModelMap, function (v, key) {
        var axisType = key.replace(/Model$/, '');
        var axisModel = seriesModel.getReferringComponents(axisType, SINGLE_REFERRING).models[0];

        if ("development" !== 'production') {
          if (!axisModel) {
            throw new Error(axisType + ' "' + retrieve3(seriesModel.get(axisType + 'Index'), seriesModel.get(axisType + 'Id'), 0) + '" not found');
          }
        }

        axisModelMap[key] = axisModel;
      });
      return axisModelMap;
    }

    var mathLog$1 = Math.log;
    function alignScaleTicks(scale, axisModel, alignToScale) {
      var intervalScaleProto = IntervalScale.prototype; // NOTE: There is a precondition for log scale  here:
      // In log scale we store _interval and _extent of exponent value.
      // So if we use the method of InternalScale to set/get these data.
      // It process the exponent value, which is linear and what we want here.

      var alignToTicks = intervalScaleProto.getTicks.call(alignToScale);
      var alignToNicedTicks = intervalScaleProto.getTicks.call(alignToScale, true);
      var alignToSplitNumber = alignToTicks.length - 1;
      var alignToInterval = intervalScaleProto.getInterval.call(alignToScale);
      var scaleExtent = getScaleExtent(scale, axisModel);
      var rawExtent = scaleExtent.extent;
      var isMinFixed = scaleExtent.fixMin;
      var isMaxFixed = scaleExtent.fixMax;

      if (scale.type === 'log') {
        var logBase = mathLog$1(scale.base);
        rawExtent = [mathLog$1(rawExtent[0]) / logBase, mathLog$1(rawExtent[1]) / logBase];
      }

      scale.setExtent(rawExtent[0], rawExtent[1]);
      scale.calcNiceExtent({
        splitNumber: alignToSplitNumber,
        fixMin: isMinFixed,
        fixMax: isMaxFixed
      });
      var extent = intervalScaleProto.getExtent.call(scale); // Need to update the rawExtent.
      // Because value in rawExtent may be not parsed. e.g. 'dataMin', 'dataMax'

      if (isMinFixed) {
        rawExtent[0] = extent[0];
      }

      if (isMaxFixed) {
        rawExtent[1] = extent[1];
      }

      var interval = intervalScaleProto.getInterval.call(scale);
      var min = rawExtent[0];
      var max = rawExtent[1];

      if (isMinFixed && isMaxFixed) {
        // User set min, max, divide to get new interval
        interval = (max - min) / alignToSplitNumber;
      } else if (isMinFixed) {
        max = rawExtent[0] + interval * alignToSplitNumber; // User set min, expand extent on the other side

        while (max < rawExtent[1] && isFinite(max) && isFinite(rawExtent[1])) {
          interval = increaseInterval(interval);
          max = rawExtent[0] + interval * alignToSplitNumber;
        }
      } else if (isMaxFixed) {
        // User set max, expand extent on the other side
        min = rawExtent[1] - interval * alignToSplitNumber;

        while (min > rawExtent[0] && isFinite(min) && isFinite(rawExtent[0])) {
          interval = increaseInterval(interval);
          min = rawExtent[1] - interval * alignToSplitNumber;
        }
      } else {
        var nicedSplitNumber = scale.getTicks().length - 1;

        if (nicedSplitNumber > alignToSplitNumber) {
          interval = increaseInterval(interval);
        }

        var range = interval * alignToSplitNumber;
        max = Math.ceil(rawExtent[1] / interval) * interval;
        min = round(max - range); // Not change the result that crossing zero.

        if (min < 0 && rawExtent[0] >= 0) {
          min = 0;
          max = round(range);
        } else if (max > 0 && rawExtent[1] <= 0) {
          max = 0;
          min = -round(range);
        }
      } // Adjust min, max based on the extent of alignTo. When min or max is set in alignTo scale


      var t0 = (alignToTicks[0].value - alignToNicedTicks[0].value) / alignToInterval;
      var t1 = (alignToTicks[alignToSplitNumber].value - alignToNicedTicks[alignToSplitNumber].value) / alignToInterval; // NOTE: Must in setExtent -> setInterval -> setNiceExtent order.

      intervalScaleProto.setExtent.call(scale, min + interval * t0, max + interval * t1);
      intervalScaleProto.setInterval.call(scale, interval);

      if (t0 || t1) {
        intervalScaleProto.setNiceExtent.call(scale, min + interval, max - interval);
      }

      if ("development" !== 'production') {
        var ticks = intervalScaleProto.getTicks.call(scale);

        if (ticks[1] && (!isValueNice(interval) || getPrecisionSafe(ticks[1].value) > getPrecisionSafe(interval))) {
          warn( // eslint-disable-next-line
          "The ticks may be not readable when set min: " + axisModel.get('min') + ", max: " + axisModel.get('max') + " and alignTicks: true");
        }
      }
    }

    var Grid =
    /** @class */
    function () {
      function Grid(gridModel, ecModel, api) {
        // FIXME:TS where used (different from registered type 'cartesian2d')?
        this.type = 'grid';
        this._coordsMap = {};
        this._coordsList = [];
        this._axesMap = {};
        this._axesList = [];
        this.axisPointerEnabled = true;
        this.dimensions = cartesian2DDimensions;

        this._initCartesian(gridModel, ecModel, api);

        this.model = gridModel;
      }

      Grid.prototype.getRect = function () {
        return this._rect;
      };

      Grid.prototype.update = function (ecModel, api) {
        var axesMap = this._axesMap;

        this._updateScale(ecModel, this.model);

        function updateAxisTicks(axes) {
          var alignTo; // Axis is added in order of axisIndex.

          var axesIndices = keys(axes);
          var len = axesIndices.length;

          if (!len) {
            return;
          }

          var axisNeedsAlign = []; // Process once and calculate the ticks for those don't use alignTicks.

          for (var i = len - 1; i >= 0; i--) {
            var idx = +axesIndices[i]; // Convert to number.

            var axis = axes[idx];
            var model = axis.model;
            var scale = axis.scale;

            if ( // Only value and log axis without interval support alignTicks.
            isIntervalOrLogScale(scale) && model.get('alignTicks') && model.get('interval') == null) {
              axisNeedsAlign.push(axis);
            } else {
              niceScaleExtent(scale, model);

              if (isIntervalOrLogScale(scale)) {
                // Can only align to interval or log axis.
                alignTo = axis;
              }
            }
          }
          // PENDING. Should we find the axis that both set interval, min, max and align to this one?

          if (axisNeedsAlign.length) {
            if (!alignTo) {
              alignTo = axisNeedsAlign.pop();
              niceScaleExtent(alignTo.scale, alignTo.model);
            }

            each(axisNeedsAlign, function (axis) {
              alignScaleTicks(axis.scale, axis.model, alignTo.scale);
            });
          }
        }

        updateAxisTicks(axesMap.x);
        updateAxisTicks(axesMap.y); // Key: axisDim_axisIndex, value: boolean, whether onZero target.

        var onZeroRecords = {};
        each(axesMap.x, function (xAxis) {
          fixAxisOnZero(axesMap, 'y', xAxis, onZeroRecords);
        });
        each(axesMap.y, function (yAxis) {
          fixAxisOnZero(axesMap, 'x', yAxis, onZeroRecords);
        }); // Resize again if containLabel is enabled
        // FIXME It may cause getting wrong grid size in data processing stage

        this.resize(this.model, api);
      };
      /**
       * Resize the grid
       */


      Grid.prototype.resize = function (gridModel, api, ignoreContainLabel) {
        var boxLayoutParams = gridModel.getBoxLayoutParams();
        var isContainLabel = !ignoreContainLabel && gridModel.get('containLabel');
        var gridRect = getLayoutRect(boxLayoutParams, {
          width: api.getWidth(),
          height: api.getHeight()
        });
        this._rect = gridRect;
        var axesList = this._axesList;
        adjustAxes(); // Minus label size

        if (isContainLabel) {
          each(axesList, function (axis) {
            if (!axis.model.get(['axisLabel', 'inside'])) {
              var labelUnionRect = estimateLabelUnionRect(axis);

              if (labelUnionRect) {
                var dim = axis.isHorizontal() ? 'height' : 'width';
                var margin = axis.model.get(['axisLabel', 'margin']);
                gridRect[dim] -= labelUnionRect[dim] + margin;

                if (axis.position === 'top') {
                  gridRect.y += labelUnionRect.height + margin;
                } else if (axis.position === 'left') {
                  gridRect.x += labelUnionRect.width + margin;
                }
              }
            }
          });
          adjustAxes();
        }

        each(this._coordsList, function (coord) {
          // Calculate affine matrix to accelerate the data to point transform.
          // If all the axes scales are time or value.
          coord.calcAffineTransform();
        });

        function adjustAxes() {
          each(axesList, function (axis) {
            var isHorizontal = axis.isHorizontal();
            var extent = isHorizontal ? [0, gridRect.width] : [0, gridRect.height];
            var idx = axis.inverse ? 1 : 0;
            axis.setExtent(extent[idx], extent[1 - idx]);
            updateAxisTransform(axis, isHorizontal ? gridRect.x : gridRect.y);
          });
        }
      };

      Grid.prototype.getAxis = function (dim, axisIndex) {
        var axesMapOnDim = this._axesMap[dim];

        if (axesMapOnDim != null) {
          return axesMapOnDim[axisIndex || 0];
        }
      };

      Grid.prototype.getAxes = function () {
        return this._axesList.slice();
      };

      Grid.prototype.getCartesian = function (xAxisIndex, yAxisIndex) {
        if (xAxisIndex != null && yAxisIndex != null) {
          var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
          return this._coordsMap[key];
        }

        if (isObject(xAxisIndex)) {
          yAxisIndex = xAxisIndex.yAxisIndex;
          xAxisIndex = xAxisIndex.xAxisIndex;
        }

        for (var i = 0, coordList = this._coordsList; i < coordList.length; i++) {
          if (coordList[i].getAxis('x').index === xAxisIndex || coordList[i].getAxis('y').index === yAxisIndex) {
            return coordList[i];
          }
        }
      };

      Grid.prototype.getCartesians = function () {
        return this._coordsList.slice();
      };
      /**
       * @implements
       */


      Grid.prototype.convertToPixel = function (ecModel, finder, value) {
        var target = this._findConvertTarget(finder);

        return target.cartesian ? target.cartesian.dataToPoint(value) : target.axis ? target.axis.toGlobalCoord(target.axis.dataToCoord(value)) : null;
      };
      /**
       * @implements
       */


      Grid.prototype.convertFromPixel = function (ecModel, finder, value) {
        var target = this._findConvertTarget(finder);

        return target.cartesian ? target.cartesian.pointToData(value) : target.axis ? target.axis.coordToData(target.axis.toLocalCoord(value)) : null;
      };

      Grid.prototype._findConvertTarget = function (finder) {
        var seriesModel = finder.seriesModel;
        var xAxisModel = finder.xAxisModel || seriesModel && seriesModel.getReferringComponents('xAxis', SINGLE_REFERRING).models[0];
        var yAxisModel = finder.yAxisModel || seriesModel && seriesModel.getReferringComponents('yAxis', SINGLE_REFERRING).models[0];
        var gridModel = finder.gridModel;
        var coordsList = this._coordsList;
        var cartesian;
        var axis;

        if (seriesModel) {
          cartesian = seriesModel.coordinateSystem;
          indexOf(coordsList, cartesian) < 0 && (cartesian = null);
        } else if (xAxisModel && yAxisModel) {
          cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
        } else if (xAxisModel) {
          axis = this.getAxis('x', xAxisModel.componentIndex);
        } else if (yAxisModel) {
          axis = this.getAxis('y', yAxisModel.componentIndex);
        } // Lowest priority.
        else if (gridModel) {
            var grid = gridModel.coordinateSystem;

            if (grid === this) {
              cartesian = this._coordsList[0];
            }
          }

        return {
          cartesian: cartesian,
          axis: axis
        };
      };
      /**
       * @implements
       */


      Grid.prototype.containPoint = function (point) {
        var coord = this._coordsList[0];

        if (coord) {
          return coord.containPoint(point);
        }
      };
      /**
       * Initialize cartesian coordinate systems
       */


      Grid.prototype._initCartesian = function (gridModel, ecModel, api) {
        var _this = this;

        var grid = this;
        var axisPositionUsed = {
          left: false,
          right: false,
          top: false,
          bottom: false
        };
        var axesMap = {
          x: {},
          y: {}
        };
        var axesCount = {
          x: 0,
          y: 0
        }; // Create axis

        ecModel.eachComponent('xAxis', createAxisCreator('x'), this);
        ecModel.eachComponent('yAxis', createAxisCreator('y'), this);

        if (!axesCount.x || !axesCount.y) {
          // Roll back when there no either x or y axis
          this._axesMap = {};
          this._axesList = [];
          return;
        }

        this._axesMap = axesMap; // Create cartesian2d

        each(axesMap.x, function (xAxis, xAxisIndex) {
          each(axesMap.y, function (yAxis, yAxisIndex) {
            var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
            var cartesian = new Cartesian2D(key);
            cartesian.master = _this;
            cartesian.model = gridModel;
            _this._coordsMap[key] = cartesian;

            _this._coordsList.push(cartesian);

            cartesian.addAxis(xAxis);
            cartesian.addAxis(yAxis);
          });
        });

        function createAxisCreator(dimName) {
          return function (axisModel, idx) {
            if (!isAxisUsedInTheGrid(axisModel, gridModel)) {
              return;
            }

            var axisPosition = axisModel.get('position');

            if (dimName === 'x') {
              // Fix position
              if (axisPosition !== 'top' && axisPosition !== 'bottom') {
                // Default bottom of X
                axisPosition = axisPositionUsed.bottom ? 'top' : 'bottom';
              }
            } else {
              // Fix position
              if (axisPosition !== 'left' && axisPosition !== 'right') {
                // Default left of Y
                axisPosition = axisPositionUsed.left ? 'right' : 'left';
              }
            }

            axisPositionUsed[axisPosition] = true;
            var axis = new Axis2D(dimName, createScaleByModel(axisModel), [0, 0], axisModel.get('type'), axisPosition);
            var isCategory = axis.type === 'category';
            axis.onBand = isCategory && axisModel.get('boundaryGap');
            axis.inverse = axisModel.get('inverse'); // Inject axis into axisModel

            axisModel.axis = axis; // Inject axisModel into axis

            axis.model = axisModel; // Inject grid info axis

            axis.grid = grid; // Index of axis, can be used as key

            axis.index = idx;

            grid._axesList.push(axis);

            axesMap[dimName][idx] = axis;
            axesCount[dimName]++;
          };
        }
      };
      /**
       * Update cartesian properties from series.
       */


      Grid.prototype._updateScale = function (ecModel, gridModel) {
        // Reset scale
        each(this._axesList, function (axis) {
          axis.scale.setExtent(Infinity, -Infinity);

          if (axis.type === 'category') {
            var categorySortInfo = axis.model.get('categorySortInfo');
            axis.scale.setSortInfo(categorySortInfo);
          }
        });
        ecModel.eachSeries(function (seriesModel) {
          if (isCartesian2DSeries(seriesModel)) {
            var axesModelMap = findAxisModels(seriesModel);
            var xAxisModel = axesModelMap.xAxisModel;
            var yAxisModel = axesModelMap.yAxisModel;

            if (!isAxisUsedInTheGrid(xAxisModel, gridModel) || !isAxisUsedInTheGrid(yAxisModel, gridModel)) {
              return;
            }

            var cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
            var data = seriesModel.getData();
            var xAxis = cartesian.getAxis('x');
            var yAxis = cartesian.getAxis('y');
            unionExtent(data, xAxis);
            unionExtent(data, yAxis);
          }
        }, this);

        function unionExtent(data, axis) {
          each(getDataDimensionsOnAxis(data, axis.dim), function (dim) {
            axis.scale.unionExtentFromData(data, dim);
          });
        }
      };
      /**
       * @param dim 'x' or 'y' or 'auto' or null/undefined
       */


      Grid.prototype.getTooltipAxes = function (dim) {
        var baseAxes = [];
        var otherAxes = [];
        each(this.getCartesians(), function (cartesian) {
          var baseAxis = dim != null && dim !== 'auto' ? cartesian.getAxis(dim) : cartesian.getBaseAxis();
          var otherAxis = cartesian.getOtherAxis(baseAxis);
          indexOf(baseAxes, baseAxis) < 0 && baseAxes.push(baseAxis);
          indexOf(otherAxes, otherAxis) < 0 && otherAxes.push(otherAxis);
        });
        return {
          baseAxes: baseAxes,
          otherAxes: otherAxes
        };
      };

      Grid.create = function (ecModel, api) {
        var grids = [];
        ecModel.eachComponent('grid', function (gridModel, idx) {
          var grid = new Grid(gridModel, ecModel, api);
          grid.name = 'grid_' + idx; // dataSampling requires axis extent, so resize
          // should be performed in create stage.

          grid.resize(gridModel, api, true);
          gridModel.coordinateSystem = grid;
          grids.push(grid);
        }); // Inject the coordinateSystems into seriesModel

        ecModel.eachSeries(function (seriesModel) {
          if (!isCartesian2DSeries(seriesModel)) {
            return;
          }

          var axesModelMap = findAxisModels(seriesModel);
          var xAxisModel = axesModelMap.xAxisModel;
          var yAxisModel = axesModelMap.yAxisModel;
          var gridModel = xAxisModel.getCoordSysModel();

          if ("development" !== 'production') {
            if (!gridModel) {
              throw new Error('Grid "' + retrieve3(xAxisModel.get('gridIndex'), xAxisModel.get('gridId'), 0) + '" not found');
            }

            if (xAxisModel.getCoordSysModel() !== yAxisModel.getCoordSysModel()) {
              throw new Error('xAxis and yAxis must use the same grid');
            }
          }

          var grid = gridModel.coordinateSystem;
          seriesModel.coordinateSystem = grid.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
        });
        return grids;
      }; // For deciding which dimensions to use when creating list data


      Grid.dimensions = cartesian2DDimensions;
      return Grid;
    }();
    /**
     * Check if the axis is used in the specified grid.
     */


    function isAxisUsedInTheGrid(axisModel, gridModel) {
      return axisModel.getCoordSysModel() === gridModel;
    }

    function fixAxisOnZero(axesMap, otherAxisDim, axis, // Key: see `getOnZeroRecordKey`
    onZeroRecords) {
      axis.getAxesOnZeroOf = function () {
        // TODO: onZero of multiple axes.
        return otherAxisOnZeroOf ? [otherAxisOnZeroOf] : [];
      }; // onZero can not be enabled in these two situations:
      // 1. When any other axis is a category axis.
      // 2. When no axis is cross 0 point.


      var otherAxes = axesMap[otherAxisDim];
      var otherAxisOnZeroOf;
      var axisModel = axis.model;
      var onZero = axisModel.get(['axisLine', 'onZero']);
      var onZeroAxisIndex = axisModel.get(['axisLine', 'onZeroAxisIndex']);

      if (!onZero) {
        return;
      } // If target axis is specified.


      if (onZeroAxisIndex != null) {
        if (canOnZeroToAxis(otherAxes[onZeroAxisIndex])) {
          otherAxisOnZeroOf = otherAxes[onZeroAxisIndex];
        }
      } else {
        // Find the first available other axis.
        for (var idx in otherAxes) {
          if (otherAxes.hasOwnProperty(idx) && canOnZeroToAxis(otherAxes[idx]) // Consider that two Y axes on one value axis,
          // if both onZero, the two Y axes overlap.
          && !onZeroRecords[getOnZeroRecordKey(otherAxes[idx])]) {
            otherAxisOnZeroOf = otherAxes[idx];
            break;
          }
        }
      }

      if (otherAxisOnZeroOf) {
        onZeroRecords[getOnZeroRecordKey(otherAxisOnZeroOf)] = true;
      }

      function getOnZeroRecordKey(axis) {
        return axis.dim + '_' + axis.index;
      }
    }

    function canOnZeroToAxis(axis) {
      return axis && axis.type !== 'category' && axis.type !== 'time' && ifAxisCrossZero(axis);
    }

    function updateAxisTransform(axis, coordBase) {
      var axisExtent = axis.getExtent();
      var axisExtentSum = axisExtent[0] + axisExtent[1]; // Fast transform

      axis.toGlobalCoord = axis.dim === 'x' ? function (coord) {
        return coord + coordBase;
      } : function (coord) {
        return axisExtentSum - coord + coordBase;
      };
      axis.toLocalCoord = axis.dim === 'x' ? function (coord) {
        return coord - coordBase;
      } : function (coord) {
        return axisExtentSum - coord + coordBase;
      };
    }

    var PI$5 = Math.PI;
    /**
     * A final axis is translated and rotated from a "standard axis".
     * So opt.position and opt.rotation is required.
     *
     * A standard axis is and axis from [0, 0] to [0, axisExtent[1]],
     * for example: (0, 0) ------------> (0, 50)
     *
     * nameDirection or tickDirection or labelDirection is 1 means tick
     * or label is below the standard axis, whereas is -1 means above
     * the standard axis. labelOffset means offset between label and axis,
     * which is useful when 'onZero', where axisLabel is in the grid and
     * label in outside grid.
     *
     * Tips: like always,
     * positive rotation represents anticlockwise, and negative rotation
     * represents clockwise.
     * The direction of position coordinate is the same as the direction
     * of screen coordinate.
     *
     * Do not need to consider axis 'inverse', which is auto processed by
     * axis extent.
     */

    var AxisBuilder =
    /** @class */
    function () {
      function AxisBuilder(axisModel, opt) {
        this.group = new Group();
        this.opt = opt;
        this.axisModel = axisModel; // Default value

        defaults(opt, {
          labelOffset: 0,
          nameDirection: 1,
          tickDirection: 1,
          labelDirection: 1,
          silent: true,
          handleAutoShown: function () {
            return true;
          }
        }); // FIXME Not use a seperate text group?

        var transformGroup = new Group({
          x: opt.position[0],
          y: opt.position[1],
          rotation: opt.rotation
        }); // this.group.add(transformGroup);
        // this._transformGroup = transformGroup;

        transformGroup.updateTransform();
        this._transformGroup = transformGroup;
      }

      AxisBuilder.prototype.hasBuilder = function (name) {
        return !!builders[name];
      };

      AxisBuilder.prototype.add = function (name) {
        builders[name](this.opt, this.axisModel, this.group, this._transformGroup);
      };

      AxisBuilder.prototype.getGroup = function () {
        return this.group;
      };

      AxisBuilder.innerTextLayout = function (axisRotation, textRotation, direction) {
        var rotationDiff = remRadian(textRotation - axisRotation);
        var textAlign;
        var textVerticalAlign;

        if (isRadianAroundZero(rotationDiff)) {
          // Label is parallel with axis line.
          textVerticalAlign = direction > 0 ? 'top' : 'bottom';
          textAlign = 'center';
        } else if (isRadianAroundZero(rotationDiff - PI$5)) {
          // Label is inverse parallel with axis line.
          textVerticalAlign = direction > 0 ? 'bottom' : 'top';
          textAlign = 'center';
        } else {
          textVerticalAlign = 'middle';

          if (rotationDiff > 0 && rotationDiff < PI$5) {
            textAlign = direction > 0 ? 'right' : 'left';
          } else {
            textAlign = direction > 0 ? 'left' : 'right';
          }
        }

        return {
          rotation: rotationDiff,
          textAlign: textAlign,
          textVerticalAlign: textVerticalAlign
        };
      };

      AxisBuilder.makeAxisEventDataBase = function (axisModel) {
        var eventData = {
          componentType: axisModel.mainType,
          componentIndex: axisModel.componentIndex
        };
        eventData[axisModel.mainType + 'Index'] = axisModel.componentIndex;
        return eventData;
      };

      AxisBuilder.isLabelSilent = function (axisModel) {
        var tooltipOpt = axisModel.get('tooltip');
        return axisModel.get('silent') // Consider mouse cursor, add these restrictions.
        || !(axisModel.get('triggerEvent') || tooltipOpt && tooltipOpt.show);
      };

      return AxisBuilder;
    }();
    var builders = {
      axisLine: function (opt, axisModel, group, transformGroup) {
        var shown = axisModel.get(['axisLine', 'show']);

        if (shown === 'auto' && opt.handleAutoShown) {
          shown = opt.handleAutoShown('axisLine');
        }

        if (!shown) {
          return;
        }

        var extent = axisModel.axis.getExtent();
        var matrix = transformGroup.transform;
        var pt1 = [extent[0], 0];
        var pt2 = [extent[1], 0];
        var inverse = pt1[0] > pt2[0];

        if (matrix) {
          applyTransform(pt1, pt1, matrix);
          applyTransform(pt2, pt2, matrix);
        }

        var lineStyle = extend({
          lineCap: 'round'
        }, axisModel.getModel(['axisLine', 'lineStyle']).getLineStyle());
        var line = new Line({
          shape: {
            x1: pt1[0],
            y1: pt1[1],
            x2: pt2[0],
            y2: pt2[1]
          },
          style: lineStyle,
          strokeContainThreshold: opt.strokeContainThreshold || 5,
          silent: true,
          z2: 1
        });
        subPixelOptimizeLine$1(line.shape, line.style.lineWidth);
        line.anid = 'line';
        group.add(line);
        var arrows = axisModel.get(['axisLine', 'symbol']);

        if (arrows != null) {
          var arrowSize = axisModel.get(['axisLine', 'symbolSize']);

          if (isString(arrows)) {
            // Use the same arrow for start and end point
            arrows = [arrows, arrows];
          }

          if (isString(arrowSize) || isNumber(arrowSize)) {
            // Use the same size for width and height
            arrowSize = [arrowSize, arrowSize];
          }

          var arrowOffset = normalizeSymbolOffset(axisModel.get(['axisLine', 'symbolOffset']) || 0, arrowSize);
          var symbolWidth_1 = arrowSize[0];
          var symbolHeight_1 = arrowSize[1];
          each([{
            rotate: opt.rotation + Math.PI / 2,
            offset: arrowOffset[0],
            r: 0
          }, {
            rotate: opt.rotation - Math.PI / 2,
            offset: arrowOffset[1],
            r: Math.sqrt((pt1[0] - pt2[0]) * (pt1[0] - pt2[0]) + (pt1[1] - pt2[1]) * (pt1[1] - pt2[1]))
          }], function (point, index) {
            if (arrows[index] !== 'none' && arrows[index] != null) {
              var symbol = createSymbol(arrows[index], -symbolWidth_1 / 2, -symbolHeight_1 / 2, symbolWidth_1, symbolHeight_1, lineStyle.stroke, true); // Calculate arrow position with offset

              var r = point.r + point.offset;
              var pt = inverse ? pt2 : pt1;
              symbol.attr({
                rotation: point.rotate,
                x: pt[0] + r * Math.cos(opt.rotation),
                y: pt[1] - r * Math.sin(opt.rotation),
                silent: true,
                z2: 11
              });
              group.add(symbol);
            }
          });
        }
      },
      axisTickLabel: function (opt, axisModel, group, transformGroup) {
        var ticksEls = buildAxisMajorTicks(group, transformGroup, axisModel, opt);
        var labelEls = buildAxisLabel(group, transformGroup, axisModel, opt);
        fixMinMaxLabelShow(axisModel, labelEls, ticksEls);
        buildAxisMinorTicks(group, transformGroup, axisModel, opt.tickDirection); // This bit fixes the label overlap issue for the time chart.
        // See https://github.com/apache/echarts/issues/14266 for more.

        if (axisModel.get(['axisLabel', 'hideOverlap'])) {
          var labelList = prepareLayoutList(map(labelEls, function (label) {
            return {
              label: label,
              priority: label.z2,
              defaultAttr: {
                ignore: label.ignore
              }
            };
          }));
          hideOverlap(labelList);
        }
      },
      axisName: function (opt, axisModel, group, transformGroup) {
        var name = retrieve(opt.axisName, axisModel.get('name'));

        if (!name) {
          return;
        }

        var nameLocation = axisModel.get('nameLocation');
        var nameDirection = opt.nameDirection;
        var textStyleModel = axisModel.getModel('nameTextStyle');
        var gap = axisModel.get('nameGap') || 0;
        var extent = axisModel.axis.getExtent();
        var gapSignal = extent[0] > extent[1] ? -1 : 1;
        var pos = [nameLocation === 'start' ? extent[0] - gapSignal * gap : nameLocation === 'end' ? extent[1] + gapSignal * gap : (extent[0] + extent[1]) / 2, // Reuse labelOffset.
        isNameLocationCenter(nameLocation) ? opt.labelOffset + nameDirection * gap : 0];
        var labelLayout;
        var nameRotation = axisModel.get('nameRotate');

        if (nameRotation != null) {
          nameRotation = nameRotation * PI$5 / 180; // To radian.
        }

        var axisNameAvailableWidth;

        if (isNameLocationCenter(nameLocation)) {
          labelLayout = AxisBuilder.innerTextLayout(opt.rotation, nameRotation != null ? nameRotation : opt.rotation, // Adapt to axis.
          nameDirection);
        } else {
          labelLayout = endTextLayout(opt.rotation, nameLocation, nameRotation || 0, extent);
          axisNameAvailableWidth = opt.axisNameAvailableWidth;

          if (axisNameAvailableWidth != null) {
            axisNameAvailableWidth = Math.abs(axisNameAvailableWidth / Math.sin(labelLayout.rotation));
            !isFinite(axisNameAvailableWidth) && (axisNameAvailableWidth = null);
          }
        }

        var textFont = textStyleModel.getFont();
        var truncateOpt = axisModel.get('nameTruncate', true) || {};
        var ellipsis = truncateOpt.ellipsis;
        var maxWidth = retrieve(opt.nameTruncateMaxWidth, truncateOpt.maxWidth, axisNameAvailableWidth);
        var textEl = new ZRText({
          x: pos[0],
          y: pos[1],
          rotation: labelLayout.rotation,
          silent: AxisBuilder.isLabelSilent(axisModel),
          style: createTextStyle(textStyleModel, {
            text: name,
            font: textFont,
            overflow: 'truncate',
            width: maxWidth,
            ellipsis: ellipsis,
            fill: textStyleModel.getTextColor() || axisModel.get(['axisLine', 'lineStyle', 'color']),
            align: textStyleModel.get('align') || labelLayout.textAlign,
            verticalAlign: textStyleModel.get('verticalAlign') || labelLayout.textVerticalAlign
          }),
          z2: 1
        });
        setTooltipConfig({
          el: textEl,
          componentModel: axisModel,
          itemName: name
        });
        textEl.__fullText = name; // Id for animation

        textEl.anid = 'name';

        if (axisModel.get('triggerEvent')) {
          var eventData = AxisBuilder.makeAxisEventDataBase(axisModel);
          eventData.targetType = 'axisName';
          eventData.name = name;
          getECData(textEl).eventData = eventData;
        } // FIXME


        transformGroup.add(textEl);
        textEl.updateTransform();
        group.add(textEl);
        textEl.decomposeTransform();
      }
    };

    function endTextLayout(rotation, textPosition, textRotate, extent) {
      var rotationDiff = remRadian(textRotate - rotation);
      var textAlign;
      var textVerticalAlign;
      var inverse = extent[0] > extent[1];
      var onLeft = textPosition === 'start' && !inverse || textPosition !== 'start' && inverse;

      if (isRadianAroundZero(rotationDiff - PI$5 / 2)) {
        textVerticalAlign = onLeft ? 'bottom' : 'top';
        textAlign = 'center';
      } else if (isRadianAroundZero(rotationDiff - PI$5 * 1.5)) {
        textVerticalAlign = onLeft ? 'top' : 'bottom';
        textAlign = 'center';
      } else {
        textVerticalAlign = 'middle';

        if (rotationDiff < PI$5 * 1.5 && rotationDiff > PI$5 / 2) {
          textAlign = onLeft ? 'left' : 'right';
        } else {
          textAlign = onLeft ? 'right' : 'left';
        }
      }

      return {
        rotation: rotationDiff,
        textAlign: textAlign,
        textVerticalAlign: textVerticalAlign
      };
    }

    function fixMinMaxLabelShow(axisModel, labelEls, tickEls) {
      if (shouldShowAllLabels(axisModel.axis)) {
        return;
      } // If min or max are user set, we need to check
      // If the tick on min(max) are overlap on their neighbour tick
      // If they are overlapped, we need to hide the min(max) tick label


      var showMinLabel = axisModel.get(['axisLabel', 'showMinLabel']);
      var showMaxLabel = axisModel.get(['axisLabel', 'showMaxLabel']); // FIXME
      // Have not consider onBand yet, where tick els is more than label els.

      labelEls = labelEls || [];
      tickEls = tickEls || [];
      var firstLabel = labelEls[0];
      var nextLabel = labelEls[1];
      var lastLabel = labelEls[labelEls.length - 1];
      var prevLabel = labelEls[labelEls.length - 2];
      var firstTick = tickEls[0];
      var nextTick = tickEls[1];
      var lastTick = tickEls[tickEls.length - 1];
      var prevTick = tickEls[tickEls.length - 2];

      if (showMinLabel === false) {
        ignoreEl(firstLabel);
        ignoreEl(firstTick);
      } else if (isTwoLabelOverlapped(firstLabel, nextLabel)) {
        if (showMinLabel) {
          ignoreEl(nextLabel);
          ignoreEl(nextTick);
        } else {
          ignoreEl(firstLabel);
          ignoreEl(firstTick);
        }
      }

      if (showMaxLabel === false) {
        ignoreEl(lastLabel);
        ignoreEl(lastTick);
      } else if (isTwoLabelOverlapped(prevLabel, lastLabel)) {
        if (showMaxLabel) {
          ignoreEl(prevLabel);
          ignoreEl(prevTick);
        } else {
          ignoreEl(lastLabel);
          ignoreEl(lastTick);
        }
      }
    }

    function ignoreEl(el) {
      el && (el.ignore = true);
    }

    function isTwoLabelOverlapped(current, next) {
      // current and next has the same rotation.
      var firstRect = current && current.getBoundingRect().clone();
      var nextRect = next && next.getBoundingRect().clone();

      if (!firstRect || !nextRect) {
        return;
      } // When checking intersect of two rotated labels, we use mRotationBack
      // to avoid that boundingRect is enlarge when using `boundingRect.applyTransform`.


      var mRotationBack = identity([]);
      rotate(mRotationBack, mRotationBack, -current.rotation);
      firstRect.applyTransform(mul$1([], mRotationBack, current.getLocalTransform()));
      nextRect.applyTransform(mul$1([], mRotationBack, next.getLocalTransform()));
      return firstRect.intersect(nextRect);
    }

    function isNameLocationCenter(nameLocation) {
      return nameLocation === 'middle' || nameLocation === 'center';
    }

    function createTicks(ticksCoords, tickTransform, tickEndCoord, tickLineStyle, anidPrefix) {
      var tickEls = [];
      var pt1 = [];
      var pt2 = [];

      for (var i = 0; i < ticksCoords.length; i++) {
        var tickCoord = ticksCoords[i].coord;
        pt1[0] = tickCoord;
        pt1[1] = 0;
        pt2[0] = tickCoord;
        pt2[1] = tickEndCoord;

        if (tickTransform) {
          applyTransform(pt1, pt1, tickTransform);
          applyTransform(pt2, pt2, tickTransform);
        } // Tick line, Not use group transform to have better line draw


        var tickEl = new Line({
          shape: {
            x1: pt1[0],
            y1: pt1[1],
            x2: pt2[0],
            y2: pt2[1]
          },
          style: tickLineStyle,
          z2: 2,
          autoBatch: true,
          silent: true
        });
        subPixelOptimizeLine$1(tickEl.shape, tickEl.style.lineWidth);
        tickEl.anid = anidPrefix + '_' + ticksCoords[i].tickValue;
        tickEls.push(tickEl);
      }

      return tickEls;
    }

    function buildAxisMajorTicks(group, transformGroup, axisModel, opt) {
      var axis = axisModel.axis;
      var tickModel = axisModel.getModel('axisTick');
      var shown = tickModel.get('show');

      if (shown === 'auto' && opt.handleAutoShown) {
        shown = opt.handleAutoShown('axisTick');
      }

      if (!shown || axis.scale.isBlank()) {
        return;
      }

      var lineStyleModel = tickModel.getModel('lineStyle');
      var tickEndCoord = opt.tickDirection * tickModel.get('length');
      var ticksCoords = axis.getTicksCoords();
      var ticksEls = createTicks(ticksCoords, transformGroup.transform, tickEndCoord, defaults(lineStyleModel.getLineStyle(), {
        stroke: axisModel.get(['axisLine', 'lineStyle', 'color'])
      }), 'ticks');

      for (var i = 0; i < ticksEls.length; i++) {
        group.add(ticksEls[i]);
      }

      return ticksEls;
    }

    function buildAxisMinorTicks(group, transformGroup, axisModel, tickDirection) {
      var axis = axisModel.axis;
      var minorTickModel = axisModel.getModel('minorTick');

      if (!minorTickModel.get('show') || axis.scale.isBlank()) {
        return;
      }

      var minorTicksCoords = axis.getMinorTicksCoords();

      if (!minorTicksCoords.length) {
        return;
      }

      var lineStyleModel = minorTickModel.getModel('lineStyle');
      var tickEndCoord = tickDirection * minorTickModel.get('length');
      var minorTickLineStyle = defaults(lineStyleModel.getLineStyle(), defaults(axisModel.getModel('axisTick').getLineStyle(), {
        stroke: axisModel.get(['axisLine', 'lineStyle', 'color'])
      }));

      for (var i = 0; i < minorTicksCoords.length; i++) {
        var minorTicksEls = createTicks(minorTicksCoords[i], transformGroup.transform, tickEndCoord, minorTickLineStyle, 'minorticks_' + i);

        for (var k = 0; k < minorTicksEls.length; k++) {
          group.add(minorTicksEls[k]);
        }
      }
    }

    function buildAxisLabel(group, transformGroup, axisModel, opt) {
      var axis = axisModel.axis;
      var show = retrieve(opt.axisLabelShow, axisModel.get(['axisLabel', 'show']));

      if (!show || axis.scale.isBlank()) {
        return;
      }

      var labelModel = axisModel.getModel('axisLabel');
      var labelMargin = labelModel.get('margin');
      var labels = axis.getViewLabels(); // Special label rotate.

      var labelRotation = (retrieve(opt.labelRotate, labelModel.get('rotate')) || 0) * PI$5 / 180;
      var labelLayout = AxisBuilder.innerTextLayout(opt.rotation, labelRotation, opt.labelDirection);
      var rawCategoryData = axisModel.getCategories && axisModel.getCategories(true);
      var labelEls = [];
      var silent = AxisBuilder.isLabelSilent(axisModel);
      var triggerEvent = axisModel.get('triggerEvent');
      each(labels, function (labelItem, index) {
        var tickValue = axis.scale.type === 'ordinal' ? axis.scale.getRawOrdinalNumber(labelItem.tickValue) : labelItem.tickValue;
        var formattedLabel = labelItem.formattedLabel;
        var rawLabel = labelItem.rawLabel;
        var itemLabelModel = labelModel;

        if (rawCategoryData && rawCategoryData[tickValue]) {
          var rawCategoryItem = rawCategoryData[tickValue];

          if (isObject(rawCategoryItem) && rawCategoryItem.textStyle) {
            itemLabelModel = new Model(rawCategoryItem.textStyle, labelModel, axisModel.ecModel);
          }
        }

        var textColor = itemLabelModel.getTextColor() || axisModel.get(['axisLine', 'lineStyle', 'color']);
        var tickCoord = axis.dataToCoord(tickValue);
        var textEl = new ZRText({
          x: tickCoord,
          y: opt.labelOffset + opt.labelDirection * labelMargin,
          rotation: labelLayout.rotation,
          silent: silent,
          z2: 10 + (labelItem.level || 0),
          style: createTextStyle(itemLabelModel, {
            text: formattedLabel,
            align: itemLabelModel.getShallow('align', true) || labelLayout.textAlign,
            verticalAlign: itemLabelModel.getShallow('verticalAlign', true) || itemLabelModel.getShallow('baseline', true) || labelLayout.textVerticalAlign,
            fill: isFunction(textColor) ? textColor( // (1) In category axis with data zoom, tick is not the original
            // index of axis.data. So tick should not be exposed to user
            // in category axis.
            // (2) Compatible with previous version, which always use formatted label as
            // input. But in interval scale the formatted label is like '223,445', which
            // maked user repalce ','. So we modify it to return original val but remain
            // it as 'string' to avoid error in replacing.
            axis.type === 'category' ? rawLabel : axis.type === 'value' ? tickValue + '' : tickValue, index) : textColor
          })
        });
        textEl.anid = 'label_' + tickValue; // Pack data for mouse event

        if (triggerEvent) {
          var eventData = AxisBuilder.makeAxisEventDataBase(axisModel);
          eventData.targetType = 'axisLabel';
          eventData.value = rawLabel;
          eventData.tickIndex = index;

          if (axis.type === 'category') {
            eventData.dataIndex = tickValue;
          }

          getECData(textEl).eventData = eventData;
        } // FIXME


        transformGroup.add(textEl);
        textEl.updateTransform();
        labelEls.push(textEl);
        group.add(textEl);
        textEl.decomposeTransform();
      });
      return labelEls;
    }

    // allAxesInfo should be updated when setOption performed.

    function collect(ecModel, api) {
      var result = {
        /**
         * key: makeKey(axis.model)
         * value: {
         *      axis,
         *      coordSys,
         *      axisPointerModel,
         *      triggerTooltip,
         *      involveSeries,
         *      snap,
         *      seriesModels,
         *      seriesDataCount
         * }
         */
        axesInfo: {},
        seriesInvolved: false,

        /**
         * key: makeKey(coordSys.model)
         * value: Object: key makeKey(axis.model), value: axisInfo
         */
        coordSysAxesInfo: {},
        coordSysMap: {}
      };
      collectAxesInfo(result, ecModel, api); // Check seriesInvolved for performance, in case too many series in some chart.

      result.seriesInvolved && collectSeriesInfo(result, ecModel);
      return result;
    }

    function collectAxesInfo(result, ecModel, api) {
      var globalTooltipModel = ecModel.getComponent('tooltip');
      var globalAxisPointerModel = ecModel.getComponent('axisPointer'); // links can only be set on global.

      var linksOption = globalAxisPointerModel.get('link', true) || [];
      var linkGroups = []; // Collect axes info.

      each(api.getCoordinateSystems(), function (coordSys) {
        // Some coordinate system do not support axes, like geo.
        if (!coordSys.axisPointerEnabled) {
          return;
        }

        var coordSysKey = makeKey(coordSys.model);
        var axesInfoInCoordSys = result.coordSysAxesInfo[coordSysKey] = {};
        result.coordSysMap[coordSysKey] = coordSys; // Set tooltip (like 'cross') is a convienent way to show axisPointer
        // for user. So we enable seting tooltip on coordSys model.

        var coordSysModel = coordSys.model;
        var baseTooltipModel = coordSysModel.getModel('tooltip', globalTooltipModel);
        each(coordSys.getAxes(), curry(saveTooltipAxisInfo, false, null)); // If axis tooltip used, choose tooltip axis for each coordSys.
        // Notice this case: coordSys is `grid` but not `cartesian2D` here.

        if (coordSys.getTooltipAxes && globalTooltipModel // If tooltip.showContent is set as false, tooltip will not
        // show but axisPointer will show as normal.
        && baseTooltipModel.get('show')) {
          // Compatible with previous logic. But series.tooltip.trigger: 'axis'
          // or series.data[n].tooltip.trigger: 'axis' are not support any more.
          var triggerAxis = baseTooltipModel.get('trigger') === 'axis';
          var cross = baseTooltipModel.get(['axisPointer', 'type']) === 'cross';
          var tooltipAxes = coordSys.getTooltipAxes(baseTooltipModel.get(['axisPointer', 'axis']));

          if (triggerAxis || cross) {
            each(tooltipAxes.baseAxes, curry(saveTooltipAxisInfo, cross ? 'cross' : true, triggerAxis));
          }

          if (cross) {
            each(tooltipAxes.otherAxes, curry(saveTooltipAxisInfo, 'cross', false));
          }
        } // fromTooltip: true | false | 'cross'
        // triggerTooltip: true | false | null


        function saveTooltipAxisInfo(fromTooltip, triggerTooltip, axis) {
          var axisPointerModel = axis.model.getModel('axisPointer', globalAxisPointerModel);
          var axisPointerShow = axisPointerModel.get('show');

          if (!axisPointerShow || axisPointerShow === 'auto' && !fromTooltip && !isHandleTrigger(axisPointerModel)) {
            return;
          }

          if (triggerTooltip == null) {
            triggerTooltip = axisPointerModel.get('triggerTooltip');
          }

          axisPointerModel = fromTooltip ? makeAxisPointerModel(axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip) : axisPointerModel;
          var snap = axisPointerModel.get('snap');
          var axisKey = makeKey(axis.model);
          var involveSeries = triggerTooltip || snap || axis.type === 'category'; // If result.axesInfo[key] exist, override it (tooltip has higher priority).

          var axisInfo = result.axesInfo[axisKey] = {
            key: axisKey,
            axis: axis,
            coordSys: coordSys,
            axisPointerModel: axisPointerModel,
            triggerTooltip: triggerTooltip,
            involveSeries: involveSeries,
            snap: snap,
            useHandle: isHandleTrigger(axisPointerModel),
            seriesModels: [],
            linkGroup: null
          };
          axesInfoInCoordSys[axisKey] = axisInfo;
          result.seriesInvolved = result.seriesInvolved || involveSeries;
          var groupIndex = getLinkGroupIndex(linksOption, axis);

          if (groupIndex != null) {
            var linkGroup = linkGroups[groupIndex] || (linkGroups[groupIndex] = {
              axesInfo: {}
            });
            linkGroup.axesInfo[axisKey] = axisInfo;
            linkGroup.mapper = linksOption[groupIndex].mapper;
            axisInfo.linkGroup = linkGroup;
          }
        }
      });
    }

    function makeAxisPointerModel(axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip) {
      var tooltipAxisPointerModel = baseTooltipModel.getModel('axisPointer');
      var fields = ['type', 'snap', 'lineStyle', 'shadowStyle', 'label', 'animation', 'animationDurationUpdate', 'animationEasingUpdate', 'z'];
      var volatileOption = {};
      each(fields, function (field) {
        volatileOption[field] = clone(tooltipAxisPointerModel.get(field));
      }); // category axis do not auto snap, otherwise some tick that do not
      // has value can not be hovered. value/time/log axis default snap if
      // triggered from tooltip and trigger tooltip.

      volatileOption.snap = axis.type !== 'category' && !!triggerTooltip; // Compatibel with previous behavior, tooltip axis do not show label by default.
      // Only these properties can be overrided from tooltip to axisPointer.

      if (tooltipAxisPointerModel.get('type') === 'cross') {
        volatileOption.type = 'line';
      }

      var labelOption = volatileOption.label || (volatileOption.label = {}); // Follow the convention, do not show label when triggered by tooltip by default.

      labelOption.show == null && (labelOption.show = false);

      if (fromTooltip === 'cross') {
        // When 'cross', both axes show labels.
        var tooltipAxisPointerLabelShow = tooltipAxisPointerModel.get(['label', 'show']);
        labelOption.show = tooltipAxisPointerLabelShow != null ? tooltipAxisPointerLabelShow : true; // If triggerTooltip, this is a base axis, which should better not use cross style
        // (cross style is dashed by default)

        if (!triggerTooltip) {
          var crossStyle = volatileOption.lineStyle = tooltipAxisPointerModel.get('crossStyle');
          crossStyle && defaults(labelOption, crossStyle.textStyle);
        }
      }

      return axis.model.getModel('axisPointer', new Model(volatileOption, globalAxisPointerModel, ecModel));
    }

    function collectSeriesInfo(result, ecModel) {
      // Prepare data for axis trigger
      ecModel.eachSeries(function (seriesModel) {
        // Notice this case: this coordSys is `cartesian2D` but not `grid`.
        var coordSys = seriesModel.coordinateSystem;
        var seriesTooltipTrigger = seriesModel.get(['tooltip', 'trigger'], true);
        var seriesTooltipShow = seriesModel.get(['tooltip', 'show'], true);

        if (!coordSys || seriesTooltipTrigger === 'none' || seriesTooltipTrigger === false || seriesTooltipTrigger === 'item' || seriesTooltipShow === false || seriesModel.get(['axisPointer', 'show'], true) === false) {
          return;
        }

        each(result.coordSysAxesInfo[makeKey(coordSys.model)], function (axisInfo) {
          var axis = axisInfo.axis;

          if (coordSys.getAxis(axis.dim) === axis) {
            axisInfo.seriesModels.push(seriesModel);
            axisInfo.seriesDataCount == null && (axisInfo.seriesDataCount = 0);
            axisInfo.seriesDataCount += seriesModel.getData().count();
          }
        });
      });
    }
    /**
     * For example:
     * {
     *     axisPointer: {
     *         links: [{
     *             xAxisIndex: [2, 4],
     *             yAxisIndex: 'all'
     *         }, {
     *             xAxisId: ['a5', 'a7'],
     *             xAxisName: 'xxx'
     *         }]
     *     }
     * }
     */


    function getLinkGroupIndex(linksOption, axis) {
      var axisModel = axis.model;
      var dim = axis.dim;

      for (var i = 0; i < linksOption.length; i++) {
        var linkOption = linksOption[i] || {};

        if (checkPropInLink(linkOption[dim + 'AxisId'], axisModel.id) || checkPropInLink(linkOption[dim + 'AxisIndex'], axisModel.componentIndex) || checkPropInLink(linkOption[dim + 'AxisName'], axisModel.name)) {
          return i;
        }
      }
    }

    function checkPropInLink(linkPropValue, axisPropValue) {
      return linkPropValue === 'all' || isArray(linkPropValue) && indexOf(linkPropValue, axisPropValue) >= 0 || linkPropValue === axisPropValue;
    }

    function fixValue(axisModel) {
      var axisInfo = getAxisInfo(axisModel);

      if (!axisInfo) {
        return;
      }

      var axisPointerModel = axisInfo.axisPointerModel;
      var scale = axisInfo.axis.scale;
      var option = axisPointerModel.option;
      var status = axisPointerModel.get('status');
      var value = axisPointerModel.get('value'); // Parse init value for category and time axis.

      if (value != null) {
        value = scale.parse(value);
      }

      var useHandle = isHandleTrigger(axisPointerModel); // If `handle` used, `axisPointer` will always be displayed, so value
      // and status should be initialized.

      if (status == null) {
        option.status = useHandle ? 'show' : 'hide';
      }

      var extent = scale.getExtent().slice();
      extent[0] > extent[1] && extent.reverse();

      if ( // Pick a value on axis when initializing.
      value == null // If both `handle` and `dataZoom` are used, value may be out of axis extent,
      // where we should re-pick a value to keep `handle` displaying normally.
      || value > extent[1]) {
        // Make handle displayed on the end of the axis when init, which looks better.
        value = extent[1];
      }

      if (value < extent[0]) {
        value = extent[0];
      }

      option.value = value;

      if (useHandle) {
        option.status = axisInfo.axis.scale.isBlank() ? 'hide' : 'show';
      }
    }
    function getAxisInfo(axisModel) {
      var coordSysAxesInfo = (axisModel.ecModel.getComponent('axisPointer') || {}).coordSysAxesInfo;
      return coordSysAxesInfo && coordSysAxesInfo.axesInfo[makeKey(axisModel)];
    }
    function getAxisPointerModel(axisModel) {
      var axisInfo = getAxisInfo(axisModel);
      return axisInfo && axisInfo.axisPointerModel;
    }

    function isHandleTrigger(axisPointerModel) {
      return !!axisPointerModel.get(['handle', 'show']);
    }
    /**
     * @param {module:echarts/model/Model} model
     * @return {string} unique key
     */


    function makeKey(model) {
      return model.type + '||' + model.id;
    }

    var axisPointerClazz = {};
    /**
     * Base class of AxisView.
     */

    var AxisView =
    /** @class */
    function (_super) {
      __extends(AxisView, _super);

      function AxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AxisView.type;
        return _this;
      }
      /**
       * @override
       */


      AxisView.prototype.render = function (axisModel, ecModel, api, payload) {
        // FIXME
        // This process should proformed after coordinate systems updated
        // (axis scale updated), and should be performed each time update.
        // So put it here temporarily, although it is not appropriate to
        // put a model-writing procedure in `view`.
        this.axisPointerClass && fixValue(axisModel);

        _super.prototype.render.apply(this, arguments);

        this._doUpdateAxisPointerClass(axisModel, api, true);
      };
      /**
       * Action handler.
       */


      AxisView.prototype.updateAxisPointer = function (axisModel, ecModel, api, payload) {
        this._doUpdateAxisPointerClass(axisModel, api, false);
      };
      /**
       * @override
       */


      AxisView.prototype.remove = function (ecModel, api) {
        var axisPointer = this._axisPointer;
        axisPointer && axisPointer.remove(api);
      };
      /**
       * @override
       */


      AxisView.prototype.dispose = function (ecModel, api) {
        this._disposeAxisPointer(api);

        _super.prototype.dispose.apply(this, arguments);
      };

      AxisView.prototype._doUpdateAxisPointerClass = function (axisModel, api, forceRender) {
        var Clazz = AxisView.getAxisPointerClass(this.axisPointerClass);

        if (!Clazz) {
          return;
        }

        var axisPointerModel = getAxisPointerModel(axisModel);
        axisPointerModel ? (this._axisPointer || (this._axisPointer = new Clazz())).render(axisModel, axisPointerModel, api, forceRender) : this._disposeAxisPointer(api);
      };

      AxisView.prototype._disposeAxisPointer = function (api) {
        this._axisPointer && this._axisPointer.dispose(api);
        this._axisPointer = null;
      };

      AxisView.registerAxisPointerClass = function (type, clazz) {
        if ("development" !== 'production') {
          if (axisPointerClazz[type]) {
            throw new Error('axisPointer ' + type + ' exists');
          }
        }

        axisPointerClazz[type] = clazz;
      };

      AxisView.getAxisPointerClass = function (type) {
        return type && axisPointerClazz[type];
      };
      AxisView.type = 'axis';
      return AxisView;
    }(ComponentView);

    var inner$6 = makeInner();
    function rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel) {
      var axis = axisModel.axis;

      if (axis.scale.isBlank()) {
        return;
      } // TODO: TYPE


      var splitAreaModel = axisModel.getModel('splitArea');
      var areaStyleModel = splitAreaModel.getModel('areaStyle');
      var areaColors = areaStyleModel.get('color');
      var gridRect = gridModel.coordinateSystem.getRect();
      var ticksCoords = axis.getTicksCoords({
        tickModel: splitAreaModel,
        clamp: true
      });

      if (!ticksCoords.length) {
        return;
      } // For Making appropriate splitArea animation, the color and anid
      // should be corresponding to previous one if possible.


      var areaColorsLen = areaColors.length;
      var lastSplitAreaColors = inner$6(axisView).splitAreaColors;
      var newSplitAreaColors = createHashMap();
      var colorIndex = 0;

      if (lastSplitAreaColors) {
        for (var i = 0; i < ticksCoords.length; i++) {
          var cIndex = lastSplitAreaColors.get(ticksCoords[i].tickValue);

          if (cIndex != null) {
            colorIndex = (cIndex + (areaColorsLen - 1) * i) % areaColorsLen;
            break;
          }
        }
      }

      var prev = axis.toGlobalCoord(ticksCoords[0].coord);
      var areaStyle = areaStyleModel.getAreaStyle();
      areaColors = isArray(areaColors) ? areaColors : [areaColors];

      for (var i = 1; i < ticksCoords.length; i++) {
        var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);
        var x = void 0;
        var y = void 0;
        var width = void 0;
        var height = void 0;

        if (axis.isHorizontal()) {
          x = prev;
          y = gridRect.y;
          width = tickCoord - x;
          height = gridRect.height;
          prev = x + width;
        } else {
          x = gridRect.x;
          y = prev;
          width = gridRect.width;
          height = tickCoord - y;
          prev = y + height;
        }

        var tickValue = ticksCoords[i - 1].tickValue;
        tickValue != null && newSplitAreaColors.set(tickValue, colorIndex);
        axisGroup.add(new Rect({
          anid: tickValue != null ? 'area_' + tickValue : null,
          shape: {
            x: x,
            y: y,
            width: width,
            height: height
          },
          style: defaults({
            fill: areaColors[colorIndex]
          }, areaStyle),
          autoBatch: true,
          silent: true
        }));
        colorIndex = (colorIndex + 1) % areaColorsLen;
      }

      inner$6(axisView).splitAreaColors = newSplitAreaColors;
    }
    function rectCoordAxisHandleRemove(axisView) {
      inner$6(axisView).splitAreaColors = null;
    }

    var axisBuilderAttrs = ['axisLine', 'axisTickLabel', 'axisName'];
    var selfBuilderAttrs = ['splitArea', 'splitLine', 'minorSplitLine'];

    var CartesianAxisView =
    /** @class */
    function (_super) {
      __extends(CartesianAxisView, _super);

      function CartesianAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CartesianAxisView.type;
        _this.axisPointerClass = 'CartesianAxisPointer';
        return _this;
      }
      /**
       * @override
       */


      CartesianAxisView.prototype.render = function (axisModel, ecModel, api, payload) {
        this.group.removeAll();
        var oldAxisGroup = this._axisGroup;
        this._axisGroup = new Group();
        this.group.add(this._axisGroup);

        if (!axisModel.get('show')) {
          return;
        }

        var gridModel = axisModel.getCoordSysModel();
        var layout = layout$1(gridModel, axisModel);
        var axisBuilder = new AxisBuilder(axisModel, extend({
          handleAutoShown: function (elementType) {
            var cartesians = gridModel.coordinateSystem.getCartesians();

            for (var i = 0; i < cartesians.length; i++) {
              if (isIntervalOrLogScale(cartesians[i].getOtherAxis(axisModel.axis).scale)) {
                // Still show axis tick or axisLine if other axis is value / log
                return true;
              }
            } // Not show axisTick or axisLine if other axis is category / time


            return false;
          }
        }, layout));
        each(axisBuilderAttrs, axisBuilder.add, axisBuilder);

        this._axisGroup.add(axisBuilder.getGroup());

        each(selfBuilderAttrs, function (name) {
          if (axisModel.get([name, 'show'])) {
            axisElementBuilders[name](this, this._axisGroup, axisModel, gridModel);
          }
        }, this); // THIS is a special case for bar racing chart.
        // Update the axis label from the natural initial layout to
        // sorted layout should has no animation.

        var isInitialSortFromBarRacing = payload && payload.type === 'changeAxisOrder' && payload.isInitSort;

        if (!isInitialSortFromBarRacing) {
          groupTransition(oldAxisGroup, this._axisGroup, axisModel);
        }

        _super.prototype.render.call(this, axisModel, ecModel, api, payload);
      };

      CartesianAxisView.prototype.remove = function () {
        rectCoordAxisHandleRemove(this);
      };

      CartesianAxisView.type = 'cartesianAxis';
      return CartesianAxisView;
    }(AxisView);

    var axisElementBuilders = {
      splitLine: function (axisView, axisGroup, axisModel, gridModel) {
        var axis = axisModel.axis;

        if (axis.scale.isBlank()) {
          return;
        }

        var splitLineModel = axisModel.getModel('splitLine');
        var lineStyleModel = splitLineModel.getModel('lineStyle');
        var lineColors = lineStyleModel.get('color');
        lineColors = isArray(lineColors) ? lineColors : [lineColors];
        var gridRect = gridModel.coordinateSystem.getRect();
        var isHorizontal = axis.isHorizontal();
        var lineCount = 0;
        var ticksCoords = axis.getTicksCoords({
          tickModel: splitLineModel
        });
        var p1 = [];
        var p2 = [];
        var lineStyle = lineStyleModel.getLineStyle();

        for (var i = 0; i < ticksCoords.length; i++) {
          var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);

          if (isHorizontal) {
            p1[0] = tickCoord;
            p1[1] = gridRect.y;
            p2[0] = tickCoord;
            p2[1] = gridRect.y + gridRect.height;
          } else {
            p1[0] = gridRect.x;
            p1[1] = tickCoord;
            p2[0] = gridRect.x + gridRect.width;
            p2[1] = tickCoord;
          }

          var colorIndex = lineCount++ % lineColors.length;
          var tickValue = ticksCoords[i].tickValue;
          var line = new Line({
            anid: tickValue != null ? 'line_' + ticksCoords[i].tickValue : null,
            autoBatch: true,
            shape: {
              x1: p1[0],
              y1: p1[1],
              x2: p2[0],
              y2: p2[1]
            },
            style: defaults({
              stroke: lineColors[colorIndex]
            }, lineStyle),
            silent: true
          });
          subPixelOptimizeLine$1(line.shape, lineStyle.lineWidth);
          axisGroup.add(line);
        }
      },
      minorSplitLine: function (axisView, axisGroup, axisModel, gridModel) {
        var axis = axisModel.axis;
        var minorSplitLineModel = axisModel.getModel('minorSplitLine');
        var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
        var gridRect = gridModel.coordinateSystem.getRect();
        var isHorizontal = axis.isHorizontal();
        var minorTicksCoords = axis.getMinorTicksCoords();

        if (!minorTicksCoords.length) {
          return;
        }

        var p1 = [];
        var p2 = [];
        var lineStyle = lineStyleModel.getLineStyle();

        for (var i = 0; i < minorTicksCoords.length; i++) {
          for (var k = 0; k < minorTicksCoords[i].length; k++) {
            var tickCoord = axis.toGlobalCoord(minorTicksCoords[i][k].coord);

            if (isHorizontal) {
              p1[0] = tickCoord;
              p1[1] = gridRect.y;
              p2[0] = tickCoord;
              p2[1] = gridRect.y + gridRect.height;
            } else {
              p1[0] = gridRect.x;
              p1[1] = tickCoord;
              p2[0] = gridRect.x + gridRect.width;
              p2[1] = tickCoord;
            }

            var line = new Line({
              anid: 'minor_line_' + minorTicksCoords[i][k].tickValue,
              autoBatch: true,
              shape: {
                x1: p1[0],
                y1: p1[1],
                x2: p2[0],
                y2: p2[1]
              },
              style: lineStyle,
              silent: true
            });
            subPixelOptimizeLine$1(line.shape, lineStyle.lineWidth);
            axisGroup.add(line);
          }
        }
      },
      splitArea: function (axisView, axisGroup, axisModel, gridModel) {
        rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel);
      }
    };

    var CartesianXAxisView =
    /** @class */
    function (_super) {
      __extends(CartesianXAxisView, _super);

      function CartesianXAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CartesianXAxisView.type;
        return _this;
      }

      CartesianXAxisView.type = 'xAxis';
      return CartesianXAxisView;
    }(CartesianAxisView);

    var CartesianYAxisView =
    /** @class */
    function (_super) {
      __extends(CartesianYAxisView, _super);

      function CartesianYAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CartesianXAxisView.type;
        return _this;
      }

      CartesianYAxisView.type = 'yAxis';
      return CartesianYAxisView;
    }(CartesianAxisView);

    var GridView =
    /** @class */
    function (_super) {
      __extends(GridView, _super);

      function GridView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'grid';
        return _this;
      }

      GridView.prototype.render = function (gridModel, ecModel) {
        this.group.removeAll();

        if (gridModel.get('show')) {
          this.group.add(new Rect({
            shape: gridModel.coordinateSystem.getRect(),
            style: defaults({
              fill: gridModel.get('backgroundColor')
            }, gridModel.getItemStyle()),
            silent: true,
            z2: -1
          }));
        }
      };

      GridView.type = 'grid';
      return GridView;
    }(ComponentView);

    var extraOption = {
      // gridIndex: 0,
      // gridId: '',
      offset: 0
    };
    function install$5(registers) {
      registers.registerComponentView(GridView);
      registers.registerComponentModel(GridModel);
      registers.registerCoordinateSystem('cartesian2d', Grid);
      axisModelCreator(registers, 'x', CartesianAxisModel, extraOption);
      axisModelCreator(registers, 'y', CartesianAxisModel, extraOption);
      registers.registerComponentView(CartesianXAxisView);
      registers.registerComponentView(CartesianYAxisView);
      registers.registerPreprocessor(function (option) {
        // Only create grid when need
        if (option.xAxis && option.yAxis && !option.grid) {
          option.grid = {};
        }
      });
    }

    function install$6(registers) {
      // In case developer forget to include grid component
      use(install$5);
      registers.registerSeriesModel(ScatterSeriesModel);
      registers.registerChartView(ScatterView);
      registers.registerLayout(pointsLayout('scatter'));
    }

    var inner$7 = makeInner();
    var clone$3 = clone;
    var bind$1 = bind;
    /**
     * Base axis pointer class in 2D.
     */

    var BaseAxisPointer =
    /** @class */
    function () {
      function BaseAxisPointer() {
        this._dragging = false;
        /**
         * In px, arbitrary value. Do not set too small,
         * no animation is ok for most cases.
         */

        this.animationThreshold = 15;
      }
      /**
       * @implement
       */


      BaseAxisPointer.prototype.render = function (axisModel, axisPointerModel, api, forceRender) {
        var value = axisPointerModel.get('value');
        var status = axisPointerModel.get('status'); // Bind them to `this`, not in closure, otherwise they will not
        // be replaced when user calling setOption in not merge mode.

        this._axisModel = axisModel;
        this._axisPointerModel = axisPointerModel;
        this._api = api; // Optimize: `render` will be called repeatly during mouse move.
        // So it is power consuming if performing `render` each time,
        // especially on mobile device.

        if (!forceRender && this._lastValue === value && this._lastStatus === status) {
          return;
        }

        this._lastValue = value;
        this._lastStatus = status;
        var group = this._group;
        var handle = this._handle;

        if (!status || status === 'hide') {
          // Do not clear here, for animation better.
          group && group.hide();
          handle && handle.hide();
          return;
        }

        group && group.show();
        handle && handle.show(); // Otherwise status is 'show'

        var elOption = {};
        this.makeElOption(elOption, value, axisModel, axisPointerModel, api); // Enable change axis pointer type.

        var graphicKey = elOption.graphicKey;

        if (graphicKey !== this._lastGraphicKey) {
          this.clear(api);
        }

        this._lastGraphicKey = graphicKey;
        var moveAnimation = this._moveAnimation = this.determineAnimation(axisModel, axisPointerModel);

        if (!group) {
          group = this._group = new Group();
          this.createPointerEl(group, elOption, axisModel, axisPointerModel);
          this.createLabelEl(group, elOption, axisModel, axisPointerModel);
          api.getZr().add(group);
        } else {
          var doUpdateProps = curry(updateProps$1, axisPointerModel, moveAnimation);
          this.updatePointerEl(group, elOption, doUpdateProps);
          this.updateLabelEl(group, elOption, doUpdateProps, axisPointerModel);
        }

        updateMandatoryProps(group, axisPointerModel, true);

        this._renderHandle(value);
      };
      /**
       * @implement
       */


      BaseAxisPointer.prototype.remove = function (api) {
        this.clear(api);
      };
      /**
       * @implement
       */


      BaseAxisPointer.prototype.dispose = function (api) {
        this.clear(api);
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.determineAnimation = function (axisModel, axisPointerModel) {
        var animation = axisPointerModel.get('animation');
        var axis = axisModel.axis;
        var isCategoryAxis = axis.type === 'category';
        var useSnap = axisPointerModel.get('snap'); // Value axis without snap always do not snap.

        if (!useSnap && !isCategoryAxis) {
          return false;
        }

        if (animation === 'auto' || animation == null) {
          var animationThreshold = this.animationThreshold;

          if (isCategoryAxis && axis.getBandWidth() > animationThreshold) {
            return true;
          } // It is important to auto animation when snap used. Consider if there is
          // a dataZoom, animation will be disabled when too many points exist, while
          // it will be enabled for better visual effect when little points exist.


          if (useSnap) {
            var seriesDataCount = getAxisInfo(axisModel).seriesDataCount;
            var axisExtent = axis.getExtent(); // Approximate band width

            return Math.abs(axisExtent[0] - axisExtent[1]) / seriesDataCount > animationThreshold;
          }

          return false;
        }

        return animation === true;
      };
      /**
       * add {pointer, label, graphicKey} to elOption
       * @protected
       */


      BaseAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) {// Shoule be implemenented by sub-class.
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.createPointerEl = function (group, elOption, axisModel, axisPointerModel) {
        var pointerOption = elOption.pointer;

        if (pointerOption) {
          var pointerEl = inner$7(group).pointerEl = new graphic[pointerOption.type](clone$3(elOption.pointer));
          group.add(pointerEl);
        }
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.createLabelEl = function (group, elOption, axisModel, axisPointerModel) {
        if (elOption.label) {
          var labelEl = inner$7(group).labelEl = new ZRText(clone$3(elOption.label));
          group.add(labelEl);
          updateLabelShowHide(labelEl, axisPointerModel);
        }
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.updatePointerEl = function (group, elOption, updateProps) {
        var pointerEl = inner$7(group).pointerEl;

        if (pointerEl && elOption.pointer) {
          pointerEl.setStyle(elOption.pointer.style);
          updateProps(pointerEl, {
            shape: elOption.pointer.shape
          });
        }
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.updateLabelEl = function (group, elOption, updateProps, axisPointerModel) {
        var labelEl = inner$7(group).labelEl;

        if (labelEl) {
          labelEl.setStyle(elOption.label.style);
          updateProps(labelEl, {
            // Consider text length change in vertical axis, animation should
            // be used on shape, otherwise the effect will be weird.
            // TODOTODO
            // shape: elOption.label.shape,
            x: elOption.label.x,
            y: elOption.label.y
          });
          updateLabelShowHide(labelEl, axisPointerModel);
        }
      };
      /**
       * @private
       */


      BaseAxisPointer.prototype._renderHandle = function (value) {
        if (this._dragging || !this.updateHandleTransform) {
          return;
        }

        var axisPointerModel = this._axisPointerModel;

        var zr = this._api.getZr();

        var handle = this._handle;
        var handleModel = axisPointerModel.getModel('handle');
        var status = axisPointerModel.get('status');

        if (!handleModel.get('show') || !status || status === 'hide') {
          handle && zr.remove(handle);
          this._handle = null;
          return;
        }

        var isInit;

        if (!this._handle) {
          isInit = true;
          handle = this._handle = createIcon(handleModel.get('icon'), {
            cursor: 'move',
            draggable: true,
            onmousemove: function (e) {
              // Fot mobile devicem, prevent screen slider on the button.
              stop(e.event);
            },
            onmousedown: bind$1(this._onHandleDragMove, this, 0, 0),
            drift: bind$1(this._onHandleDragMove, this),
            ondragend: bind$1(this._onHandleDragEnd, this)
          });
          zr.add(handle);
        }

        updateMandatoryProps(handle, axisPointerModel, false); // update style

        handle.setStyle(handleModel.getItemStyle(null, ['color', 'borderColor', 'borderWidth', 'opacity', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'])); // update position

        var handleSize = handleModel.get('size');

        if (!isArray(handleSize)) {
          handleSize = [handleSize, handleSize];
        }

        handle.scaleX = handleSize[0] / 2;
        handle.scaleY = handleSize[1] / 2;
        createOrUpdate(this, '_doDispatchAxisPointer', handleModel.get('throttle') || 0, 'fixRate');

        this._moveHandleToValue(value, isInit);
      };

      BaseAxisPointer.prototype._moveHandleToValue = function (value, isInit) {
        updateProps$1(this._axisPointerModel, !isInit && this._moveAnimation, this._handle, getHandleTransProps(this.getHandleTransform(value, this._axisModel, this._axisPointerModel)));
      };

      BaseAxisPointer.prototype._onHandleDragMove = function (dx, dy) {
        var handle = this._handle;

        if (!handle) {
          return;
        }

        this._dragging = true; // Persistent for throttle.

        var trans = this.updateHandleTransform(getHandleTransProps(handle), [dx, dy], this._axisModel, this._axisPointerModel);
        this._payloadInfo = trans;
        handle.stopAnimation();
        handle.attr(getHandleTransProps(trans));
        inner$7(handle).lastProp = null;

        this._doDispatchAxisPointer();
      };
      /**
       * Throttled method.
       */


      BaseAxisPointer.prototype._doDispatchAxisPointer = function () {
        var handle = this._handle;

        if (!handle) {
          return;
        }

        var payloadInfo = this._payloadInfo;
        var axisModel = this._axisModel;

        this._api.dispatchAction({
          type: 'updateAxisPointer',
          x: payloadInfo.cursorPoint[0],
          y: payloadInfo.cursorPoint[1],
          tooltipOption: payloadInfo.tooltipOption,
          axesInfo: [{
            axisDim: axisModel.axis.dim,
            axisIndex: axisModel.componentIndex
          }]
        });
      };

      BaseAxisPointer.prototype._onHandleDragEnd = function () {
        this._dragging = false;
        var handle = this._handle;

        if (!handle) {
          return;
        }

        var value = this._axisPointerModel.get('value'); // Consider snap or categroy axis, handle may be not consistent with
        // axisPointer. So move handle to align the exact value position when
        // drag ended.


        this._moveHandleToValue(value); // For the effect: tooltip will be shown when finger holding on handle
        // button, and will be hidden after finger left handle button.


        this._api.dispatchAction({
          type: 'hideTip'
        });
      };
      /**
       * @private
       */


      BaseAxisPointer.prototype.clear = function (api) {
        this._lastValue = null;
        this._lastStatus = null;
        var zr = api.getZr();
        var group = this._group;
        var handle = this._handle;

        if (zr && group) {
          this._lastGraphicKey = null;
          group && zr.remove(group);
          handle && zr.remove(handle);
          this._group = null;
          this._handle = null;
          this._payloadInfo = null;
        }

        clear(this, '_doDispatchAxisPointer');
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.doClear = function () {// Implemented by sub-class if necessary.
      };

      BaseAxisPointer.prototype.buildLabel = function (xy, wh, xDimIndex) {
        xDimIndex = xDimIndex || 0;
        return {
          x: xy[xDimIndex],
          y: xy[1 - xDimIndex],
          width: wh[xDimIndex],
          height: wh[1 - xDimIndex]
        };
      };

      return BaseAxisPointer;
    }();

    function updateProps$1(animationModel, moveAnimation, el, props) {
      // Animation optimize.
      if (!propsEqual(inner$7(el).lastProp, props)) {
        inner$7(el).lastProp = props;
        moveAnimation ? updateProps(el, props, animationModel) : (el.stopAnimation(), el.attr(props));
      }
    }

    function propsEqual(lastProps, newProps) {
      if (isObject(lastProps) && isObject(newProps)) {
        var equals_1 = true;
        each(newProps, function (item, key) {
          equals_1 = equals_1 && propsEqual(lastProps[key], item);
        });
        return !!equals_1;
      } else {
        return lastProps === newProps;
      }
    }

    function updateLabelShowHide(labelEl, axisPointerModel) {
      labelEl[axisPointerModel.get(['label', 'show']) ? 'show' : 'hide']();
    }

    function getHandleTransProps(trans) {
      return {
        x: trans.x || 0,
        y: trans.y || 0,
        rotation: trans.rotation || 0
      };
    }

    function updateMandatoryProps(group, axisPointerModel, silent) {
      var z = axisPointerModel.get('z');
      var zlevel = axisPointerModel.get('zlevel');
      group && group.traverse(function (el) {
        if (el.type !== 'group') {
          z != null && (el.z = z);
          zlevel != null && (el.zlevel = zlevel);
          el.silent = silent;
        }
      });
    }

    function buildElStyle(axisPointerModel) {
      var axisPointerType = axisPointerModel.get('type');
      var styleModel = axisPointerModel.getModel(axisPointerType + 'Style');
      var style;

      if (axisPointerType === 'line') {
        style = styleModel.getLineStyle();
        style.fill = null;
      } else if (axisPointerType === 'shadow') {
        style = styleModel.getAreaStyle();
        style.stroke = null;
      }

      return style;
    }
    /**
     * @param {Function} labelPos {align, verticalAlign, position}
     */

    function buildLabelElOption(elOption, axisModel, axisPointerModel, api, labelPos) {
      var value = axisPointerModel.get('value');
      var text = getValueLabel(value, axisModel.axis, axisModel.ecModel, axisPointerModel.get('seriesDataIndices'), {
        precision: axisPointerModel.get(['label', 'precision']),
        formatter: axisPointerModel.get(['label', 'formatter'])
      });
      var labelModel = axisPointerModel.getModel('label');
      var paddings = normalizeCssArray$1(labelModel.get('padding') || 0);
      var font = labelModel.getFont();
      var textRect = getBoundingRect(text, font);
      var position = labelPos.position;
      var width = textRect.width + paddings[1] + paddings[3];
      var height = textRect.height + paddings[0] + paddings[2]; // Adjust by align.

      var align = labelPos.align;
      align === 'right' && (position[0] -= width);
      align === 'center' && (position[0] -= width / 2);
      var verticalAlign = labelPos.verticalAlign;
      verticalAlign === 'bottom' && (position[1] -= height);
      verticalAlign === 'middle' && (position[1] -= height / 2); // Not overflow ec container

      confineInContainer(position, width, height, api);
      var bgColor = labelModel.get('backgroundColor');

      if (!bgColor || bgColor === 'auto') {
        bgColor = axisModel.get(['axisLine', 'lineStyle', 'color']);
      }

      elOption.label = {
        // shape: {x: 0, y: 0, width: width, height: height, r: labelModel.get('borderRadius')},
        x: position[0],
        y: position[1],
        style: createTextStyle(labelModel, {
          text: text,
          font: font,
          fill: labelModel.getTextColor(),
          padding: paddings,
          backgroundColor: bgColor
        }),
        // Lable should be over axisPointer.
        z2: 10
      };
    } // Do not overflow ec container

    function confineInContainer(position, width, height, api) {
      var viewWidth = api.getWidth();
      var viewHeight = api.getHeight();
      position[0] = Math.min(position[0] + width, viewWidth) - width;
      position[1] = Math.min(position[1] + height, viewHeight) - height;
      position[0] = Math.max(position[0], 0);
      position[1] = Math.max(position[1], 0);
    }

    function getValueLabel(value, axis, ecModel, seriesDataIndices, opt) {
      value = axis.scale.parse(value);
      var text = axis.scale.getLabel({
        value: value
      }, {
        // If `precision` is set, width can be fixed (like '12.00500'), which
        // helps to debounce when when moving label.
        precision: opt.precision
      });
      var formatter = opt.formatter;

      if (formatter) {
        var params_1 = {
          value: getAxisRawValue(axis, {
            value: value
          }),
          axisDimension: axis.dim,
          axisIndex: axis.index,
          seriesData: []
        };
        each(seriesDataIndices, function (idxItem) {
          var series = ecModel.getSeriesByIndex(idxItem.seriesIndex);
          var dataIndex = idxItem.dataIndexInside;
          var dataParams = series && series.getDataParams(dataIndex);
          dataParams && params_1.seriesData.push(dataParams);
        });

        if (isString(formatter)) {
          text = formatter.replace('{value}', text);
        } else if (isFunction(formatter)) {
          text = formatter(params_1);
        }
      }

      return text;
    }
    function getTransformedPosition(axis, value, layoutInfo) {
      var transform = create$1();
      rotate(transform, transform, layoutInfo.rotation);
      translate(transform, transform, layoutInfo.position);
      return applyTransform$1([axis.dataToCoord(value), (layoutInfo.labelOffset || 0) + (layoutInfo.labelDirection || 1) * (layoutInfo.labelMargin || 0)], transform);
    }
    function buildCartesianSingleLabelElOption(value, elOption, layoutInfo, axisModel, axisPointerModel, api) {
      // @ts-ignore
      var textLayout = AxisBuilder.innerTextLayout(layoutInfo.rotation, 0, layoutInfo.labelDirection);
      layoutInfo.labelMargin = axisPointerModel.get(['label', 'margin']);
      buildLabelElOption(elOption, axisModel, axisPointerModel, api, {
        position: getTransformedPosition(axisModel.axis, value, layoutInfo),
        align: textLayout.textAlign,
        verticalAlign: textLayout.textVerticalAlign
      });
    }
    function makeLineShape(p1, p2, xDimIndex) {
      xDimIndex = xDimIndex || 0;
      return {
        x1: p1[xDimIndex],
        y1: p1[1 - xDimIndex],
        x2: p2[xDimIndex],
        y2: p2[1 - xDimIndex]
      };
    }
    function makeRectShape(xy, wh, xDimIndex) {
      xDimIndex = xDimIndex || 0;
      return {
        x: xy[xDimIndex],
        y: xy[1 - xDimIndex],
        width: wh[xDimIndex],
        height: wh[1 - xDimIndex]
      };
    }

    var CartesianAxisPointer =
    /** @class */
    function (_super) {
      __extends(CartesianAxisPointer, _super);

      function CartesianAxisPointer() {
        return _super !== null && _super.apply(this, arguments) || this;
      }
      /**
       * @override
       */


      CartesianAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) {
        var axis = axisModel.axis;
        var grid = axis.grid;
        var axisPointerType = axisPointerModel.get('type');
        var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent();
        var pixelValue = axis.toGlobalCoord(axis.dataToCoord(value, true));

        if (axisPointerType && axisPointerType !== 'none') {
          var elStyle = buildElStyle(axisPointerModel);
          var pointerOption = pointerShapeBuilder[axisPointerType](axis, pixelValue, otherExtent);
          pointerOption.style = elStyle;
          elOption.graphicKey = pointerOption.type;
          elOption.pointer = pointerOption;
        }

        var layoutInfo = layout$1(grid.model, axisModel);
        buildCartesianSingleLabelElOption( // @ts-ignore
        value, elOption, layoutInfo, axisModel, axisPointerModel, api);
      };
      /**
       * @override
       */


      CartesianAxisPointer.prototype.getHandleTransform = function (value, axisModel, axisPointerModel) {
        var layoutInfo = layout$1(axisModel.axis.grid.model, axisModel, {
          labelInside: false
        }); // @ts-ignore

        layoutInfo.labelMargin = axisPointerModel.get(['handle', 'margin']);
        var pos = getTransformedPosition(axisModel.axis, value, layoutInfo);
        return {
          x: pos[0],
          y: pos[1],
          rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
        };
      };
      /**
       * @override
       */


      CartesianAxisPointer.prototype.updateHandleTransform = function (transform, delta, axisModel, axisPointerModel) {
        var axis = axisModel.axis;
        var grid = axis.grid;
        var axisExtent = axis.getGlobalExtent(true);
        var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent();
        var dimIndex = axis.dim === 'x' ? 0 : 1;
        var currPosition = [transform.x, transform.y];
        currPosition[dimIndex] += delta[dimIndex];
        currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]);
        currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]);
        var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2;
        var cursorPoint = [cursorOtherValue, cursorOtherValue];
        cursorPoint[dimIndex] = currPosition[dimIndex]; // Make tooltip do not overlap axisPointer and in the middle of the grid.

        var tooltipOptions = [{
          verticalAlign: 'middle'
        }, {
          align: 'center'
        }];
        return {
          x: currPosition[0],
          y: currPosition[1],
          rotation: transform.rotation,
          cursorPoint: cursorPoint,
          tooltipOption: tooltipOptions[dimIndex]
        };
      };

      return CartesianAxisPointer;
    }(BaseAxisPointer);

    function getCartesian(grid, axis) {
      var opt = {};
      opt[axis.dim + 'AxisIndex'] = axis.index;
      return grid.getCartesian(opt);
    }

    var pointerShapeBuilder = {
      line: function (axis, pixelValue, otherExtent) {
        var targetShape = makeLineShape([pixelValue, otherExtent[0]], [pixelValue, otherExtent[1]], getAxisDimIndex(axis));
        return {
          type: 'Line',
          subPixelOptimize: true,
          shape: targetShape
        };
      },
      shadow: function (axis, pixelValue, otherExtent) {
        var bandWidth = Math.max(1, axis.getBandWidth());
        var span = otherExtent[1] - otherExtent[0];
        return {
          type: 'Rect',
          shape: makeRectShape([pixelValue - bandWidth / 2, otherExtent[0]], [bandWidth, span], getAxisDimIndex(axis))
        };
      }
    };

    function getAxisDimIndex(axis) {
      return axis.dim === 'x' ? 0 : 1;
    }

    var AxisPointerModel =
    /** @class */
    function (_super) {
      __extends(AxisPointerModel, _super);

      function AxisPointerModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AxisPointerModel.type;
        return _this;
      }

      AxisPointerModel.type = 'axisPointer';
      AxisPointerModel.defaultOption = {
        // 'auto' means that show when triggered by tooltip or handle.
        show: 'auto',
        // zlevel: 0,
        z: 50,
        type: 'line',
        // axispointer triggered by tootip determine snap automatically,
        // see `modelHelper`.
        snap: false,
        triggerTooltip: true,
        value: null,
        status: null,
        link: [],
        // Do not set 'auto' here, otherwise global animation: false
        // will not effect at this axispointer.
        animation: null,
        animationDurationUpdate: 200,
        lineStyle: {
          color: '#B9BEC9',
          width: 1,
          type: 'dashed'
        },
        shadowStyle: {
          color: 'rgba(210,219,238,0.2)'
        },
        label: {
          show: true,
          formatter: null,
          precision: 'auto',
          margin: 3,
          color: '#fff',
          padding: [5, 7, 5, 7],
          backgroundColor: 'auto',
          borderColor: null,
          borderWidth: 0,
          borderRadius: 3
        },
        handle: {
          show: false,
          // eslint-disable-next-line
          icon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z',
          size: 45,
          // handle margin is from symbol center to axis, which is stable when circular move.
          margin: 50,
          // color: '#1b8bbd'
          // color: '#2f4554'
          color: '#333',
          shadowBlur: 3,
          shadowColor: '#aaa',
          shadowOffsetX: 0,
          shadowOffsetY: 2,
          // For mobile performance
          throttle: 40
        }
      };
      return AxisPointerModel;
    }(ComponentModel);

    var inner$8 = makeInner();
    var each$3 = each;
    /**
     * @param {string} key
     * @param {module:echarts/ExtensionAPI} api
     * @param {Function} handler
     *      param: {string} currTrigger
     *      param: {Array.<number>} point
     */

    function register(key, api, handler) {
      if (env.node) {
        return;
      }

      var zr = api.getZr();
      inner$8(zr).records || (inner$8(zr).records = {});
      initGlobalListeners(zr, api);
      var record = inner$8(zr).records[key] || (inner$8(zr).records[key] = {});
      record.handler = handler;
    }

    function initGlobalListeners(zr, api) {
      if (inner$8(zr).initialized) {
        return;
      }

      inner$8(zr).initialized = true;
      useHandler('click', curry(doEnter, 'click'));
      useHandler('mousemove', curry(doEnter, 'mousemove')); // useHandler('mouseout', onLeave);

      useHandler('globalout', onLeave);

      function useHandler(eventType, cb) {
        zr.on(eventType, function (e) {
          var dis = makeDispatchAction(api);
          each$3(inner$8(zr).records, function (record) {
            record && cb(record, e, dis.dispatchAction);
          });
          dispatchTooltipFinally(dis.pendings, api);
        });
      }
    }

    function dispatchTooltipFinally(pendings, api) {
      var showLen = pendings.showTip.length;
      var hideLen = pendings.hideTip.length;
      var actuallyPayload;

      if (showLen) {
        actuallyPayload = pendings.showTip[showLen - 1];
      } else if (hideLen) {
        actuallyPayload = pendings.hideTip[hideLen - 1];
      }

      if (actuallyPayload) {
        actuallyPayload.dispatchAction = null;
        api.dispatchAction(actuallyPayload);
      }
    }

    function onLeave(record, e, dispatchAction) {
      record.handler('leave', null, dispatchAction);
    }

    function doEnter(currTrigger, record, e, dispatchAction) {
      record.handler(currTrigger, e, dispatchAction);
    }

    function makeDispatchAction(api) {
      var pendings = {
        showTip: [],
        hideTip: []
      }; // FIXME
      // better approach?
      // 'showTip' and 'hideTip' can be triggered by axisPointer and tooltip,
      // which may be conflict, (axisPointer call showTip but tooltip call hideTip);
      // So we have to add "final stage" to merge those dispatched actions.

      var dispatchAction = function (payload) {
        var pendingList = pendings[payload.type];

        if (pendingList) {
          pendingList.push(payload);
        } else {
          payload.dispatchAction = dispatchAction;
          api.dispatchAction(payload);
        }
      };

      return {
        dispatchAction: dispatchAction,
        pendings: pendings
      };
    }

    function unregister(key, api) {
      if (env.node) {
        return;
      }

      var zr = api.getZr();
      var record = (inner$8(zr).records || {})[key];

      if (record) {
        inner$8(zr).records[key] = null;
      }
    }

    var AxisPointerView =
    /** @class */
    function (_super) {
      __extends(AxisPointerView, _super);

      function AxisPointerView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AxisPointerView.type;
        return _this;
      }

      AxisPointerView.prototype.render = function (globalAxisPointerModel, ecModel, api) {
        var globalTooltipModel = ecModel.getComponent('tooltip');
        var triggerOn = globalAxisPointerModel.get('triggerOn') || globalTooltipModel && globalTooltipModel.get('triggerOn') || 'mousemove|click'; // Register global listener in AxisPointerView to enable
        // AxisPointerView to be independent to Tooltip.

        register('axisPointer', api, function (currTrigger, e, dispatchAction) {
          // If 'none', it is not controlled by mouse totally.
          if (triggerOn !== 'none' && (currTrigger === 'leave' || triggerOn.indexOf(currTrigger) >= 0)) {
            dispatchAction({
              type: 'updateAxisPointer',
              currTrigger: currTrigger,
              x: e && e.offsetX,
              y: e && e.offsetY
            });
          }
        });
      };

      AxisPointerView.prototype.remove = function (ecModel, api) {
        unregister('axisPointer', api);
      };

      AxisPointerView.prototype.dispose = function (ecModel, api) {
        unregister('axisPointer', api);
      };

      AxisPointerView.type = 'axisPointer';
      return AxisPointerView;
    }(ComponentView);

    /**
     * @param finder contains {seriesIndex, dataIndex, dataIndexInside}
     * @param ecModel
     * @return  {point: [x, y], el: ...} point Will not be null.
     */

    function findPointFromSeries(finder, ecModel) {
      var point = [];
      var seriesIndex = finder.seriesIndex;
      var seriesModel;

      if (seriesIndex == null || !(seriesModel = ecModel.getSeriesByIndex(seriesIndex))) {
        return {
          point: []
        };
      }

      var data = seriesModel.getData();
      var dataIndex = queryDataIndex(data, finder);

      if (dataIndex == null || dataIndex < 0 || isArray(dataIndex)) {
        return {
          point: []
        };
      }

      var el = data.getItemGraphicEl(dataIndex);
      var coordSys = seriesModel.coordinateSystem;

      if (seriesModel.getTooltipPosition) {
        point = seriesModel.getTooltipPosition(dataIndex) || [];
      } else if (coordSys && coordSys.dataToPoint) {
        if (finder.isStacked) {
          var baseAxis = coordSys.getBaseAxis();
          var valueAxis = coordSys.getOtherAxis(baseAxis);
          var valueAxisDim = valueAxis.dim;
          var baseAxisDim = baseAxis.dim;
          var baseDataOffset = valueAxisDim === 'x' || valueAxisDim === 'radius' ? 1 : 0;
          var baseDim = data.mapDimension(baseAxisDim);
          var stackedData = [];
          stackedData[baseDataOffset] = data.get(baseDim, dataIndex);
          stackedData[1 - baseDataOffset] = data.get(data.getCalculationInfo('stackResultDimension'), dataIndex);
          point = coordSys.dataToPoint(stackedData) || [];
        } else {
          point = coordSys.dataToPoint(data.getValues(map(coordSys.dimensions, function (dim) {
            return data.mapDimension(dim);
          }), dataIndex)) || [];
        }
      } else if (el) {
        // Use graphic bounding rect
        var rect = el.getBoundingRect().clone();
        rect.applyTransform(el.transform);
        point = [rect.x + rect.width / 2, rect.y + rect.height / 2];
      }

      return {
        point: point,
        el: el
      };
    }

    var inner$9 = makeInner();
    /**
     * Basic logic: check all axis, if they do not demand show/highlight,
     * then hide/downplay them.
     *
     * @return content of event obj for echarts.connect.
     */

    function axisTrigger(payload, ecModel, api) {
      var currTrigger = payload.currTrigger;
      var point = [payload.x, payload.y];
      var finder = payload;
      var dispatchAction = payload.dispatchAction || bind(api.dispatchAction, api);
      var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo; // Pending
      // See #6121. But we are not able to reproduce it yet.

      if (!coordSysAxesInfo) {
        return;
      }

      if (illegalPoint(point)) {
        // Used in the default behavior of `connection`: use the sample seriesIndex
        // and dataIndex. And also used in the tooltipView trigger.
        point = findPointFromSeries({
          seriesIndex: finder.seriesIndex,
          // Do not use dataIndexInside from other ec instance.
          // FIXME: auto detect it?
          dataIndex: finder.dataIndex
        }, ecModel).point;
      }

      var isIllegalPoint = illegalPoint(point); // Axis and value can be specified when calling dispatchAction({type: 'updateAxisPointer'}).
      // Notice: In this case, it is difficult to get the `point` (which is necessary to show
      // tooltip, so if point is not given, we just use the point found by sample seriesIndex
      // and dataIndex.

      var inputAxesInfo = finder.axesInfo;
      var axesInfo = coordSysAxesInfo.axesInfo;
      var shouldHide = currTrigger === 'leave' || illegalPoint(point);
      var outputPayload = {};
      var showValueMap = {};
      var dataByCoordSys = {
        list: [],
        map: {}
      };
      var updaters = {
        showPointer: curry(showPointer, showValueMap),
        showTooltip: curry(showTooltip, dataByCoordSys)
      }; // Process for triggered axes.

      each(coordSysAxesInfo.coordSysMap, function (coordSys, coordSysKey) {
        // If a point given, it must be contained by the coordinate system.
        var coordSysContainsPoint = isIllegalPoint || coordSys.containPoint(point);
        each(coordSysAxesInfo.coordSysAxesInfo[coordSysKey], function (axisInfo, key) {
          var axis = axisInfo.axis;
          var inputAxisInfo = findInputAxisInfo(inputAxesInfo, axisInfo); // If no inputAxesInfo, no axis is restricted.

          if (!shouldHide && coordSysContainsPoint && (!inputAxesInfo || inputAxisInfo)) {
            var val = inputAxisInfo && inputAxisInfo.value;

            if (val == null && !isIllegalPoint) {
              val = axis.pointToData(point);
            }

            val != null && processOnAxis(axisInfo, val, updaters, false, outputPayload);
          }
        });
      }); // Process for linked axes.

      var linkTriggers = {};
      each(axesInfo, function (tarAxisInfo, tarKey) {
        var linkGroup = tarAxisInfo.linkGroup; // If axis has been triggered in the previous stage, it should not be triggered by link.

        if (linkGroup && !showValueMap[tarKey]) {
          each(linkGroup.axesInfo, function (srcAxisInfo, srcKey) {
            var srcValItem = showValueMap[srcKey]; // If srcValItem exist, source axis is triggered, so link to target axis.

            if (srcAxisInfo !== tarAxisInfo && srcValItem) {
              var val = srcValItem.value;
              linkGroup.mapper && (val = tarAxisInfo.axis.scale.parse(linkGroup.mapper(val, makeMapperParam(srcAxisInfo), makeMapperParam(tarAxisInfo))));
              linkTriggers[tarAxisInfo.key] = val;
            }
          });
        }
      });
      each(linkTriggers, function (val, tarKey) {
        processOnAxis(axesInfo[tarKey], val, updaters, true, outputPayload);
      });
      updateModelActually(showValueMap, axesInfo, outputPayload);
      dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction);
      dispatchHighDownActually(axesInfo, dispatchAction, api);
      return outputPayload;
    }

    function processOnAxis(axisInfo, newValue, updaters, noSnap, outputFinder) {
      var axis = axisInfo.axis;

      if (axis.scale.isBlank() || !axis.containData(newValue)) {
        return;
      }

      if (!axisInfo.involveSeries) {
        updaters.showPointer(axisInfo, newValue);
        return;
      } // Heavy calculation. So put it after axis.containData checking.


      var payloadInfo = buildPayloadsBySeries(newValue, axisInfo);
      var payloadBatch = payloadInfo.payloadBatch;
      var snapToValue = payloadInfo.snapToValue; // Fill content of event obj for echarts.connect.
      // By default use the first involved series data as a sample to connect.

      if (payloadBatch[0] && outputFinder.seriesIndex == null) {
        extend(outputFinder, payloadBatch[0]);
      } // If no linkSource input, this process is for collecting link
      // target, where snap should not be accepted.


      if (!noSnap && axisInfo.snap) {
        if (axis.containData(snapToValue) && snapToValue != null) {
          newValue = snapToValue;
        }
      }

      updaters.showPointer(axisInfo, newValue, payloadBatch); // Tooltip should always be snapToValue, otherwise there will be
      // incorrect "axis value ~ series value" mapping displayed in tooltip.

      updaters.showTooltip(axisInfo, payloadInfo, snapToValue);
    }

    function buildPayloadsBySeries(value, axisInfo) {
      var axis = axisInfo.axis;
      var dim = axis.dim;
      var snapToValue = value;
      var payloadBatch = [];
      var minDist = Number.MAX_VALUE;
      var minDiff = -1;
      each(axisInfo.seriesModels, function (series, idx) {
        var dataDim = series.getData().mapDimensionsAll(dim);
        var seriesNestestValue;
        var dataIndices;

        if (series.getAxisTooltipData) {
          var result = series.getAxisTooltipData(dataDim, value, axis);
          dataIndices = result.dataIndices;
          seriesNestestValue = result.nestestValue;
        } else {
          dataIndices = series.getData().indicesOfNearest(dataDim[0], value, // Add a threshold to avoid find the wrong dataIndex
          // when data length is not same.
          // false,
          axis.type === 'category' ? 0.5 : null);

          if (!dataIndices.length) {
            return;
          }

          seriesNestestValue = series.getData().get(dataDim[0], dataIndices[0]);
        }

        if (seriesNestestValue == null || !isFinite(seriesNestestValue)) {
          return;
        }

        var diff = value - seriesNestestValue;
        var dist = Math.abs(diff); // Consider category case

        if (dist <= minDist) {
          if (dist < minDist || diff >= 0 && minDiff < 0) {
            minDist = dist;
            minDiff = diff;
            snapToValue = seriesNestestValue;
            payloadBatch.length = 0;
          }

          each(dataIndices, function (dataIndex) {
            payloadBatch.push({
              seriesIndex: series.seriesIndex,
              dataIndexInside: dataIndex,
              dataIndex: series.getData().getRawIndex(dataIndex)
            });
          });
        }
      });
      return {
        payloadBatch: payloadBatch,
        snapToValue: snapToValue
      };
    }

    function showPointer(showValueMap, axisInfo, value, payloadBatch) {
      showValueMap[axisInfo.key] = {
        value: value,
        payloadBatch: payloadBatch
      };
    }

    function showTooltip(dataByCoordSys, axisInfo, payloadInfo, value) {
      var payloadBatch = payloadInfo.payloadBatch;
      var axis = axisInfo.axis;
      var axisModel = axis.model;
      var axisPointerModel = axisInfo.axisPointerModel; // If no data, do not create anything in dataByCoordSys,
      // whose length will be used to judge whether dispatch action.

      if (!axisInfo.triggerTooltip || !payloadBatch.length) {
        return;
      }

      var coordSysModel = axisInfo.coordSys.model;
      var coordSysKey = makeKey(coordSysModel);
      var coordSysItem = dataByCoordSys.map[coordSysKey];

      if (!coordSysItem) {
        coordSysItem = dataByCoordSys.map[coordSysKey] = {
          coordSysId: coordSysModel.id,
          coordSysIndex: coordSysModel.componentIndex,
          coordSysType: coordSysModel.type,
          coordSysMainType: coordSysModel.mainType,
          dataByAxis: []
        };
        dataByCoordSys.list.push(coordSysItem);
      }

      coordSysItem.dataByAxis.push({
        axisDim: axis.dim,
        axisIndex: axisModel.componentIndex,
        axisType: axisModel.type,
        axisId: axisModel.id,
        value: value,
        // Caustion: viewHelper.getValueLabel is actually on "view stage", which
        // depends that all models have been updated. So it should not be performed
        // here. Considering axisPointerModel used here is volatile, which is hard
        // to be retrieve in TooltipView, we prepare parameters here.
        valueLabelOpt: {
          precision: axisPointerModel.get(['label', 'precision']),
          formatter: axisPointerModel.get(['label', 'formatter'])
        },
        seriesDataIndices: payloadBatch.slice()
      });
    }

    function updateModelActually(showValueMap, axesInfo, outputPayload) {
      var outputAxesInfo = outputPayload.axesInfo = []; // Basic logic: If no 'show' required, 'hide' this axisPointer.

      each(axesInfo, function (axisInfo, key) {
        var option = axisInfo.axisPointerModel.option;
        var valItem = showValueMap[key];

        if (valItem) {
          !axisInfo.useHandle && (option.status = 'show');
          option.value = valItem.value; // For label formatter param and highlight.

          option.seriesDataIndices = (valItem.payloadBatch || []).slice();
        } // When always show (e.g., handle used), remain
        // original value and status.
        else {
            // If hide, value still need to be set, consider
            // click legend to toggle axis blank.
            !axisInfo.useHandle && (option.status = 'hide');
          } // If status is 'hide', should be no info in payload.


        option.status === 'show' && outputAxesInfo.push({
          axisDim: axisInfo.axis.dim,
          axisIndex: axisInfo.axis.model.componentIndex,
          value: option.value
        });
      });
    }

    function dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction) {
      // Basic logic: If no showTip required, hideTip will be dispatched.
      if (illegalPoint(point) || !dataByCoordSys.list.length) {
        dispatchAction({
          type: 'hideTip'
        });
        return;
      } // In most case only one axis (or event one series is used). It is
      // convinient to fetch payload.seriesIndex and payload.dataIndex
      // dirtectly. So put the first seriesIndex and dataIndex of the first
      // axis on the payload.


      var sampleItem = ((dataByCoordSys.list[0].dataByAxis[0] || {}).seriesDataIndices || [])[0] || {};
      dispatchAction({
        type: 'showTip',
        escapeConnect: true,
        x: point[0],
        y: point[1],
        tooltipOption: payload.tooltipOption,
        position: payload.position,
        dataIndexInside: sampleItem.dataIndexInside,
        dataIndex: sampleItem.dataIndex,
        seriesIndex: sampleItem.seriesIndex,
        dataByCoordSys: dataByCoordSys.list
      });
    }

    function dispatchHighDownActually(axesInfo, dispatchAction, api) {
      // FIXME
      // highlight status modification shoule be a stage of main process?
      // (Consider confilct (e.g., legend and axisPointer) and setOption)
      var zr = api.getZr();
      var highDownKey = 'axisPointerLastHighlights';
      var lastHighlights = inner$9(zr)[highDownKey] || {};
      var newHighlights = inner$9(zr)[highDownKey] = {}; // Update highlight/downplay status according to axisPointer model.
      // Build hash map and remove duplicate incidentally.

      each(axesInfo, function (axisInfo, key) {
        var option = axisInfo.axisPointerModel.option;
        option.status === 'show' && each(option.seriesDataIndices, function (batchItem) {
          var key = batchItem.seriesIndex + ' | ' + batchItem.dataIndex;
          newHighlights[key] = batchItem;
        });
      }); // Diff.

      var toHighlight = [];
      var toDownplay = [];
      each(lastHighlights, function (batchItem, key) {
        !newHighlights[key] && toDownplay.push(batchItem);
      });
      each(newHighlights, function (batchItem, key) {
        !lastHighlights[key] && toHighlight.push(batchItem);
      });
      toDownplay.length && api.dispatchAction({
        type: 'downplay',
        escapeConnect: true,
        // Not blur others when highlight in axisPointer.
        notBlur: true,
        batch: toDownplay
      });
      toHighlight.length && api.dispatchAction({
        type: 'highlight',
        escapeConnect: true,
        // Not blur others when highlight in axisPointer.
        notBlur: true,
        batch: toHighlight
      });
    }

    function findInputAxisInfo(inputAxesInfo, axisInfo) {
      for (var i = 0; i < (inputAxesInfo || []).length; i++) {
        var inputAxisInfo = inputAxesInfo[i];

        if (axisInfo.axis.dim === inputAxisInfo.axisDim && axisInfo.axis.model.componentIndex === inputAxisInfo.axisIndex) {
          return inputAxisInfo;
        }
      }
    }

    function makeMapperParam(axisInfo) {
      var axisModel = axisInfo.axis.model;
      var item = {};
      var dim = item.axisDim = axisInfo.axis.dim;
      item.axisIndex = item[dim + 'AxisIndex'] = axisModel.componentIndex;
      item.axisName = item[dim + 'AxisName'] = axisModel.name;
      item.axisId = item[dim + 'AxisId'] = axisModel.id;
      return item;
    }

    function illegalPoint(point) {
      return !point || point[0] == null || isNaN(point[0]) || point[1] == null || isNaN(point[1]);
    }

    function install$7(registers) {
      // CartesianAxisPointer is not supposed to be required here. But consider
      // echarts.simple.js and online build tooltip, which only require gridSimple,
      // CartesianAxisPointer should be able to required somewhere.
      AxisView.registerAxisPointerClass('CartesianAxisPointer', CartesianAxisPointer);
      registers.registerComponentModel(AxisPointerModel);
      registers.registerComponentView(AxisPointerView);
      registers.registerPreprocessor(function (option) {
        // Always has a global axisPointerModel for default setting.
        if (option) {
          (!option.axisPointer || option.axisPointer.length === 0) && (option.axisPointer = {});
          var link = option.axisPointer.link; // Normalize to array to avoid object mergin. But if link
          // is not set, remain null/undefined, otherwise it will
          // override existent link setting.

          if (link && !isArray(link)) {
            option.axisPointer.link = [link];
          }
        }
      }); // This process should proformed after coordinate systems created
      // and series data processed. So put it on statistic processing stage.

      registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, function (ecModel, api) {
        // Build axisPointerModel, mergin tooltip.axisPointer model for each axis.
        // allAxesInfo should be updated when setOption performed.
        ecModel.getComponent('axisPointer').coordSysAxesInfo = collect(ecModel, api);
      }); // Broadcast to all views.

      registers.registerAction({
        type: 'updateAxisPointer',
        event: 'updateAxisPointer',
        update: ':updateAxisPointer'
      }, axisTrigger);
    }

    function install$8(registers) {
      use(install$5);
      use(install$7);
    }

    function setKeyInfoToNewElOption(resultItem, newElOption) {
      var existElOption = resultItem.existing; // Set id and type after id assigned.

      newElOption.id = resultItem.keyInfo.id;
      !newElOption.type && existElOption && (newElOption.type = existElOption.type); // Set parent id if not specified

      if (newElOption.parentId == null) {
        var newElParentOption = newElOption.parentOption;

        if (newElParentOption) {
          newElOption.parentId = newElParentOption.id;
        } else if (existElOption) {
          newElOption.parentId = existElOption.parentId;
        }
      } // Clear


      newElOption.parentOption = null;
    }

    function isSetLoc(obj, props) {
      var isSet;
      each(props, function (prop) {
        obj[prop] != null && obj[prop] !== 'auto' && (isSet = true);
      });
      return isSet;
    }

    function mergeNewElOptionToExist(existList, index, newElOption) {
      // Update existing options, for `getOption` feature.
      var newElOptCopy = extend({}, newElOption);
      var existElOption = existList[index];
      var $action = newElOption.$action || 'merge';

      if ($action === 'merge') {
        if (existElOption) {
          if ("development" !== 'production') {
            var newType = newElOption.type;
            assert(!newType || existElOption.type === newType, 'Please set $action: "replace" to change `type`');
          } // We can ensure that newElOptCopy and existElOption are not
          // the same object, so `merge` will not change newElOptCopy.


          merge(existElOption, newElOptCopy, true); // Rigid body, use ignoreSize.

          mergeLayoutParam(existElOption, newElOptCopy, {
            ignoreSize: true
          }); // Will be used in render.

          copyLayoutParams(newElOption, existElOption); // Copy transition info to new option so it can be used in the transition.
          // DO IT AFTER merge

          copyTransitionInfo(newElOption, existElOption);
          copyTransitionInfo(newElOption, existElOption, 'shape');
          copyTransitionInfo(newElOption, existElOption, 'style');
          copyTransitionInfo(newElOption, existElOption, 'extra'); // Copy clipPath

          newElOption.clipPath = existElOption.clipPath;
        } else {
          existList[index] = newElOptCopy;
        }
      } else if ($action === 'replace') {
        existList[index] = newElOptCopy;
      } else if ($action === 'remove') {
        // null will be cleaned later.
        existElOption && (existList[index] = null);
      }
    }

    var TRANSITION_PROPS_TO_COPY = ['transition', 'enterFrom', 'leaveTo'];
    var ROOT_TRANSITION_PROPS_TO_COPY = TRANSITION_PROPS_TO_COPY.concat(['enterAnimation', 'updateAnimation', 'leaveAnimation']);

    function copyTransitionInfo(target, source, targetProp) {
      if (targetProp) {
        if (!target[targetProp] && source[targetProp]) {
          // TODO avoid creating this empty object when there is no transition configuration.
          target[targetProp] = {};
        }

        target = target[targetProp];
        source = source[targetProp];
      }

      if (!target || !source) {
        return;
      }

      var props = targetProp ? TRANSITION_PROPS_TO_COPY : ROOT_TRANSITION_PROPS_TO_COPY;

      for (var i = 0; i < props.length; i++) {
        var prop = props[i];

        if (target[prop] == null && source[prop] != null) {
          target[prop] = source[prop];
        }
      }
    }

    function setLayoutInfoToExist(existItem, newElOption) {
      if (!existItem) {
        return;
      }

      existItem.hv = newElOption.hv = [// Rigid body, don't care about `width`.
      isSetLoc(newElOption, ['left', 'right']), // Rigid body, don't care about `height`.
      isSetLoc(newElOption, ['top', 'bottom'])]; // Give default group size. Otherwise layout error may occur.

      if (existItem.type === 'group') {
        var existingGroupOpt = existItem;
        var newGroupOpt = newElOption;
        existingGroupOpt.width == null && (existingGroupOpt.width = newGroupOpt.width = 0);
        existingGroupOpt.height == null && (existingGroupOpt.height = newGroupOpt.height = 0);
      }
    }

    var GraphicComponentModel =
    /** @class */
    function (_super) {
      __extends(GraphicComponentModel, _super);

      function GraphicComponentModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = GraphicComponentModel.type;
        _this.preventAutoZ = true;
        return _this;
      }

      GraphicComponentModel.prototype.mergeOption = function (option, ecModel) {
        // Prevent default merge to elements
        var elements = this.option.elements;
        this.option.elements = null;

        _super.prototype.mergeOption.call(this, option, ecModel);

        this.option.elements = elements;
      };

      GraphicComponentModel.prototype.optionUpdated = function (newOption, isInit) {
        var thisOption = this.option;
        var newList = (isInit ? thisOption : newOption).elements;
        var existList = thisOption.elements = isInit ? [] : thisOption.elements;
        var flattenedList = [];

        this._flatten(newList, flattenedList, null);

        var mappingResult = mappingToExists(existList, flattenedList, 'normalMerge'); // Clear elOptionsToUpdate

        var elOptionsToUpdate = this._elOptionsToUpdate = [];
        each(mappingResult, function (resultItem, index) {
          var newElOption = resultItem.newOption;

          if ("development" !== 'production') {
            assert(isObject(newElOption) || resultItem.existing, 'Empty graphic option definition');
          }

          if (!newElOption) {
            return;
          }

          elOptionsToUpdate.push(newElOption);
          setKeyInfoToNewElOption(resultItem, newElOption);
          mergeNewElOptionToExist(existList, index, newElOption);
          setLayoutInfoToExist(existList[index], newElOption);
        }, this); // Clean

        thisOption.elements = filter(existList, function (item) {
          // $action should be volatile, otherwise option gotten from
          // `getOption` will contain unexpected $action.
          item && delete item.$action;
          return item != null;
        });
      };
      /**
       * Convert
       * [{
       *  type: 'group',
       *  id: 'xx',
       *  children: [{type: 'circle'}, {type: 'polygon'}]
       * }]
       * to
       * [
       *  {type: 'group', id: 'xx'},
       *  {type: 'circle', parentId: 'xx'},
       *  {type: 'polygon', parentId: 'xx'}
       * ]
       */


      GraphicComponentModel.prototype._flatten = function (optionList, result, parentOption) {
        each(optionList, function (option) {
          if (!option) {
            return;
          }

          if (parentOption) {
            option.parentOption = parentOption;
          }

          result.push(option);
          var children = option.children; // here we don't judge if option.type is `group`
          // when new option doesn't provide `type`, it will cause that the children can't be updated.

          if (children && children.length) {
            this._flatten(children, result, option);
          } // Deleting for JSON output, and for not affecting group creation.


          delete option.children;
        }, this);
      }; // FIXME
      // Pass to view using payload? setOption has a payload?


      GraphicComponentModel.prototype.useElOptionsToUpdate = function () {
        var els = this._elOptionsToUpdate; // Clear to avoid render duplicately when zooming.

        this._elOptionsToUpdate = null;
        return els;
      };

      GraphicComponentModel.type = 'graphic';
      GraphicComponentModel.defaultOption = {
        elements: [] // parentId: null

      };
      return GraphicComponentModel;
    }(ComponentModel);

    /**
     * Whether need to call `convertEC4CompatibleStyle`.
     */

    function isEC4CompatibleStyle(style, elType, hasOwnTextContentOption, hasOwnTextConfig) {
      // Since echarts5, `RectText` is separated from its host element and style.text
      // does not exist any more. The compat work brings some extra burden on performance.
      // So we provide:
      // `legacy: true` force make compat.
      // `legacy: false`, force do not compat.
      // `legacy` not set: auto detect whether legacy.
      //     But in this case we do not compat (difficult to detect and rare case):
      //     Becuse custom series and graphic component support "merge", users may firstly
      //     only set `textStrokeWidth` style or secondly only set `text`.
      return style && (style.legacy || style.legacy !== false && !hasOwnTextContentOption && !hasOwnTextConfig && elType !== 'tspan' // Difficult to detect whether legacy for a "text" el.
      && (elType === 'text' || hasOwn(style, 'text')));
    }
    /**
     * `EC4CompatibleStyle` is style that might be in echarts4 format or echarts5 format.
     * @param hostStyle The properties might be modified.
     * @return If be text el, `textContentStyle` and `textConfig` will not be returned.
     *         Otherwise a `textContentStyle` and `textConfig` will be created, whose props area
     *         retried from the `hostStyle`.
     */

    function convertFromEC4CompatibleStyle(hostStyle, elType, isNormal) {
      var srcStyle = hostStyle;
      var textConfig;
      var textContent;
      var textContentStyle;

      if (elType === 'text') {
        textContentStyle = srcStyle;
      } else {
        textContentStyle = {};
        hasOwn(srcStyle, 'text') && (textContentStyle.text = srcStyle.text);
        hasOwn(srcStyle, 'rich') && (textContentStyle.rich = srcStyle.rich);
        hasOwn(srcStyle, 'textFill') && (textContentStyle.fill = srcStyle.textFill);
        hasOwn(srcStyle, 'textStroke') && (textContentStyle.stroke = srcStyle.textStroke);
        hasOwn(srcStyle, 'fontFamily') && (textContentStyle.fontFamily = srcStyle.fontFamily);
        hasOwn(srcStyle, 'fontSize') && (textContentStyle.fontSize = srcStyle.fontSize);
        hasOwn(srcStyle, 'fontStyle') && (textContentStyle.fontStyle = srcStyle.fontStyle);
        hasOwn(srcStyle, 'fontWeight') && (textContentStyle.fontWeight = srcStyle.fontWeight);
        textContent = {
          type: 'text',
          style: textContentStyle,
          // ec4 does not support rectText trigger.
          // And when text position is different in normal and emphasis
          // => hover text trigger emphasis;
          // => text position changed, leave mouse pointer immediately;
          // That might cause incorrect state.
          silent: true
        };
        textConfig = {};
        var hasOwnPos = hasOwn(srcStyle, 'textPosition');

        if (isNormal) {
          textConfig.position = hasOwnPos ? srcStyle.textPosition : 'inside';
        } else {
          hasOwnPos && (textConfig.position = srcStyle.textPosition);
        }

        hasOwn(srcStyle, 'textPosition') && (textConfig.position = srcStyle.textPosition);
        hasOwn(srcStyle, 'textOffset') && (textConfig.offset = srcStyle.textOffset);
        hasOwn(srcStyle, 'textRotation') && (textConfig.rotation = srcStyle.textRotation);
        hasOwn(srcStyle, 'textDistance') && (textConfig.distance = srcStyle.textDistance);
      }

      convertEC4CompatibleRichItem(textContentStyle, hostStyle);
      each(textContentStyle.rich, function (richItem) {
        convertEC4CompatibleRichItem(richItem, richItem);
      });
      return {
        textConfig: textConfig,
        textContent: textContent
      };
    }
    /**
     * The result will be set to `out`.
     */

    function convertEC4CompatibleRichItem(out, richItem) {
      if (!richItem) {
        return;
      } // (1) For simplicity, make textXXX properties (deprecated since ec5) has
      // higher priority. For example, consider in ec4 `borderColor: 5, textBorderColor: 10`
      // on a rect means `borderColor: 4` on the rect and `borderColor: 10` on an attached
      // richText in ec5.
      // (2) `out === richItem` if and only if `out` is text el or rich item.
      // So we can overwrite existing props in `out` since textXXX has higher priority.


      richItem.font = richItem.textFont || richItem.font;
      hasOwn(richItem, 'textStrokeWidth') && (out.lineWidth = richItem.textStrokeWidth);
      hasOwn(richItem, 'textAlign') && (out.align = richItem.textAlign);
      hasOwn(richItem, 'textVerticalAlign') && (out.verticalAlign = richItem.textVerticalAlign);
      hasOwn(richItem, 'textLineHeight') && (out.lineHeight = richItem.textLineHeight);
      hasOwn(richItem, 'textWidth') && (out.width = richItem.textWidth);
      hasOwn(richItem, 'textHeight') && (out.height = richItem.textHeight);
      hasOwn(richItem, 'textBackgroundColor') && (out.backgroundColor = richItem.textBackgroundColor);
      hasOwn(richItem, 'textPadding') && (out.padding = richItem.textPadding);
      hasOwn(richItem, 'textBorderColor') && (out.borderColor = richItem.textBorderColor);
      hasOwn(richItem, 'textBorderWidth') && (out.borderWidth = richItem.textBorderWidth);
      hasOwn(richItem, 'textBorderRadius') && (out.borderRadius = richItem.textBorderRadius);
      hasOwn(richItem, 'textBoxShadowColor') && (out.shadowColor = richItem.textBoxShadowColor);
      hasOwn(richItem, 'textBoxShadowBlur') && (out.shadowBlur = richItem.textBoxShadowBlur);
      hasOwn(richItem, 'textBoxShadowOffsetX') && (out.shadowOffsetX = richItem.textBoxShadowOffsetX);
      hasOwn(richItem, 'textBoxShadowOffsetY') && (out.shadowOffsetY = richItem.textBoxShadowOffsetY);
    }

    var LEGACY_TRANSFORM_PROPS_MAP = {
      position: ['x', 'y'],
      scale: ['scaleX', 'scaleY'],
      origin: ['originX', 'originY']
    };
    var LEGACY_TRANSFORM_PROPS = keys(LEGACY_TRANSFORM_PROPS_MAP);
    var TRANSFORM_PROPS_MAP = reduce(TRANSFORMABLE_PROPS, function (obj, key) {
      obj[key] = 1;
      return obj;
    }, {});
    var transformPropNamesStr = TRANSFORMABLE_PROPS.join(', '); // '' means root

    var ELEMENT_ANIMATABLE_PROPS = ['', 'style', 'shape', 'extra'];
    var transitionInnerStore = makeInner();

    function getElementAnimationConfig(animationType, el, elOption, parentModel, dataIndex) {
      var animationProp = animationType + "Animation";
      var config = getAnimationConfig(animationType, parentModel, dataIndex) || {};
      var userDuring = transitionInnerStore(el).userDuring; // Only set when duration is > 0 and it's need to be animated.

      if (config.duration > 0) {
        // For simplicity, if during not specified, the previous during will not work any more.
        config.during = userDuring ? bind(duringCall, {
          el: el,
          userDuring: userDuring
        }) : null;
        config.setToFinal = true;
        config.scope = animationType;
      }

      extend(config, elOption[animationProp]);
      return config;
    }

    function applyUpdateTransition(el, elOption, animatableModel, opts) {
      opts = opts || {};
      var dataIndex = opts.dataIndex,
          isInit = opts.isInit,
          clearStyle = opts.clearStyle;
      var hasAnimation = animatableModel.isAnimationEnabled(); // Save the meta info for further morphing. Like apply on the sub morphing elements.

      var store = transitionInnerStore(el);
      var styleOpt = elOption.style;
      store.userDuring = elOption.during;
      var transFromProps = {};
      var propsToSet = {};
      prepareTransformAllPropsFinal(el, elOption, propsToSet);
      prepareShapeOrExtraAllPropsFinal('shape', elOption, propsToSet);
      prepareShapeOrExtraAllPropsFinal('extra', elOption, propsToSet);

      if (!isInit && hasAnimation) {
        prepareTransformTransitionFrom(el, elOption, transFromProps);
        prepareShapeOrExtraTransitionFrom('shape', el, elOption, transFromProps);
        prepareShapeOrExtraTransitionFrom('extra', el, elOption, transFromProps);
        prepareStyleTransitionFrom(el, elOption, styleOpt, transFromProps);
      }

      propsToSet.style = styleOpt;
      applyPropsDirectly(el, propsToSet, clearStyle);
      applyMiscProps(el, elOption);

      if (hasAnimation) {
        if (isInit) {
          var enterFromProps_1 = {};
          each(ELEMENT_ANIMATABLE_PROPS, function (propName) {
            var prop = propName ? elOption[propName] : elOption;

            if (prop && prop.enterFrom) {
              if (propName) {
                enterFromProps_1[propName] = enterFromProps_1[propName] || {};
              }

              extend(propName ? enterFromProps_1[propName] : enterFromProps_1, prop.enterFrom);
            }
          });
          var config = getElementAnimationConfig('enter', el, elOption, animatableModel, dataIndex);

          if (config.duration > 0) {
            el.animateFrom(enterFromProps_1, config);
          }
        } else {
          applyPropsTransition(el, elOption, dataIndex || 0, animatableModel, transFromProps);
        }
      } // Store leave to be used in leave transition.


      updateLeaveTo(el, elOption);
      styleOpt ? el.dirty() : el.markRedraw();
    }
    function updateLeaveTo(el, elOption) {
      // Try merge to previous set leaveTo
      var leaveToProps = transitionInnerStore(el).leaveToProps;

      for (var i = 0; i < ELEMENT_ANIMATABLE_PROPS.length; i++) {
        var propName = ELEMENT_ANIMATABLE_PROPS[i];
        var prop = propName ? elOption[propName] : elOption;

        if (prop && prop.leaveTo) {
          if (!leaveToProps) {
            leaveToProps = transitionInnerStore(el).leaveToProps = {};
          }

          if (propName) {
            leaveToProps[propName] = leaveToProps[propName] || {};
          }

          extend(propName ? leaveToProps[propName] : leaveToProps, prop.leaveTo);
        }
      }
    }
    function applyLeaveTransition(el, elOption, animatableModel, onRemove) {
      if (el) {
        var parent_1 = el.parent;
        var leaveToProps = transitionInnerStore(el).leaveToProps;

        if (leaveToProps) {
          // TODO TODO use leave after leaveAnimation in series is introduced
          // TODO Data index?
          var config = getElementAnimationConfig('update', el, elOption, animatableModel, 0);

          config.done = function () {
            parent_1.remove(el);
            onRemove && onRemove();
          };

          el.animateTo(leaveToProps, config);
        } else {
          parent_1.remove(el);
          onRemove && onRemove();
        }
      }
    }
    function isTransitionAll(transition) {
      return transition === 'all';
    }

    function applyPropsDirectly(el, // Can be null/undefined
    allPropsFinal, clearStyle) {
      var styleOpt = allPropsFinal.style;

      if (!el.isGroup && styleOpt) {
        if (clearStyle) {
          el.useStyle({}); // When style object changed, how to trade the existing animation?
          // It is probably complicated and not needed to cover all the cases.
          // But still need consider the case:
          // (1) When using init animation on `style.opacity`, and before the animation
          //     ended users triggers an update by mousewhel. At that time the init
          //     animation should better be continued rather than terminated.
          //     So after `useStyle` called, we should change the animation target manually
          //     to continue the effect of the init animation.
          // (2) PENDING: If the previous animation targeted at a `val1`, and currently we need
          //     to update the value to `val2` and no animation declared, should be terminate
          //     the previous animation or just modify the target of the animation?
          //     Therotically That will happen not only on `style` but also on `shape` and
          //     `transfrom` props. But we haven't handle this case at present yet.
          // (3) PENDING: Is it proper to visit `animators` and `targetName`?

          var animators = el.animators;

          for (var i = 0; i < animators.length; i++) {
            var animator = animators[i]; // targetName is the "topKey".

            if (animator.targetName === 'style') {
              animator.changeTarget(el.style);
            }
          }
        }

        el.setStyle(styleOpt);
      }

      if (allPropsFinal) {
        // Not set style here.
        allPropsFinal.style = null; // Set el to the final state firstly.

        allPropsFinal && el.attr(allPropsFinal);
        allPropsFinal.style = styleOpt;
      }
    }

    function applyPropsTransition(el, elOption, dataIndex, model, // Can be null/undefined
    transFromProps) {
      if (transFromProps) {
        var config = getElementAnimationConfig('update', el, elOption, model, dataIndex);

        if (config.duration > 0) {
          el.animateFrom(transFromProps, config);
        }
      }
    }

    function applyMiscProps(el, elOption) {
      // Merge by default.
      hasOwn(elOption, 'silent') && (el.silent = elOption.silent);
      hasOwn(elOption, 'ignore') && (el.ignore = elOption.ignore);

      if (el instanceof Displayable) {
        hasOwn(elOption, 'invisible') && (el.invisible = elOption.invisible);
      }

      if (el instanceof Path) {
        hasOwn(elOption, 'autoBatch') && (el.autoBatch = elOption.autoBatch);
      }
    } // Use it to avoid it be exposed to user.


    var tmpDuringScope = {};
    var transitionDuringAPI = {
      // Usually other props do not need to be changed in animation during.
      setTransform: function (key, val) {
        if ("development" !== 'production') {
          assert(hasOwn(TRANSFORM_PROPS_MAP, key), 'Only ' + transformPropNamesStr + ' available in `setTransform`.');
        }

        tmpDuringScope.el[key] = val;
        return this;
      },
      getTransform: function (key) {
        if ("development" !== 'production') {
          assert(hasOwn(TRANSFORM_PROPS_MAP, key), 'Only ' + transformPropNamesStr + ' available in `getTransform`.');
        }

        return tmpDuringScope.el[key];
      },
      setShape: function (key, val) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var el = tmpDuringScope.el;
        var shape = el.shape || (el.shape = {});
        shape[key] = val;
        el.dirtyShape && el.dirtyShape();
        return this;
      },
      getShape: function (key) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var shape = tmpDuringScope.el.shape;

        if (shape) {
          return shape[key];
        }
      },
      setStyle: function (key, val) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var el = tmpDuringScope.el;
        var style = el.style;

        if (style) {
          if ("development" !== 'production') {
            if (eqNaN(val)) {
              warn('style.' + key + ' must not be assigned with NaN.');
            }
          }

          style[key] = val;
          el.dirtyStyle && el.dirtyStyle();
        }

        return this;
      },
      getStyle: function (key) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var style = tmpDuringScope.el.style;

        if (style) {
          return style[key];
        }
      },
      setExtra: function (key, val) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var extra = tmpDuringScope.el.extra || (tmpDuringScope.el.extra = {});
        extra[key] = val;
        return this;
      },
      getExtra: function (key) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var extra = tmpDuringScope.el.extra;

        if (extra) {
          return extra[key];
        }
      }
    };

    function assertNotReserved(key) {
      if ("development" !== 'production') {
        if (key === 'transition' || key === 'enterFrom' || key === 'leaveTo') {
          throw new Error('key must not be "' + key + '"');
        }
      }
    }

    function duringCall() {
      // Do not provide "percent" until some requirements come.
      // Because consider thies case:
      // enterFrom: {x: 100, y: 30}, transition: 'x'.
      // And enter duration is different from update duration.
      // Thus it might be confused about the meaning of "percent" in during callback.
      var scope = this;
      var el = scope.el;

      if (!el) {
        return;
      } // If el is remove from zr by reason like legend, during still need to called,
      // because el will be added back to zr and the prop value should not be incorrect.


      var latestUserDuring = transitionInnerStore(el).userDuring;
      var scopeUserDuring = scope.userDuring; // Ensured a during is only called once in each animation frame.
      // If a during is called multiple times in one frame, maybe some users' calculation logic
      // might be wrong (not sure whether this usage exists).
      // The case of a during might be called twice can be: by default there is a animator for
      // 'x', 'y' when init. Before the init animation finished, call `setOption` to start
      // another animators for 'style'/'shape'/'extra'.

      if (latestUserDuring !== scopeUserDuring) {
        // release
        scope.el = scope.userDuring = null;
        return;
      }

      tmpDuringScope.el = el; // Give no `this` to user in "during" calling.

      scopeUserDuring(transitionDuringAPI); // FIXME: if in future meet the case that some prop will be both modified in `during` and `state`,
      // consider the issue that the prop might be incorrect when return to "normal" state.
    }

    function prepareShapeOrExtraTransitionFrom(mainAttr, fromEl, elOption, transFromProps) {
      var attrOpt = elOption[mainAttr];

      if (!attrOpt) {
        return;
      }

      var elPropsInAttr = fromEl[mainAttr];
      var transFromPropsInAttr;

      if (elPropsInAttr) {
        var transition = elOption.transition;
        var attrTransition = attrOpt.transition;

        if (attrTransition) {
          !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});

          if (isTransitionAll(attrTransition)) {
            extend(transFromPropsInAttr, elPropsInAttr);
          } else {
            var transitionKeys = normalizeToArray(attrTransition);

            for (var i = 0; i < transitionKeys.length; i++) {
              var key = transitionKeys[i];
              var elVal = elPropsInAttr[key];
              transFromPropsInAttr[key] = elVal;
            }
          }
        } else if (isTransitionAll(transition) || indexOf(transition, mainAttr) >= 0) {
          !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});
          var elPropsInAttrKeys = keys(elPropsInAttr);

          for (var i = 0; i < elPropsInAttrKeys.length; i++) {
            var key = elPropsInAttrKeys[i];
            var elVal = elPropsInAttr[key];

            if (isNonStyleTransitionEnabled(attrOpt[key], elVal)) {
              transFromPropsInAttr[key] = elVal;
            }
          }
        }
      }
    }

    function prepareShapeOrExtraAllPropsFinal(mainAttr, elOption, allProps) {
      var attrOpt = elOption[mainAttr];

      if (!attrOpt) {
        return;
      }

      var allPropsInAttr = allProps[mainAttr] = {};
      var keysInAttr = keys(attrOpt);

      for (var i = 0; i < keysInAttr.length; i++) {
        var key = keysInAttr[i]; // To avoid share one object with different element, and
        // to avoid user modify the object inexpectedly, have to clone.

        allPropsInAttr[key] = cloneValue(attrOpt[key]);
      }
    }

    function prepareTransformTransitionFrom(el, elOption, transFromProps) {
      var transition = elOption.transition;
      var transitionKeys = isTransitionAll(transition) ? TRANSFORMABLE_PROPS : normalizeToArray(transition || []);

      for (var i = 0; i < transitionKeys.length; i++) {
        var key = transitionKeys[i];

        if (key === 'style' || key === 'shape' || key === 'extra') {
          continue;
        }

        var elVal = el[key];

        if ("development" !== 'production') {
          checkTransformPropRefer(key, 'el.transition');
        } // Do not clone, animator will perform that clone.


        transFromProps[key] = elVal;
      }
    }

    function prepareTransformAllPropsFinal(el, elOption, allProps) {
      for (var i = 0; i < LEGACY_TRANSFORM_PROPS.length; i++) {
        var legacyName = LEGACY_TRANSFORM_PROPS[i];
        var xyName = LEGACY_TRANSFORM_PROPS_MAP[legacyName];
        var legacyArr = elOption[legacyName];

        if (legacyArr) {
          allProps[xyName[0]] = legacyArr[0];
          allProps[xyName[1]] = legacyArr[1];
        }
      }

      for (var i = 0; i < TRANSFORMABLE_PROPS.length; i++) {
        var key = TRANSFORMABLE_PROPS[i];

        if (elOption[key] != null) {
          allProps[key] = elOption[key];
        }
      }
    }

    function prepareStyleTransitionFrom(fromEl, elOption, styleOpt, transFromProps) {
      if (!styleOpt) {
        return;
      }

      var fromElStyle = fromEl.style;
      var transFromStyleProps;

      if (fromElStyle) {
        var styleTransition = styleOpt.transition;
        var elTransition = elOption.transition;

        if (styleTransition && !isTransitionAll(styleTransition)) {
          var transitionKeys = normalizeToArray(styleTransition);
          !transFromStyleProps && (transFromStyleProps = transFromProps.style = {});

          for (var i = 0; i < transitionKeys.length; i++) {
            var key = transitionKeys[i];
            var elVal = fromElStyle[key]; // Do not clone, see `checkNonStyleTansitionRefer`.

            transFromStyleProps[key] = elVal;
          }
        } else if (fromEl.getAnimationStyleProps && (isTransitionAll(elTransition) || isTransitionAll(styleTransition) || indexOf(elTransition, 'style') >= 0)) {
          var animationProps = fromEl.getAnimationStyleProps();
          var animationStyleProps = animationProps ? animationProps.style : null;

          if (animationStyleProps) {
            !transFromStyleProps && (transFromStyleProps = transFromProps.style = {});
            var styleKeys = keys(styleOpt);

            for (var i = 0; i < styleKeys.length; i++) {
              var key = styleKeys[i];

              if (animationStyleProps[key]) {
                var elVal = fromElStyle[key];
                transFromStyleProps[key] = elVal;
              }
            }
          }
        }
      }
    }

    function isNonStyleTransitionEnabled(optVal, elVal) {
      // The same as `checkNonStyleTansitionRefer`.
      return !isArrayLike(optVal) ? optVal != null && isFinite(optVal) : optVal !== elVal;
    }

    var checkTransformPropRefer;

    if ("development" !== 'production') {
      checkTransformPropRefer = function (key, usedIn) {
        if (!hasOwn(TRANSFORM_PROPS_MAP, key)) {
          warn('Prop `' + key + '` is not a permitted in `' + usedIn + '`. ' + 'Only `' + keys(TRANSFORM_PROPS_MAP).join('`, `') + '` are permitted.');
        }
      };
    }

    var getStateToRestore = makeInner();
    var KEYFRAME_EXCLUDE_KEYS = ['percent', 'easing', 'shape', 'style', 'extra'];
    /**
     * Stop previous keyframe animation and restore the attributes.
     * Avoid new keyframe animation starts with wrong internal state when the percent: 0 is not set.
     */

    function stopPreviousKeyframeAnimationAndRestore(el) {
      // Stop previous keyframe animation.
      el.stopAnimation('keyframe'); // Restore

      el.attr(getStateToRestore(el));
    }
    function applyKeyframeAnimation(el, animationOpts, animatableModel) {
      if (!animatableModel.isAnimationEnabled() || !animationOpts) {
        return;
      }

      if (isArray(animationOpts)) {
        each(animationOpts, function (singleAnimationOpts) {
          applyKeyframeAnimation(el, singleAnimationOpts, animatableModel);
        });
        return;
      }

      var keyframes = animationOpts.keyframes;
      var duration = animationOpts.duration;

      if (animatableModel && duration == null) {
        // Default to use duration of config.
        // NOTE: animation config from payload will be ignored because they are mainly for transitions.
        var config = getAnimationConfig('enter', animatableModel, 0);
        duration = config && config.duration;
      }

      if (!keyframes || !duration) {
        return;
      }

      var stateToRestore = getStateToRestore(el);
      each(ELEMENT_ANIMATABLE_PROPS, function (targetPropName) {
        if (targetPropName && !el[targetPropName]) {
          return;
        }

        var animator;
        var endFrameIsSet = false; // Sort keyframes by percent.

        keyframes.sort(function (a, b) {
          return a.percent - b.percent;
        });
        each(keyframes, function (kf) {
          // Stop current animation.
          var animators = el.animators;
          var kfValues = targetPropName ? kf[targetPropName] : kf;

          if ("development" !== 'production') {
            if (kf.percent >= 1) {
              endFrameIsSet = true;
            }
          }

          if (!kfValues) {
            return;
          }

          var propKeys = keys(kfValues);

          if (!targetPropName) {
            // PENDING performance?
            propKeys = filter(propKeys, function (key) {
              return indexOf(KEYFRAME_EXCLUDE_KEYS, key) < 0;
            });
          }

          if (!propKeys.length) {
            return;
          }

          if (!animator) {
            animator = el.animate(targetPropName, animationOpts.loop, true);
            animator.scope = 'keyframe';
          }

          for (var i = 0; i < animators.length; i++) {
            // Stop all other animation that is not keyframe.
            if (animators[i] !== animator && animators[i].targetName === animator.targetName) {
              animators[i].stopTracks(propKeys);
            }
          }

          targetPropName && (stateToRestore[targetPropName] = stateToRestore[targetPropName] || {});
          var savedTarget = targetPropName ? stateToRestore[targetPropName] : stateToRestore;
          each(propKeys, function (key) {
            // Save original value.
            savedTarget[key] = ((targetPropName ? el[targetPropName] : el) || {})[key];
          });
          animator.whenWithKeys(duration * kf.percent, kfValues, propKeys, kf.easing);
        });

        if (!animator) {
          return;
        }

        if ("development" !== 'production') {
          if (!endFrameIsSet) {
            warn('End frame with percent: 1 is missing in the keyframeAnimation.', true);
          }
        }

        animator.delay(animationOpts.delay || 0).duration(duration).start(animationOpts.easing);
      });
    }

    var nonShapeGraphicElements = {
      // Reserved but not supported in graphic component.
      path: null,
      compoundPath: null,
      // Supported in graphic component.
      group: Group,
      image: ZRImage,
      text: ZRText
    };
    var inner$a = makeInner(); // ------------------------
    // View
    // ------------------------

    var GraphicComponentView =
    /** @class */
    function (_super) {
      __extends(GraphicComponentView, _super);

      function GraphicComponentView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = GraphicComponentView.type;
        return _this;
      }

      GraphicComponentView.prototype.init = function () {
        this._elMap = createHashMap();
      };

      GraphicComponentView.prototype.render = function (graphicModel, ecModel, api) {
        // Having leveraged between use cases and algorithm complexity, a very
        // simple layout mechanism is used:
        // The size(width/height) can be determined by itself or its parent (not
        // implemented yet), but can not by its children. (Top-down travel)
        // The location(x/y) can be determined by the bounding rect of itself
        // (can including its descendants or not) and the size of its parent.
        // (Bottom-up travel)
        // When `chart.clear()` or `chart.setOption({...}, true)` with the same id,
        // view will be reused.
        if (graphicModel !== this._lastGraphicModel) {
          this._clear();
        }

        this._lastGraphicModel = graphicModel;

        this._updateElements(graphicModel);

        this._relocate(graphicModel, api);
      };
      /**
       * Update graphic elements.
       */


      GraphicComponentView.prototype._updateElements = function (graphicModel) {
        var elOptionsToUpdate = graphicModel.useElOptionsToUpdate();

        if (!elOptionsToUpdate) {
          return;
        }

        var elMap = this._elMap;
        var rootGroup = this.group;
        var globalZ = graphicModel.get('z');
        var globalZLevel = graphicModel.get('zlevel'); // Top-down tranverse to assign graphic settings to each elements.

        each(elOptionsToUpdate, function (elOption) {
          var id = convertOptionIdName(elOption.id, null);
          var elExisting = id != null ? elMap.get(id) : null;
          var parentId = convertOptionIdName(elOption.parentId, null);
          var targetElParent = parentId != null ? elMap.get(parentId) : rootGroup;
          var elType = elOption.type;
          var elOptionStyle = elOption.style;

          if (elType === 'text' && elOptionStyle) {
            // In top/bottom mode, textVerticalAlign should not be used, which cause
            // inaccurately locating.
            if (elOption.hv && elOption.hv[1]) {
              elOptionStyle.textVerticalAlign = elOptionStyle.textBaseline = elOptionStyle.verticalAlign = elOptionStyle.align = null;
            }
          }

          var textContentOption = elOption.textContent;
          var textConfig = elOption.textConfig;

          if (elOptionStyle && isEC4CompatibleStyle(elOptionStyle, elType, !!textConfig, !!textContentOption)) {
            var convertResult = convertFromEC4CompatibleStyle(elOptionStyle, elType, true);

            if (!textConfig && convertResult.textConfig) {
              textConfig = elOption.textConfig = convertResult.textConfig;
            }

            if (!textContentOption && convertResult.textContent) {
              textContentOption = convertResult.textContent;
            }
          } // Remove unnecessary props to avoid potential problems.


          var elOptionCleaned = getCleanedElOption(elOption); // For simple, do not support parent change, otherwise reorder is needed.

          if ("development" !== 'production') {
            elExisting && assert(targetElParent === elExisting.parent, 'Changing parent is not supported.');
          }

          var $action = elOption.$action || 'merge';
          var isMerge = $action === 'merge';
          var isReplace = $action === 'replace';

          if (isMerge) {
            var isInit = !elExisting;
            var el_1 = elExisting;

            if (isInit) {
              el_1 = createEl(id, targetElParent, elOption.type, elMap);
            } else {
              el_1 && (inner$a(el_1).isNew = false); // Stop and restore before update any other attributes.

              stopPreviousKeyframeAnimationAndRestore(el_1);
            }

            if (el_1) {
              applyUpdateTransition(el_1, elOptionCleaned, graphicModel, {
                isInit: isInit
              });
              updateCommonAttrs(el_1, elOption, globalZ, globalZLevel);
            }
          } else if (isReplace) {
            removeEl(elExisting, elOption, elMap, graphicModel);
            var el_2 = createEl(id, targetElParent, elOption.type, elMap);

            if (el_2) {
              applyUpdateTransition(el_2, elOptionCleaned, graphicModel, {
                isInit: true
              });
              updateCommonAttrs(el_2, elOption, globalZ, globalZLevel);
            }
          } else if ($action === 'remove') {
            updateLeaveTo(elExisting, elOption);
            removeEl(elExisting, elOption, elMap, graphicModel);
          }

          var el = elMap.get(id);

          if (el && textContentOption) {
            if (isMerge) {
              var textContentExisting = el.getTextContent();
              textContentExisting ? textContentExisting.attr(textContentOption) : el.setTextContent(new ZRText(textContentOption));
            } else if (isReplace) {
              el.setTextContent(new ZRText(textContentOption));
            }
          }

          if (el) {
            var clipPathOption = elOption.clipPath;

            if (clipPathOption) {
              var clipPathType = clipPathOption.type;
              var clipPath = void 0;
              var isInit = false;

              if (isMerge) {
                var oldClipPath = el.getClipPath();
                isInit = !oldClipPath || inner$a(oldClipPath).type !== clipPathType;
                clipPath = isInit ? newEl(clipPathType) : oldClipPath;
              } else if (isReplace) {
                isInit = true;
                clipPath = newEl(clipPathType);
              }

              el.setClipPath(clipPath);
              applyUpdateTransition(clipPath, clipPathOption, graphicModel, {
                isInit: isInit
              });
              applyKeyframeAnimation(clipPath, clipPathOption.keyframeAnimation, graphicModel);
            }

            var elInner = inner$a(el);
            el.setTextConfig(textConfig);
            elInner.option = elOption;
            setEventData(el, graphicModel, elOption);
            setTooltipConfig({
              el: el,
              componentModel: graphicModel,
              itemName: el.name,
              itemTooltipOption: elOption.tooltip
            });
            applyKeyframeAnimation(el, elOption.keyframeAnimation, graphicModel);
          }
        });
      };
      /**
       * Locate graphic elements.
       */


      GraphicComponentView.prototype._relocate = function (graphicModel, api) {
        var elOptions = graphicModel.option.elements;
        var rootGroup = this.group;
        var elMap = this._elMap;
        var apiWidth = api.getWidth();
        var apiHeight = api.getHeight();
        var xy = ['x', 'y']; // Top-down to calculate percentage width/height of group

        for (var i = 0; i < elOptions.length; i++) {
          var elOption = elOptions[i];
          var id = convertOptionIdName(elOption.id, null);
          var el = id != null ? elMap.get(id) : null;

          if (!el || !el.isGroup) {
            continue;
          }

          var parentEl = el.parent;
          var isParentRoot = parentEl === rootGroup; // Like 'position:absolut' in css, default 0.

          var elInner = inner$a(el);
          var parentElInner = inner$a(parentEl);
          elInner.width = parsePercent$1(elInner.option.width, isParentRoot ? apiWidth : parentElInner.width) || 0;
          elInner.height = parsePercent$1(elInner.option.height, isParentRoot ? apiHeight : parentElInner.height) || 0;
        } // Bottom-up tranvese all elements (consider ec resize) to locate elements.


        for (var i = elOptions.length - 1; i >= 0; i--) {
          var elOption = elOptions[i];
          var id = convertOptionIdName(elOption.id, null);
          var el = id != null ? elMap.get(id) : null;

          if (!el) {
            continue;
          }

          var parentEl = el.parent;
          var parentElInner = inner$a(parentEl);
          var containerInfo = parentEl === rootGroup ? {
            width: apiWidth,
            height: apiHeight
          } : {
            width: parentElInner.width,
            height: parentElInner.height
          }; // PENDING
          // Currently, when `bounding: 'all'`, the union bounding rect of the group
          // does not include the rect of [0, 0, group.width, group.height], which
          // is probably weird for users. Should we make a break change for it?

          var layoutPos = {};
          var layouted = positionElement(el, elOption, containerInfo, null, {
            hv: elOption.hv,
            boundingMode: elOption.bounding
          }, layoutPos);

          if (!inner$a(el).isNew && layouted) {
            var transition = elOption.transition;
            var animatePos = {};

            for (var k = 0; k < xy.length; k++) {
              var key = xy[k];
              var val = layoutPos[key];

              if (transition && (isTransitionAll(transition) || indexOf(transition, key) >= 0)) {
                animatePos[key] = val;
              } else {
                el[key] = val;
              }
            }

            updateProps(el, animatePos, graphicModel, 0);
          } else {
            el.attr(layoutPos);
          }
        }
      };
      /**
       * Clear all elements.
       */


      GraphicComponentView.prototype._clear = function () {
        var _this = this;

        var elMap = this._elMap;
        elMap.each(function (el) {
          removeEl(el, inner$a(el).option, elMap, _this._lastGraphicModel);
        });
        this._elMap = createHashMap();
      };

      GraphicComponentView.prototype.dispose = function () {
        this._clear();
      };

      GraphicComponentView.type = 'graphic';
      return GraphicComponentView;
    }(ComponentView);

    function newEl(graphicType) {
      if ("development" !== 'production') {
        assert(graphicType, 'graphic type MUST be set');
      }

      var Clz = hasOwn(nonShapeGraphicElements, graphicType) // Those graphic elements are not shapes. They should not be
      // overwritten by users, so do them first.
      ? nonShapeGraphicElements[graphicType] : getShapeClass(graphicType);

      if ("development" !== 'production') {
        assert(Clz, "graphic type " + graphicType + " can not be found");
      }

      var el = new Clz({});
      inner$a(el).type = graphicType;
      return el;
    }

    function createEl(id, targetElParent, graphicType, elMap) {
      var el = newEl(graphicType);
      targetElParent.add(el);
      elMap.set(id, el);
      inner$a(el).id = id;
      inner$a(el).isNew = true;
      return el;
    }

    function removeEl(elExisting, elOption, elMap, graphicModel) {
      var existElParent = elExisting && elExisting.parent;

      if (existElParent) {
        elExisting.type === 'group' && elExisting.traverse(function (el) {
          removeEl(el, elOption, elMap, graphicModel);
        });
        applyLeaveTransition(elExisting, elOption, graphicModel);
        elMap.removeKey(inner$a(elExisting).id);
      }
    }

    function updateCommonAttrs(el, elOption, defaultZ, defaultZlevel) {
      if (!el.isGroup) {
        each([['cursor', Displayable.prototype.cursor], // We should not support configure z and zlevel in the element level.
        // But seems we didn't limit it previously. So here still use it to avoid breaking.
        ['zlevel', defaultZlevel || 0], ['z', defaultZ || 0], // z2 must not be null/undefined, otherwise sort error may occur.
        ['z2', 0]], function (item) {
          var prop = item[0];

          if (hasOwn(elOption, prop)) {
            el[prop] = retrieve2(elOption[prop], item[1]);
          } else if (el[prop] == null) {
            el[prop] = item[1];
          }
        });
      }

      each(keys(elOption), function (key) {
        // Assign event handlers.
        // PENDING: should enumerate all event names or use pattern matching?
        if (key.indexOf('on') === 0) {
          var val = elOption[key];
          el[key] = isFunction(val) ? val : null;
        }
      });

      if (hasOwn(elOption, 'draggable')) {
        el.draggable = elOption.draggable;
      } // Other attributes


      elOption.name != null && (el.name = elOption.name);
      elOption.id != null && (el.id = elOption.id);
    } // Remove unnecessary props to avoid potential problems.


    function getCleanedElOption(elOption) {
      elOption = extend({}, elOption);
      each(['id', 'parentId', '$action', 'hv', 'bounding', 'textContent', 'clipPath'].concat(LOCATION_PARAMS), function (name) {
        delete elOption[name];
      });
      return elOption;
    }

    function setEventData(el, graphicModel, elOption) {
      var eventData = getECData(el).eventData; // Simple optimize for large amount of elements that no need event.

      if (!el.silent && !el.ignore && !eventData) {
        eventData = getECData(el).eventData = {
          componentType: 'graphic',
          componentIndex: graphicModel.componentIndex,
          name: el.name
        };
      } // `elOption.info` enables user to mount some info on
      // elements and use them in event handlers.


      if (eventData) {
        eventData.info = elOption.info;
      }
    }

    function install$9(registers) {
      registers.registerComponentModel(GraphicComponentModel);
      registers.registerComponentView(GraphicComponentView);
      registers.registerPreprocessor(function (option) {
        var graphicOption = option.graphic; // Convert
        // {graphic: [{left: 10, type: 'circle'}, ...]}
        // or
        // {graphic: {left: 10, type: 'circle'}}
        // to
        // {graphic: [{elements: [{left: 10, type: 'circle'}, ...]}]}

        if (isArray(graphicOption)) {
          if (!graphicOption[0] || !graphicOption[0].elements) {
            option.graphic = [{
              elements: graphicOption
            }];
          } else {
            // Only one graphic instance can be instantiated. (We don't
            // want that too many views are created in echarts._viewMap.)
            option.graphic = [option.graphic[0]];
          }
        } else if (graphicOption && !graphicOption.elements) {
          option.graphic = [{
            elements: [graphicOption]
          }];
        }
      });
    }

    var DATA_ZOOM_AXIS_DIMENSIONS = ['x', 'y', 'radius', 'angle', 'single']; // Supported coords.
    // FIXME: polar has been broken (but rarely used).

    var SERIES_COORDS = ['cartesian2d', 'polar', 'singleAxis'];
    function isCoordSupported(seriesModel) {
      var coordType = seriesModel.get('coordinateSystem');
      return indexOf(SERIES_COORDS, coordType) >= 0;
    }
    function getAxisMainType(axisDim) {
      if ("development" !== 'production') {
        assert(axisDim);
      }

      return axisDim + 'Axis';
    }
    /**
     * If two dataZoomModels has the same axis controlled, we say that they are 'linked'.
     * This function finds all linked dataZoomModels start from the given payload.
     */

    function findEffectedDataZooms(ecModel, payload) {
      // Key: `DataZoomAxisDimension`
      var axisRecords = createHashMap();
      var effectedModels = []; // Key: uid of dataZoomModel

      var effectedModelMap = createHashMap(); // Find the dataZooms specified by payload.

      ecModel.eachComponent({
        mainType: 'dataZoom',
        query: payload
      }, function (dataZoomModel) {
        if (!effectedModelMap.get(dataZoomModel.uid)) {
          addToEffected(dataZoomModel);
        }
      }); // Start from the given dataZoomModels, travel the graph to find
      // all of the linked dataZoom models.

      var foundNewLink;

      do {
        foundNewLink = false;
        ecModel.eachComponent('dataZoom', processSingle);
      } while (foundNewLink);

      function processSingle(dataZoomModel) {
        if (!effectedModelMap.get(dataZoomModel.uid) && isLinked(dataZoomModel)) {
          addToEffected(dataZoomModel);
          foundNewLink = true;
        }
      }

      function addToEffected(dataZoom) {
        effectedModelMap.set(dataZoom.uid, true);
        effectedModels.push(dataZoom);
        markAxisControlled(dataZoom);
      }

      function isLinked(dataZoomModel) {
        var isLink = false;
        dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
          var axisIdxArr = axisRecords.get(axisDim);

          if (axisIdxArr && axisIdxArr[axisIndex]) {
            isLink = true;
          }
        });
        return isLink;
      }

      function markAxisControlled(dataZoomModel) {
        dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
          (axisRecords.get(axisDim) || axisRecords.set(axisDim, []))[axisIndex] = true;
        });
      }

      return effectedModels;
    }
    /**
     * Find the first target coordinate system.
     * Available after model built.
     *
     * @return Like {
     *                  grid: [
     *                      {model: coord0, axisModels: [axis1, axis3], coordIndex: 1},
     *                      {model: coord1, axisModels: [axis0, axis2], coordIndex: 0},
     *                      ...
     *                  ],  // cartesians must not be null/undefined.
     *                  polar: [
     *                      {model: coord0, axisModels: [axis4], coordIndex: 0},
     *                      ...
     *                  ],  // polars must not be null/undefined.
     *                  singleAxis: [
     *                      {model: coord0, axisModels: [], coordIndex: 0}
     *                  ]
     *              }
     */

    function collectReferCoordSysModelInfo(dataZoomModel) {
      var ecModel = dataZoomModel.ecModel;
      var coordSysInfoWrap = {
        infoList: [],
        infoMap: createHashMap()
      };
      dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
        var axisModel = ecModel.getComponent(getAxisMainType(axisDim), axisIndex);

        if (!axisModel) {
          return;
        }

        var coordSysModel = axisModel.getCoordSysModel();

        if (!coordSysModel) {
          return;
        }

        var coordSysUid = coordSysModel.uid;
        var coordSysInfo = coordSysInfoWrap.infoMap.get(coordSysUid);

        if (!coordSysInfo) {
          coordSysInfo = {
            model: coordSysModel,
            axisModels: []
          };
          coordSysInfoWrap.infoList.push(coordSysInfo);
          coordSysInfoWrap.infoMap.set(coordSysUid, coordSysInfo);
        }

        coordSysInfo.axisModels.push(axisModel);
      });
      return coordSysInfoWrap;
    }

    var DataZoomAxisInfo =
    /** @class */
    function () {
      function DataZoomAxisInfo() {
        this.indexList = [];
        this.indexMap = [];
      }

      DataZoomAxisInfo.prototype.add = function (axisCmptIdx) {
        // Remove duplication.
        if (!this.indexMap[axisCmptIdx]) {
          this.indexList.push(axisCmptIdx);
          this.indexMap[axisCmptIdx] = true;
        }
      };

      return DataZoomAxisInfo;
    }();

    var DataZoomModel =
    /** @class */
    function (_super) {
      __extends(DataZoomModel, _super);

      function DataZoomModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = DataZoomModel.type;
        _this._autoThrottle = true;
        _this._noTarget = true;
        /**
         * It is `[rangeModeForMin, rangeModeForMax]`.
         * The optional values for `rangeMode`:
         * + `'value'` mode: the axis extent will always be determined by
         *     `dataZoom.startValue` and `dataZoom.endValue`, despite
         *     how data like and how `axis.min` and `axis.max` are.
         * + `'percent'` mode: `100` represents 100% of the `[dMin, dMax]`,
         *     where `dMin` is `axis.min` if `axis.min` specified, otherwise `data.extent[0]`,
         *     and `dMax` is `axis.max` if `axis.max` specified, otherwise `data.extent[1]`.
         *     Axis extent will be determined by the result of the percent of `[dMin, dMax]`.
         *
         * For example, when users are using dynamic data (update data periodically via `setOption`),
         * if in `'value`' mode, the window will be kept in a fixed value range despite how
         * data are appended, while if in `'percent'` mode, whe window range will be changed alone with
         * the appended data (suppose `axis.min` and `axis.max` are not specified).
         */

        _this._rangePropMode = ['percent', 'percent'];
        return _this;
      }

      DataZoomModel.prototype.init = function (option, parentModel, ecModel) {
        var inputRawOption = retrieveRawOption(option);
        /**
         * Suppose a "main process" start at the point that model prepared (that is,
         * model initialized or merged or method called in `action`).
         * We should keep the `main process` idempotent, that is, given a set of values
         * on `option`, we get the same result.
         *
         * But sometimes, values on `option` will be updated for providing users
         * a "final calculated value" (`dataZoomProcessor` will do that). Those value
         * should not be the base/input of the `main process`.
         *
         * So in that case we should save and keep the input of the `main process`
         * separately, called `settledOption`.
         *
         * For example, consider the case:
         * (Step_1) brush zoom the grid by `toolbox.dataZoom`,
         *     where the original input `option.startValue`, `option.endValue` are earsed by
         *     calculated value.
         * (Step)2) click the legend to hide and show a series,
         *     where the new range is calculated by the earsed `startValue` and `endValue`,
         *     which brings incorrect result.
         */

        this.settledOption = inputRawOption;
        this.mergeDefaultAndTheme(option, ecModel);

        this._doInit(inputRawOption);
      };

      DataZoomModel.prototype.mergeOption = function (newOption) {
        var inputRawOption = retrieveRawOption(newOption); // FIX #2591

        merge(this.option, newOption, true);
        merge(this.settledOption, inputRawOption, true);

        this._doInit(inputRawOption);
      };

      DataZoomModel.prototype._doInit = function (inputRawOption) {
        var thisOption = this.option;

        this._setDefaultThrottle(inputRawOption);

        this._updateRangeUse(inputRawOption);

        var settledOption = this.settledOption;
        each([['start', 'startValue'], ['end', 'endValue']], function (names, index) {
          // start/end has higher priority over startValue/endValue if they
          // both set, but we should make chart.setOption({endValue: 1000})
          // effective, rather than chart.setOption({endValue: 1000, end: null}).
          if (this._rangePropMode[index] === 'value') {
            thisOption[names[0]] = settledOption[names[0]] = null;
          } // Otherwise do nothing and use the merge result.

        }, this);

        this._resetTarget();
      };

      DataZoomModel.prototype._resetTarget = function () {
        var optionOrient = this.get('orient', true);
        var targetAxisIndexMap = this._targetAxisInfoMap = createHashMap();

        var hasAxisSpecified = this._fillSpecifiedTargetAxis(targetAxisIndexMap);

        if (hasAxisSpecified) {
          this._orient = optionOrient || this._makeAutoOrientByTargetAxis();
        } else {
          this._orient = optionOrient || 'horizontal';

          this._fillAutoTargetAxisByOrient(targetAxisIndexMap, this._orient);
        }

        this._noTarget = true;
        targetAxisIndexMap.each(function (axisInfo) {
          if (axisInfo.indexList.length) {
            this._noTarget = false;
          }
        }, this);
      };

      DataZoomModel.prototype._fillSpecifiedTargetAxis = function (targetAxisIndexMap) {
        var hasAxisSpecified = false;
        each(DATA_ZOOM_AXIS_DIMENSIONS, function (axisDim) {
          var refering = this.getReferringComponents(getAxisMainType(axisDim), MULTIPLE_REFERRING); // When user set axisIndex as a empty array, we think that user specify axisIndex
          // but do not want use auto mode. Because empty array may be encountered when
          // some error occurred.

          if (!refering.specified) {
            return;
          }

          hasAxisSpecified = true;
          var axisInfo = new DataZoomAxisInfo();
          each(refering.models, function (axisModel) {
            axisInfo.add(axisModel.componentIndex);
          });
          targetAxisIndexMap.set(axisDim, axisInfo);
        }, this);
        return hasAxisSpecified;
      };

      DataZoomModel.prototype._fillAutoTargetAxisByOrient = function (targetAxisIndexMap, orient) {
        var ecModel = this.ecModel;
        var needAuto = true; // Find axis that parallel to dataZoom as default.

        if (needAuto) {
          var axisDim = orient === 'vertical' ? 'y' : 'x';
          var axisModels = ecModel.findComponents({
            mainType: axisDim + 'Axis'
          });
          setParallelAxis(axisModels, axisDim);
        } // Find axis that parallel to dataZoom as default.


        if (needAuto) {
          var axisModels = ecModel.findComponents({
            mainType: 'singleAxis',
            filter: function (axisModel) {
              return axisModel.get('orient', true) === orient;
            }
          });
          setParallelAxis(axisModels, 'single');
        }

        function setParallelAxis(axisModels, axisDim) {
          // At least use the first parallel axis as the target axis.
          var axisModel = axisModels[0];

          if (!axisModel) {
            return;
          }

          var axisInfo = new DataZoomAxisInfo();
          axisInfo.add(axisModel.componentIndex);
          targetAxisIndexMap.set(axisDim, axisInfo);
          needAuto = false; // Find parallel axes in the same grid.

          if (axisDim === 'x' || axisDim === 'y') {
            var gridModel_1 = axisModel.getReferringComponents('grid', SINGLE_REFERRING).models[0];
            gridModel_1 && each(axisModels, function (axModel) {
              if (axisModel.componentIndex !== axModel.componentIndex && gridModel_1 === axModel.getReferringComponents('grid', SINGLE_REFERRING).models[0]) {
                axisInfo.add(axModel.componentIndex);
              }
            });
          }
        }

        if (needAuto) {
          // If no parallel axis, find the first category axis as default. (Also consider polar).
          each(DATA_ZOOM_AXIS_DIMENSIONS, function (axisDim) {
            if (!needAuto) {
              return;
            }

            var axisModels = ecModel.findComponents({
              mainType: getAxisMainType(axisDim),
              filter: function (axisModel) {
                return axisModel.get('type', true) === 'category';
              }
            });

            if (axisModels[0]) {
              var axisInfo = new DataZoomAxisInfo();
              axisInfo.add(axisModels[0].componentIndex);
              targetAxisIndexMap.set(axisDim, axisInfo);
              needAuto = false;
            }
          }, this);
        }
      };

      DataZoomModel.prototype._makeAutoOrientByTargetAxis = function () {
        var dim; // Find the first axis

        this.eachTargetAxis(function (axisDim) {
          !dim && (dim = axisDim);
        }, this);
        return dim === 'y' ? 'vertical' : 'horizontal';
      };

      DataZoomModel.prototype._setDefaultThrottle = function (inputRawOption) {
        // When first time user set throttle, auto throttle ends.
        if (inputRawOption.hasOwnProperty('throttle')) {
          this._autoThrottle = false;
        }

        if (this._autoThrottle) {
          var globalOption = this.ecModel.option;
          this.option.throttle = globalOption.animation && globalOption.animationDurationUpdate > 0 ? 100 : 20;
        }
      };

      DataZoomModel.prototype._updateRangeUse = function (inputRawOption) {
        var rangePropMode = this._rangePropMode;
        var rangeModeInOption = this.get('rangeMode');
        each([['start', 'startValue'], ['end', 'endValue']], function (names, index) {
          var percentSpecified = inputRawOption[names[0]] != null;
          var valueSpecified = inputRawOption[names[1]] != null;

          if (percentSpecified && !valueSpecified) {
            rangePropMode[index] = 'percent';
          } else if (!percentSpecified && valueSpecified) {
            rangePropMode[index] = 'value';
          } else if (rangeModeInOption) {
            rangePropMode[index] = rangeModeInOption[index];
          } else if (percentSpecified) {
            // percentSpecified && valueSpecified
            rangePropMode[index] = 'percent';
          } // else remain its original setting.

        });
      };

      DataZoomModel.prototype.noTarget = function () {
        return this._noTarget;
      };

      DataZoomModel.prototype.getFirstTargetAxisModel = function () {
        var firstAxisModel;
        this.eachTargetAxis(function (axisDim, axisIndex) {
          if (firstAxisModel == null) {
            firstAxisModel = this.ecModel.getComponent(getAxisMainType(axisDim), axisIndex);
          }
        }, this);
        return firstAxisModel;
      };
      /**
       * @param {Function} callback param: axisModel, dimNames, axisIndex, dataZoomModel, ecModel
       */


      DataZoomModel.prototype.eachTargetAxis = function (callback, context) {
        this._targetAxisInfoMap.each(function (axisInfo, axisDim) {
          each(axisInfo.indexList, function (axisIndex) {
            callback.call(context, axisDim, axisIndex);
          });
        });
      };
      /**
       * @return If not found, return null/undefined.
       */


      DataZoomModel.prototype.getAxisProxy = function (axisDim, axisIndex) {
        var axisModel = this.getAxisModel(axisDim, axisIndex);

        if (axisModel) {
          return axisModel.__dzAxisProxy;
        }
      };
      /**
       * @return If not found, return null/undefined.
       */


      DataZoomModel.prototype.getAxisModel = function (axisDim, axisIndex) {
        if ("development" !== 'production') {
          assert(axisDim && axisIndex != null);
        }

        var axisInfo = this._targetAxisInfoMap.get(axisDim);

        if (axisInfo && axisInfo.indexMap[axisIndex]) {
          return this.ecModel.getComponent(getAxisMainType(axisDim), axisIndex);
        }
      };
      /**
       * If not specified, set to undefined.
       */


      DataZoomModel.prototype.setRawRange = function (opt) {
        var thisOption = this.option;
        var settledOption = this.settledOption;
        each([['start', 'startValue'], ['end', 'endValue']], function (names) {
          // Consider the pair <start, startValue>:
          // If one has value and the other one is `null/undefined`, we both set them
          // to `settledOption`. This strategy enables the feature to clear the original
          // value in `settledOption` to `null/undefined`.
          // But if both of them are `null/undefined`, we do not set them to `settledOption`
          // and keep `settledOption` with the original value. This strategy enables users to
          // only set <end or endValue> but not set <start or startValue> when calling
          // `dispatchAction`.
          // The pair <end, endValue> is treated in the same way.
          if (opt[names[0]] != null || opt[names[1]] != null) {
            thisOption[names[0]] = settledOption[names[0]] = opt[names[0]];
            thisOption[names[1]] = settledOption[names[1]] = opt[names[1]];
          }
        }, this);

        this._updateRangeUse(opt);
      };

      DataZoomModel.prototype.setCalculatedRange = function (opt) {
        var option = this.option;
        each(['start', 'startValue', 'end', 'endValue'], function (name) {
          option[name] = opt[name];
        });
      };

      DataZoomModel.prototype.getPercentRange = function () {
        var axisProxy = this.findRepresentativeAxisProxy();

        if (axisProxy) {
          return axisProxy.getDataPercentWindow();
        }
      };
      /**
       * For example, chart.getModel().getComponent('dataZoom').getValueRange('y', 0);
       *
       * @return [startValue, endValue] value can only be '-' or finite number.
       */


      DataZoomModel.prototype.getValueRange = function (axisDim, axisIndex) {
        if (axisDim == null && axisIndex == null) {
          var axisProxy = this.findRepresentativeAxisProxy();

          if (axisProxy) {
            return axisProxy.getDataValueWindow();
          }
        } else {
          return this.getAxisProxy(axisDim, axisIndex).getDataValueWindow();
        }
      };
      /**
       * @param axisModel If axisModel given, find axisProxy
       *      corresponding to the axisModel
       */


      DataZoomModel.prototype.findRepresentativeAxisProxy = function (axisModel) {
        if (axisModel) {
          return axisModel.__dzAxisProxy;
        } // Find the first hosted axisProxy


        var firstProxy;

        var axisDimList = this._targetAxisInfoMap.keys();

        for (var i = 0; i < axisDimList.length; i++) {
          var axisDim = axisDimList[i];

          var axisInfo = this._targetAxisInfoMap.get(axisDim);

          for (var j = 0; j < axisInfo.indexList.length; j++) {
            var proxy = this.getAxisProxy(axisDim, axisInfo.indexList[j]);

            if (proxy.hostedBy(this)) {
              return proxy;
            }

            if (!firstProxy) {
              firstProxy = proxy;
            }
          }
        } // If no hosted proxy found, still need to return a proxy.
        // This case always happens in toolbox dataZoom, where axes are all hosted by
        // other dataZooms.


        return firstProxy;
      };

      DataZoomModel.prototype.getRangePropMode = function () {
        return this._rangePropMode.slice();
      };

      DataZoomModel.prototype.getOrient = function () {
        if ("development" !== 'production') {
          // Should not be called before initialized.
          assert(this._orient);
        }

        return this._orient;
      };

      DataZoomModel.type = 'dataZoom';
      DataZoomModel.dependencies = ['xAxis', 'yAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'series', 'toolbox'];
      DataZoomModel.defaultOption = {
        // zlevel: 0,
        z: 4,
        filterMode: 'filter',
        start: 0,
        end: 100
      };
      return DataZoomModel;
    }(ComponentModel);
    /**
     * Retrieve those raw params from option, which will be cached separately,
     * because they will be overwritten by normalized/calculated values in the main
     * process.
     */


    function retrieveRawOption(option) {
      var ret = {};
      each(['start', 'end', 'startValue', 'endValue', 'throttle'], function (name) {
        option.hasOwnProperty(name) && (ret[name] = option[name]);
      });
      return ret;
    }

    var SelectDataZoomModel =
    /** @class */
    function (_super) {
      __extends(SelectDataZoomModel, _super);

      function SelectDataZoomModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SelectDataZoomModel.type;
        return _this;
      }

      SelectDataZoomModel.type = 'dataZoom.select';
      return SelectDataZoomModel;
    }(DataZoomModel);

    var DataZoomView =
    /** @class */
    function (_super) {
      __extends(DataZoomView, _super);

      function DataZoomView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = DataZoomView.type;
        return _this;
      }

      DataZoomView.prototype.render = function (dataZoomModel, ecModel, api, payload) {
        this.dataZoomModel = dataZoomModel;
        this.ecModel = ecModel;
        this.api = api;
      };

      DataZoomView.type = 'dataZoom';
      return DataZoomView;
    }(ComponentView);

    var SelectDataZoomView =
    /** @class */
    function (_super) {
      __extends(SelectDataZoomView, _super);

      function SelectDataZoomView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SelectDataZoomView.type;
        return _this;
      }

      SelectDataZoomView.type = 'dataZoom.select';
      return SelectDataZoomView;
    }(DataZoomView);

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */

    /**
     * Calculate slider move result.
     * Usage:
     * (1) If both handle0 and handle1 are needed to be moved, set minSpan the same as
     * maxSpan and the same as `Math.abs(handleEnd[1] - handleEnds[0])`.
     * (2) If handle0 is forbidden to cross handle1, set minSpan as `0`.
     *
     * @param delta Move length.
     * @param handleEnds handleEnds[0] can be bigger then handleEnds[1].
     *              handleEnds will be modified in this method.
     * @param extent handleEnds is restricted by extent.
     *              extent[0] should less or equals than extent[1].
     * @param handleIndex Can be 'all', means that both move the two handleEnds.
     * @param minSpan The range of dataZoom can not be smaller than that.
     *              If not set, handle0 and cross handle1. If set as a non-negative
     *              number (including `0`), handles will push each other when reaching
     *              the minSpan.
     * @param maxSpan The range of dataZoom can not be larger than that.
     * @return The input handleEnds.
     */
    function sliderMove(delta, handleEnds, extent, handleIndex, minSpan, maxSpan) {
      delta = delta || 0;
      var extentSpan = extent[1] - extent[0]; // Notice maxSpan and minSpan can be null/undefined.

      if (minSpan != null) {
        minSpan = restrict(minSpan, [0, extentSpan]);
      }

      if (maxSpan != null) {
        maxSpan = Math.max(maxSpan, minSpan != null ? minSpan : 0);
      }

      if (handleIndex === 'all') {
        var handleSpan = Math.abs(handleEnds[1] - handleEnds[0]);
        handleSpan = restrict(handleSpan, [0, extentSpan]);
        minSpan = maxSpan = restrict(handleSpan, [minSpan, maxSpan]);
        handleIndex = 0;
      }

      handleEnds[0] = restrict(handleEnds[0], extent);
      handleEnds[1] = restrict(handleEnds[1], extent);
      var originalDistSign = getSpanSign(handleEnds, handleIndex);
      handleEnds[handleIndex] += delta; // Restrict in extent.

      var extentMinSpan = minSpan || 0;
      var realExtent = extent.slice();
      originalDistSign.sign < 0 ? realExtent[0] += extentMinSpan : realExtent[1] -= extentMinSpan;
      handleEnds[handleIndex] = restrict(handleEnds[handleIndex], realExtent); // Expand span.

      var currDistSign;
      currDistSign = getSpanSign(handleEnds, handleIndex);

      if (minSpan != null && (currDistSign.sign !== originalDistSign.sign || currDistSign.span < minSpan)) {
        // If minSpan exists, 'cross' is forbidden.
        handleEnds[1 - handleIndex] = handleEnds[handleIndex] + originalDistSign.sign * minSpan;
      } // Shrink span.


      currDistSign = getSpanSign(handleEnds, handleIndex);

      if (maxSpan != null && currDistSign.span > maxSpan) {
        handleEnds[1 - handleIndex] = handleEnds[handleIndex] + currDistSign.sign * maxSpan;
      }

      return handleEnds;
    }

    function getSpanSign(handleEnds, handleIndex) {
      var dist = handleEnds[handleIndex] - handleEnds[1 - handleIndex]; // If `handleEnds[0] === handleEnds[1]`, always believe that handleEnd[0]
      // is at left of handleEnds[1] for non-cross case.

      return {
        span: Math.abs(dist),
        sign: dist > 0 ? -1 : dist < 0 ? 1 : handleIndex ? -1 : 1
      };
    }

    function restrict(value, extend) {
      return Math.min(extend[1] != null ? extend[1] : Infinity, Math.max(extend[0] != null ? extend[0] : -Infinity, value));
    }

    var each$4 = each;
    var asc$1 = asc;
    /**
     * Operate single axis.
     * One axis can only operated by one axis operator.
     * Different dataZoomModels may be defined to operate the same axis.
     * (i.e. 'inside' data zoom and 'slider' data zoom components)
     * So dataZoomModels share one axisProxy in that case.
     */

    var AxisProxy =
    /** @class */
    function () {
      function AxisProxy(dimName, axisIndex, dataZoomModel, ecModel) {
        this._dimName = dimName;
        this._axisIndex = axisIndex;
        this.ecModel = ecModel;
        this._dataZoomModel = dataZoomModel; // /**
        //  * @readOnly
        //  * @private
        //  */
        // this.hasSeriesStacked;
      }
      /**
       * Whether the axisProxy is hosted by dataZoomModel.
       */


      AxisProxy.prototype.hostedBy = function (dataZoomModel) {
        return this._dataZoomModel === dataZoomModel;
      };
      /**
       * @return Value can only be NaN or finite value.
       */


      AxisProxy.prototype.getDataValueWindow = function () {
        return this._valueWindow.slice();
      };
      /**
       * @return {Array.<number>}
       */


      AxisProxy.prototype.getDataPercentWindow = function () {
        return this._percentWindow.slice();
      };

      AxisProxy.prototype.getTargetSeriesModels = function () {
        var seriesModels = [];
        this.ecModel.eachSeries(function (seriesModel) {
          if (isCoordSupported(seriesModel)) {
            var axisMainType = getAxisMainType(this._dimName);
            var axisModel = seriesModel.getReferringComponents(axisMainType, SINGLE_REFERRING).models[0];

            if (axisModel && this._axisIndex === axisModel.componentIndex) {
              seriesModels.push(seriesModel);
            }
          }
        }, this);
        return seriesModels;
      };

      AxisProxy.prototype.getAxisModel = function () {
        return this.ecModel.getComponent(this._dimName + 'Axis', this._axisIndex);
      };

      AxisProxy.prototype.getMinMaxSpan = function () {
        return clone(this._minMaxSpan);
      };
      /**
       * Only calculate by given range and this._dataExtent, do not change anything.
       */


      AxisProxy.prototype.calculateDataWindow = function (opt) {
        var dataExtent = this._dataExtent;
        var axisModel = this.getAxisModel();
        var scale = axisModel.axis.scale;

        var rangePropMode = this._dataZoomModel.getRangePropMode();

        var percentExtent = [0, 100];
        var percentWindow = [];
        var valueWindow = [];
        var hasPropModeValue;
        each$4(['start', 'end'], function (prop, idx) {
          var boundPercent = opt[prop];
          var boundValue = opt[prop + 'Value']; // Notice: dataZoom is based either on `percentProp` ('start', 'end') or
          // on `valueProp` ('startValue', 'endValue'). (They are based on the data extent
          // but not min/max of axis, which will be calculated by data window then).
          // The former one is suitable for cases that a dataZoom component controls multiple
          // axes with different unit or extent, and the latter one is suitable for accurate
          // zoom by pixel (e.g., in dataZoomSelect).
          // we use `getRangePropMode()` to mark which prop is used. `rangePropMode` is updated
          // only when setOption or dispatchAction, otherwise it remains its original value.
          // (Why not only record `percentProp` and always map to `valueProp`? Because
          // the map `valueProp` -> `percentProp` -> `valueProp` probably not the original
          // `valueProp`. consider two axes constrolled by one dataZoom. They have different
          // data extent. All of values that are overflow the `dataExtent` will be calculated
          // to percent '100%').

          if (rangePropMode[idx] === 'percent') {
            boundPercent == null && (boundPercent = percentExtent[idx]); // Use scale.parse to math round for category or time axis.

            boundValue = scale.parse(linearMap(boundPercent, percentExtent, dataExtent));
          } else {
            hasPropModeValue = true;
            boundValue = boundValue == null ? dataExtent[idx] : scale.parse(boundValue); // Calculating `percent` from `value` may be not accurate, because
            // This calculation can not be inversed, because all of values that
            // are overflow the `dataExtent` will be calculated to percent '100%'

            boundPercent = linearMap(boundValue, dataExtent, percentExtent);
          } // valueWindow[idx] = round(boundValue);
          // percentWindow[idx] = round(boundPercent);
          // fallback to extent start/end when parsed value or percent is invalid


          valueWindow[idx] = boundValue == null || isNaN(boundValue) ? dataExtent[idx] : boundValue;
          percentWindow[idx] = boundPercent == null || isNaN(boundPercent) ? percentExtent[idx] : boundPercent;
        });
        asc$1(valueWindow);
        asc$1(percentWindow); // The windows from user calling of `dispatchAction` might be out of the extent,
        // or do not obey the `min/maxSpan`, `min/maxValueSpan`. But we don't restrict window
        // by `zoomLock` here, because we see `zoomLock` just as a interaction constraint,
        // where API is able to initialize/modify the window size even though `zoomLock`
        // specified.

        var spans = this._minMaxSpan;
        hasPropModeValue ? restrictSet(valueWindow, percentWindow, dataExtent, percentExtent, false) : restrictSet(percentWindow, valueWindow, percentExtent, dataExtent, true);

        function restrictSet(fromWindow, toWindow, fromExtent, toExtent, toValue) {
          var suffix = toValue ? 'Span' : 'ValueSpan';
          sliderMove(0, fromWindow, fromExtent, 'all', spans['min' + suffix], spans['max' + suffix]);

          for (var i = 0; i < 2; i++) {
            toWindow[i] = linearMap(fromWindow[i], fromExtent, toExtent, true);
            toValue && (toWindow[i] = scale.parse(toWindow[i]));
          }
        }

        return {
          valueWindow: valueWindow,
          percentWindow: percentWindow
        };
      };
      /**
       * Notice: reset should not be called before series.restoreData() is called,
       * so it is recommended to be called in "process stage" but not "model init
       * stage".
       */


      AxisProxy.prototype.reset = function (dataZoomModel) {
        if (dataZoomModel !== this._dataZoomModel) {
          return;
        }

        var targetSeries = this.getTargetSeriesModels(); // Culculate data window and data extent, and record them.

        this._dataExtent = calculateDataExtent(this, this._dimName, targetSeries); // `calculateDataWindow` uses min/maxSpan.

        this._updateMinMaxSpan();

        var dataWindow = this.calculateDataWindow(dataZoomModel.settledOption);
        this._valueWindow = dataWindow.valueWindow;
        this._percentWindow = dataWindow.percentWindow; // Update axis setting then.

        this._setAxisModel();
      };

      AxisProxy.prototype.filterData = function (dataZoomModel, api) {
        if (dataZoomModel !== this._dataZoomModel) {
          return;
        }

        var axisDim = this._dimName;
        var seriesModels = this.getTargetSeriesModels();
        var filterMode = dataZoomModel.get('filterMode');
        var valueWindow = this._valueWindow;

        if (filterMode === 'none') {
          return;
        } // FIXME
        // Toolbox may has dataZoom injected. And if there are stacked bar chart
        // with NaN data, NaN will be filtered and stack will be wrong.
        // So we need to force the mode to be set empty.
        // In fect, it is not a big deal that do not support filterMode-'filter'
        // when using toolbox#dataZoom, utill tooltip#dataZoom support "single axis
        // selection" some day, which might need "adapt to data extent on the
        // otherAxis", which is disabled by filterMode-'empty'.
        // But currently, stack has been fixed to based on value but not index,
        // so this is not an issue any more.
        // let otherAxisModel = this.getOtherAxisModel();
        // if (dataZoomModel.get('$fromToolbox')
        //     && otherAxisModel
        //     && otherAxisModel.hasSeriesStacked
        // ) {
        //     filterMode = 'empty';
        // }
        // TODO
        // filterMode 'weakFilter' and 'empty' is not optimized for huge data yet.


        each$4(seriesModels, function (seriesModel) {
          var seriesData = seriesModel.getData();
          var dataDims = seriesData.mapDimensionsAll(axisDim);

          if (!dataDims.length) {
            return;
          }

          if (filterMode === 'weakFilter') {
            var store_1 = seriesData.getStore();
            var dataDimIndices_1 = map(dataDims, function (dim) {
              return seriesData.getDimensionIndex(dim);
            }, seriesData);
            seriesData.filterSelf(function (dataIndex) {
              var leftOut;
              var rightOut;
              var hasValue;

              for (var i = 0; i < dataDims.length; i++) {
                var value = store_1.get(dataDimIndices_1[i], dataIndex);
                var thisHasValue = !isNaN(value);
                var thisLeftOut = value < valueWindow[0];
                var thisRightOut = value > valueWindow[1];

                if (thisHasValue && !thisLeftOut && !thisRightOut) {
                  return true;
                }

                thisHasValue && (hasValue = true);
                thisLeftOut && (leftOut = true);
                thisRightOut && (rightOut = true);
              } // If both left out and right out, do not filter.


              return hasValue && leftOut && rightOut;
            });
          } else {
            each$4(dataDims, function (dim) {
              if (filterMode === 'empty') {
                seriesModel.setData(seriesData = seriesData.map(dim, function (value) {
                  return !isInWindow(value) ? NaN : value;
                }));
              } else {
                var range = {};
                range[dim] = valueWindow; // console.time('select');

                seriesData.selectRange(range); // console.timeEnd('select');
              }
            });
          }

          each$4(dataDims, function (dim) {
            seriesData.setApproximateExtent(valueWindow, dim);
          });
        });

        function isInWindow(value) {
          return value >= valueWindow[0] && value <= valueWindow[1];
        }
      };

      AxisProxy.prototype._updateMinMaxSpan = function () {
        var minMaxSpan = this._minMaxSpan = {};
        var dataZoomModel = this._dataZoomModel;
        var dataExtent = this._dataExtent;
        each$4(['min', 'max'], function (minMax) {
          var percentSpan = dataZoomModel.get(minMax + 'Span');
          var valueSpan = dataZoomModel.get(minMax + 'ValueSpan');
          valueSpan != null && (valueSpan = this.getAxisModel().axis.scale.parse(valueSpan)); // minValueSpan and maxValueSpan has higher priority than minSpan and maxSpan

          if (valueSpan != null) {
            percentSpan = linearMap(dataExtent[0] + valueSpan, dataExtent, [0, 100], true);
          } else if (percentSpan != null) {
            valueSpan = linearMap(percentSpan, [0, 100], dataExtent, true) - dataExtent[0];
          }

          minMaxSpan[minMax + 'Span'] = percentSpan;
          minMaxSpan[minMax + 'ValueSpan'] = valueSpan;
        }, this);
      };

      AxisProxy.prototype._setAxisModel = function () {
        var axisModel = this.getAxisModel();
        var percentWindow = this._percentWindow;
        var valueWindow = this._valueWindow;

        if (!percentWindow) {
          return;
        } // [0, 500]: arbitrary value, guess axis extent.


        var precision = getPixelPrecision(valueWindow, [0, 500]);
        precision = Math.min(precision, 20); // For value axis, if min/max/scale are not set, we just use the extent obtained
        // by series data, which may be a little different from the extent calculated by
        // `axisHelper.getScaleExtent`. But the different just affects the experience a
        // little when zooming. So it will not be fixed until some users require it strongly.

        var rawExtentInfo = axisModel.axis.scale.rawExtentInfo;

        if (percentWindow[0] !== 0) {
          rawExtentInfo.setDeterminedMinMax('min', +valueWindow[0].toFixed(precision));
        }

        if (percentWindow[1] !== 100) {
          rawExtentInfo.setDeterminedMinMax('max', +valueWindow[1].toFixed(precision));
        }

        rawExtentInfo.freeze();
      };

      return AxisProxy;
    }();

    function calculateDataExtent(axisProxy, axisDim, seriesModels) {
      var dataExtent = [Infinity, -Infinity];
      each$4(seriesModels, function (seriesModel) {
        unionAxisExtentFromData(dataExtent, seriesModel.getData(), axisDim);
      }); // It is important to get "consistent" extent when more then one axes is
      // controlled by a `dataZoom`, otherwise those axes will not be synchronized
      // when zooming. But it is difficult to know what is "consistent", considering
      // axes have different type or even different meanings (For example, two
      // time axes are used to compare data of the same date in different years).
      // So basically dataZoom just obtains extent by series.data (in category axis
      // extent can be obtained from axis.data).
      // Nevertheless, user can set min/max/scale on axes to make extent of axes
      // consistent.

      var axisModel = axisProxy.getAxisModel();
      var rawExtentResult = ensureScaleRawExtentInfo(axisModel.axis.scale, axisModel, dataExtent).calculate();
      return [rawExtentResult.min, rawExtentResult.max];
    }

    var dataZoomProcessor = {
      // `dataZoomProcessor` will only be performed in needed series. Consider if
      // there is a line series and a pie series, it is better not to update the
      // line series if only pie series is needed to be updated.
      getTargetSeries: function (ecModel) {
        function eachAxisModel(cb) {
          ecModel.eachComponent('dataZoom', function (dataZoomModel) {
            dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
              var axisModel = ecModel.getComponent(getAxisMainType(axisDim), axisIndex);
              cb(axisDim, axisIndex, axisModel, dataZoomModel);
            });
          });
        } // FIXME: it brings side-effect to `getTargetSeries`.
        // Prepare axis proxies.


        eachAxisModel(function (axisDim, axisIndex, axisModel, dataZoomModel) {
          // dispose all last axis proxy, in case that some axis are deleted.
          axisModel.__dzAxisProxy = null;
        });
        var proxyList = [];
        eachAxisModel(function (axisDim, axisIndex, axisModel, dataZoomModel) {
          // Different dataZooms may constrol the same axis. In that case,
          // an axisProxy serves both of them.
          if (!axisModel.__dzAxisProxy) {
            // Use the first dataZoomModel as the main model of axisProxy.
            axisModel.__dzAxisProxy = new AxisProxy(axisDim, axisIndex, dataZoomModel, ecModel);
            proxyList.push(axisModel.__dzAxisProxy);
          }
        });
        var seriesModelMap = createHashMap();
        each(proxyList, function (axisProxy) {
          each(axisProxy.getTargetSeriesModels(), function (seriesModel) {
            seriesModelMap.set(seriesModel.uid, seriesModel);
          });
        });
        return seriesModelMap;
      },
      // Consider appendData, where filter should be performed. Because data process is
      // in block mode currently, it is not need to worry about that the overallProgress
      // execute every frame.
      overallReset: function (ecModel, api) {
        ecModel.eachComponent('dataZoom', function (dataZoomModel) {
          // We calculate window and reset axis here but not in model
          // init stage and not after action dispatch handler, because
          // reset should be called after seriesData.restoreData.
          dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
            dataZoomModel.getAxisProxy(axisDim, axisIndex).reset(dataZoomModel);
          }); // Caution: data zoom filtering is order sensitive when using
          // percent range and no min/max/scale set on axis.
          // For example, we have dataZoom definition:
          // [
          //      {xAxisIndex: 0, start: 30, end: 70},
          //      {yAxisIndex: 0, start: 20, end: 80}
          // ]
          // In this case, [20, 80] of y-dataZoom should be based on data
          // that have filtered by x-dataZoom using range of [30, 70],
          // but should not be based on full raw data. Thus sliding
          // x-dataZoom will change both ranges of xAxis and yAxis,
          // while sliding y-dataZoom will only change the range of yAxis.
          // So we should filter x-axis after reset x-axis immediately,
          // and then reset y-axis and filter y-axis.

          dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
            dataZoomModel.getAxisProxy(axisDim, axisIndex).filterData(dataZoomModel, api);
          });
        });
        ecModel.eachComponent('dataZoom', function (dataZoomModel) {
          // Fullfill all of the range props so that user
          // is able to get them from chart.getOption().
          var axisProxy = dataZoomModel.findRepresentativeAxisProxy();

          if (axisProxy) {
            var percentRange = axisProxy.getDataPercentWindow();
            var valueRange = axisProxy.getDataValueWindow();
            dataZoomModel.setCalculatedRange({
              start: percentRange[0],
              end: percentRange[1],
              startValue: valueRange[0],
              endValue: valueRange[1]
            });
          }
        });
      }
    };

    function installDataZoomAction(registers) {
      registers.registerAction('dataZoom', function (payload, ecModel) {
        var effectedModels = findEffectedDataZooms(ecModel, payload);
        each(effectedModels, function (dataZoomModel) {
          dataZoomModel.setRawRange({
            start: payload.start,
            end: payload.end,
            startValue: payload.startValue,
            endValue: payload.endValue
          });
        });
      });
    }

    var installed = false;
    function installCommon(registers) {
      if (installed) {
        return;
      }

      installed = true;
      registers.registerProcessor(registers.PRIORITY.PROCESSOR.FILTER, dataZoomProcessor);
      installDataZoomAction(registers);
      registers.registerSubTypeDefaulter('dataZoom', function () {
        // Default 'slider' when no type specified.
        return 'slider';
      });
    }

    function install$a(registers) {
      registers.registerComponentModel(SelectDataZoomModel);
      registers.registerComponentView(SelectDataZoomView);
      installCommon(registers);
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    var ToolboxFeature =
    /** @class */
    function () {
      function ToolboxFeature() {}

      return ToolboxFeature;
    }();
    var features = {};
    function registerFeature(name, ctor) {
      features[name] = ctor;
    }
    function getFeature(name) {
      return features[name];
    }

    var ToolboxModel =
    /** @class */
    function (_super) {
      __extends(ToolboxModel, _super);

      function ToolboxModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ToolboxModel.type;
        return _this;
      }

      ToolboxModel.prototype.optionUpdated = function () {
        _super.prototype.optionUpdated.apply(this, arguments);

        var ecModel = this.ecModel;
        each(this.option.feature, function (featureOpt, featureName) {
          var Feature = getFeature(featureName);

          if (Feature) {
            if (Feature.getDefaultOption) {
              Feature.defaultOption = Feature.getDefaultOption(ecModel);
            }

            merge(featureOpt, Feature.defaultOption);
          }
        });
      };

      ToolboxModel.type = 'toolbox';
      ToolboxModel.layoutMode = {
        type: 'box',
        ignoreSize: true
      };
      ToolboxModel.defaultOption = {
        show: true,
        z: 6,
        // zlevel: 0,
        orient: 'horizontal',
        left: 'right',
        top: 'top',
        // right
        // bottom
        backgroundColor: 'transparent',
        borderColor: '#ccc',
        borderRadius: 0,
        borderWidth: 0,
        padding: 5,
        itemSize: 15,
        itemGap: 8,
        showTitle: true,
        iconStyle: {
          borderColor: '#666',
          color: 'none'
        },
        emphasis: {
          iconStyle: {
            borderColor: '#3E98C5'
          }
        },
        // textStyle: {},
        // feature
        tooltip: {
          show: false,
          position: 'bottom'
        }
      };
      return ToolboxModel;
    }(ComponentModel);

    /**
     * Layout list like component.
     * It will box layout each items in group of component and then position the whole group in the viewport
     * @param {module:zrender/group/Group} group
     * @param {module:echarts/model/Component} componentModel
     * @param {module:echarts/ExtensionAPI}
     */

    function layout$2(group, componentModel, api) {
      var boxLayoutParams = componentModel.getBoxLayoutParams();
      var padding = componentModel.get('padding');
      var viewportSize = {
        width: api.getWidth(),
        height: api.getHeight()
      };
      var rect = getLayoutRect(boxLayoutParams, viewportSize, padding);
      box(componentModel.get('orient'), group, componentModel.get('itemGap'), rect.width, rect.height);
      positionElement(group, boxLayoutParams, viewportSize, padding);
    }
    function makeBackground(rect, componentModel) {
      var padding = normalizeCssArray$1(componentModel.get('padding'));
      var style = componentModel.getItemStyle(['color', 'opacity']);
      style.fill = componentModel.get('backgroundColor');
      rect = new Rect({
        shape: {
          x: rect.x - padding[3],
          y: rect.y - padding[0],
          width: rect.width + padding[1] + padding[3],
          height: rect.height + padding[0] + padding[2],
          r: componentModel.get('borderRadius')
        },
        style: style,
        silent: true,
        z2: -1
      }); // FIXME
      // `subPixelOptimizeRect` may bring some gap between edge of viewpart
      // and background rect when setting like `left: 0`, `top: 0`.
      // graphic.subPixelOptimizeRect(rect);

      return rect;
    }

    var ToolboxView =
    /** @class */
    function (_super) {
      __extends(ToolboxView, _super);

      function ToolboxView() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      ToolboxView.prototype.render = function (toolboxModel, ecModel, api, payload) {
        var group = this.group;
        group.removeAll();

        if (!toolboxModel.get('show')) {
          return;
        }

        var itemSize = +toolboxModel.get('itemSize');
        var isVertical = toolboxModel.get('orient') === 'vertical';
        var featureOpts = toolboxModel.get('feature') || {};
        var features = this._features || (this._features = {});
        var featureNames = [];
        each(featureOpts, function (opt, name) {
          featureNames.push(name);
        });
        new DataDiffer(this._featureNames || [], featureNames).add(processFeature).update(processFeature).remove(curry(processFeature, null)).execute(); // Keep for diff.

        this._featureNames = featureNames;

        function processFeature(newIndex, oldIndex) {
          var featureName = featureNames[newIndex];
          var oldName = featureNames[oldIndex];
          var featureOpt = featureOpts[featureName];
          var featureModel = new Model(featureOpt, toolboxModel, toolboxModel.ecModel);
          var feature; // FIX#11236, merge feature title from MagicType newOption. TODO: consider seriesIndex ?

          if (payload && payload.newTitle != null && payload.featureName === featureName) {
            featureOpt.title = payload.newTitle;
          }

          if (featureName && !oldName) {
            // Create
            if (isUserFeatureName(featureName)) {
              feature = {
                onclick: featureModel.option.onclick,
                featureName: featureName
              };
            } else {
              var Feature = getFeature(featureName);

              if (!Feature) {
                return;
              }

              feature = new Feature();
            }

            features[featureName] = feature;
          } else {
            feature = features[oldName]; // If feature does not exsit.

            if (!feature) {
              return;
            }
          }

          feature.uid = getUID('toolbox-feature');
          feature.model = featureModel;
          feature.ecModel = ecModel;
          feature.api = api;
          var isToolboxFeature = feature instanceof ToolboxFeature;

          if (!featureName && oldName) {
            isToolboxFeature && feature.dispose && feature.dispose(ecModel, api);
            return;
          }

          if (!featureModel.get('show') || isToolboxFeature && feature.unusable) {
            isToolboxFeature && feature.remove && feature.remove(ecModel, api);
            return;
          }

          createIconPaths(featureModel, feature, featureName);

          featureModel.setIconStatus = function (iconName, status) {
            var option = this.option;
            var iconPaths = this.iconPaths;
            option.iconStatus = option.iconStatus || {};
            option.iconStatus[iconName] = status;

            if (iconPaths[iconName]) {
              (status === 'emphasis' ? enterEmphasis : leaveEmphasis)(iconPaths[iconName]);
            }
          };

          if (feature instanceof ToolboxFeature) {
            if (feature.render) {
              feature.render(featureModel, ecModel, api, payload);
            }
          }
        }

        function createIconPaths(featureModel, feature, featureName) {
          var iconStyleModel = featureModel.getModel('iconStyle');
          var iconStyleEmphasisModel = featureModel.getModel(['emphasis', 'iconStyle']); // If one feature has mutiple icon. they are orginaized as
          // {
          //     icon: {
          //         foo: '',
          //         bar: ''
          //     },
          //     title: {
          //         foo: '',
          //         bar: ''
          //     }
          // }

          var icons = feature instanceof ToolboxFeature && feature.getIcons ? feature.getIcons() : featureModel.get('icon');
          var titles = featureModel.get('title') || {};
          var iconsMap;
          var titlesMap;

          if (isString(icons)) {
            iconsMap = {};
            iconsMap[featureName] = icons;
          } else {
            iconsMap = icons;
          }

          if (isString(titles)) {
            titlesMap = {};
            titlesMap[featureName] = titles;
          } else {
            titlesMap = titles;
          }

          var iconPaths = featureModel.iconPaths = {};
          each(iconsMap, function (iconStr, iconName) {
            var path = createIcon(iconStr, {}, {
              x: -itemSize / 2,
              y: -itemSize / 2,
              width: itemSize,
              height: itemSize
            }); // TODO handling image

            path.setStyle(iconStyleModel.getItemStyle());
            var pathEmphasisState = path.ensureState('emphasis');
            pathEmphasisState.style = iconStyleEmphasisModel.getItemStyle(); // Text position calculation

            var textContent = new ZRText({
              style: {
                text: titlesMap[iconName],
                align: iconStyleEmphasisModel.get('textAlign'),
                borderRadius: iconStyleEmphasisModel.get('textBorderRadius'),
                padding: iconStyleEmphasisModel.get('textPadding'),
                fill: null
              },
              ignore: true
            });
            path.setTextContent(textContent);
            setTooltipConfig({
              el: path,
              componentModel: toolboxModel,
              itemName: iconName,
              formatterParamsExtra: {
                title: titlesMap[iconName]
              }
            });
            path.__title = titlesMap[iconName];
            path.on('mouseover', function () {
              // Should not reuse above hoverStyle, which might be modified.
              var hoverStyle = iconStyleEmphasisModel.getItemStyle();
              var defaultTextPosition = isVertical ? toolboxModel.get('right') == null && toolboxModel.get('left') !== 'right' ? 'right' : 'left' : toolboxModel.get('bottom') == null && toolboxModel.get('top') !== 'bottom' ? 'bottom' : 'top';
              textContent.setStyle({
                fill: iconStyleEmphasisModel.get('textFill') || hoverStyle.fill || hoverStyle.stroke || '#000',
                backgroundColor: iconStyleEmphasisModel.get('textBackgroundColor')
              });
              path.setTextConfig({
                position: iconStyleEmphasisModel.get('textPosition') || defaultTextPosition
              });
              textContent.ignore = !toolboxModel.get('showTitle'); // Use enterEmphasis and leaveEmphasis provide by ec.
              // There are flags managed by the echarts.

              api.enterEmphasis(this);
            }).on('mouseout', function () {
              if (featureModel.get(['iconStatus', iconName]) !== 'emphasis') {
                api.leaveEmphasis(this);
              }

              textContent.hide();
            });
            (featureModel.get(['iconStatus', iconName]) === 'emphasis' ? enterEmphasis : leaveEmphasis)(path);
            group.add(path);
            path.on('click', bind(feature.onclick, feature, ecModel, api, iconName));
            iconPaths[iconName] = path;
          });
        }

        layout$2(group, toolboxModel, api); // Render background after group is layout
        // FIXME

        group.add(makeBackground(group.getBoundingRect(), toolboxModel)); // Adjust icon title positions to avoid them out of screen

        isVertical || group.eachChild(function (icon) {
          var titleText = icon.__title; // const hoverStyle = icon.hoverStyle;
          // TODO simplify code?

          var emphasisState = icon.ensureState('emphasis');
          var emphasisTextConfig = emphasisState.textConfig || (emphasisState.textConfig = {});
          var textContent = icon.getTextContent();
          var emphasisTextState = textContent && textContent.ensureState('emphasis'); // May be background element

          if (emphasisTextState && !isFunction(emphasisTextState) && titleText) {
            var emphasisTextStyle = emphasisTextState.style || (emphasisTextState.style = {});
            var rect = getBoundingRect(titleText, ZRText.makeFont(emphasisTextStyle));
            var offsetX = icon.x + group.x;
            var offsetY = icon.y + group.y + itemSize;
            var needPutOnTop = false;

            if (offsetY + rect.height > api.getHeight()) {
              emphasisTextConfig.position = 'top';
              needPutOnTop = true;
            }

            var topOffset = needPutOnTop ? -5 - rect.height : itemSize + 10;

            if (offsetX + rect.width / 2 > api.getWidth()) {
              emphasisTextConfig.position = ['100%', topOffset];
              emphasisTextStyle.align = 'right';
            } else if (offsetX - rect.width / 2 < 0) {
              emphasisTextConfig.position = [0, topOffset];
              emphasisTextStyle.align = 'left';
            }
          }
        });
      };

      ToolboxView.prototype.updateView = function (toolboxModel, ecModel, api, payload) {
        each(this._features, function (feature) {
          feature instanceof ToolboxFeature && feature.updateView && feature.updateView(feature.model, ecModel, api, payload);
        });
      }; // updateLayout(toolboxModel, ecModel, api, payload) {
      //     zrUtil.each(this._features, function (feature) {
      //         feature.updateLayout && feature.updateLayout(feature.model, ecModel, api, payload);
      //     });
      // },


      ToolboxView.prototype.remove = function (ecModel, api) {
        each(this._features, function (feature) {
          feature instanceof ToolboxFeature && feature.remove && feature.remove(ecModel, api);
        });
        this.group.removeAll();
      };

      ToolboxView.prototype.dispose = function (ecModel, api) {
        each(this._features, function (feature) {
          feature instanceof ToolboxFeature && feature.dispose && feature.dispose(ecModel, api);
        });
      };

      ToolboxView.type = 'toolbox';
      return ToolboxView;
    }(ComponentView);

    function isUserFeatureName(featureName) {
      return featureName.indexOf('my') === 0;
    }

    /* global window, document */

    var SaveAsImage =
    /** @class */
    function (_super) {
      __extends(SaveAsImage, _super);

      function SaveAsImage() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      SaveAsImage.prototype.onclick = function (ecModel, api) {
        var model = this.model;
        var title = model.get('name') || ecModel.get('title.0.text') || 'echarts';
        var isSvg = api.getZr().painter.getType() === 'svg';
        var type = isSvg ? 'svg' : model.get('type', true) || 'png';
        var url = api.getConnectedDataURL({
          type: type,
          backgroundColor: model.get('backgroundColor', true) || ecModel.get('backgroundColor') || '#fff',
          connectedBackgroundColor: model.get('connectedBackgroundColor'),
          excludeComponents: model.get('excludeComponents'),
          pixelRatio: model.get('pixelRatio')
        });
        var browser = env.browser; // Chrome, Firefox, New Edge

        if (isFunction(MouseEvent) && (browser.newEdge || !browser.ie && !browser.edge)) {
          var $a = document.createElement('a');
          $a.download = title + '.' + type;
          $a.target = '_blank';
          $a.href = url;
          var evt = new MouseEvent('click', {
            // some micro front-end framework， window maybe is a Proxy
            view: document.defaultView,
            bubbles: true,
            cancelable: false
          });
          $a.dispatchEvent(evt);
        } // IE or old Edge
        else {
            // @ts-ignore
            if (window.navigator.msSaveOrOpenBlob || isSvg) {
              var parts = url.split(','); // data:[<mime type>][;charset=<charset>][;base64],<encoded data>

              var base64Encoded = parts[0].indexOf('base64') > -1;
              var bstr = isSvg // should decode the svg data uri first
              ? decodeURIComponent(parts[1]) : parts[1]; // only `atob` when the data uri is encoded with base64
              // otherwise, like `svg` data uri exported by zrender,
              // there will be an error, for it's not encoded with base64.
              // (just a url-encoded string through `encodeURIComponent`)

              base64Encoded && (bstr = window.atob(bstr));
              var filename = title + '.' + type; // @ts-ignore

              if (window.navigator.msSaveOrOpenBlob) {
                var n = bstr.length;
                var u8arr = new Uint8Array(n);

                while (n--) {
                  u8arr[n] = bstr.charCodeAt(n);
                }

                var blob = new Blob([u8arr]); // @ts-ignore

                window.navigator.msSaveOrOpenBlob(blob, filename);
              } else {
                var frame = document.createElement('iframe');
                document.body.appendChild(frame);
                var cw = frame.contentWindow;
                var doc = cw.document;
                doc.open('image/svg+xml', 'replace');
                doc.write(bstr);
                doc.close();
                cw.focus();
                doc.execCommand('SaveAs', true, filename);
                document.body.removeChild(frame);
              }
            } else {
              var lang = model.get('lang');
              var html = '' + '<body style="margin:0;">' + '<img src="' + url + '" style="max-width:100%;" title="' + (lang && lang[0] || '') + '" />' + '</body>';
              var tab = window.open();
              tab.document.write(html);
              tab.document.title = title;
            }
          }
      };

      SaveAsImage.getDefaultOption = function (ecModel) {
        var defaultOption = {
          show: true,
          icon: 'M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0',
          title: ecModel.getLocaleModel().get(['toolbox', 'saveAsImage', 'title']),
          type: 'png',
          // Default use option.backgroundColor
          // backgroundColor: '#fff',
          connectedBackgroundColor: '#fff',
          name: '',
          excludeComponents: ['toolbox'],
          // use current pixel ratio of device by default
          // pixelRatio: 1,
          lang: ecModel.getLocaleModel().get(['toolbox', 'saveAsImage', 'lang'])
        };
        return defaultOption;
      };

      return SaveAsImage;
    }(ToolboxFeature);

    var INNER_STACK_KEYWORD = '__ec_magicType_stack__';
    var radioTypes = [['line', 'bar'], ['stack']];

    var MagicType =
    /** @class */
    function (_super) {
      __extends(MagicType, _super);

      function MagicType() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      MagicType.prototype.getIcons = function () {
        var model = this.model;
        var availableIcons = model.get('icon');
        var icons = {};
        each(model.get('type'), function (type) {
          if (availableIcons[type]) {
            icons[type] = availableIcons[type];
          }
        });
        return icons;
      };

      MagicType.getDefaultOption = function (ecModel) {
        var defaultOption = {
          show: true,
          type: [],
          // Icon group
          icon: {
            line: 'M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4',
            bar: 'M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7',
            // eslint-disable-next-line
            stack: 'M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z' // jshint ignore:line

          },
          // `line`, `bar`, `stack`, `tiled`
          title: ecModel.getLocaleModel().get(['toolbox', 'magicType', 'title']),
          option: {},
          seriesIndex: {}
        };
        return defaultOption;
      };

      MagicType.prototype.onclick = function (ecModel, api, type) {
        var model = this.model;
        var seriesIndex = model.get(['seriesIndex', type]); // Not supported magicType

        if (!seriesOptGenreator[type]) {
          return;
        }

        var newOption = {
          series: []
        };

        var generateNewSeriesTypes = function (seriesModel) {
          var seriesType = seriesModel.subType;
          var seriesId = seriesModel.id;
          var newSeriesOpt = seriesOptGenreator[type](seriesType, seriesId, seriesModel, model);

          if (newSeriesOpt) {
            // PENDING If merge original option?
            defaults(newSeriesOpt, seriesModel.option);
            newOption.series.push(newSeriesOpt);
          } // Modify boundaryGap


          var coordSys = seriesModel.coordinateSystem;

          if (coordSys && coordSys.type === 'cartesian2d' && (type === 'line' || type === 'bar')) {
            var categoryAxis = coordSys.getAxesByScale('ordinal')[0];

            if (categoryAxis) {
              var axisDim = categoryAxis.dim;
              var axisType = axisDim + 'Axis';
              var axisModel = seriesModel.getReferringComponents(axisType, SINGLE_REFERRING).models[0];
              var axisIndex = axisModel.componentIndex;
              newOption[axisType] = newOption[axisType] || [];

              for (var i = 0; i <= axisIndex; i++) {
                newOption[axisType][axisIndex] = newOption[axisType][axisIndex] || {};
              }

              newOption[axisType][axisIndex].boundaryGap = type === 'bar';
            }
          }
        };

        each(radioTypes, function (radio) {
          if (indexOf(radio, type) >= 0) {
            each(radio, function (item) {
              model.setIconStatus(item, 'normal');
            });
          }
        });
        model.setIconStatus(type, 'emphasis');
        ecModel.eachComponent({
          mainType: 'series',
          query: seriesIndex == null ? null : {
            seriesIndex: seriesIndex
          }
        }, generateNewSeriesTypes);
        var newTitle;
        var currentType = type; // Change title of stack

        if (type === 'stack') {
          // use titles in model instead of ecModel
          // as stack and tiled appears in pair, just flip them
          // no need of checking stack state
          newTitle = merge({
            stack: model.option.title.tiled,
            tiled: model.option.title.stack
          }, model.option.title);

          if (model.get(['iconStatus', type]) !== 'emphasis') {
            currentType = 'tiled';
          }
        }

        api.dispatchAction({
          type: 'changeMagicType',
          currentType: currentType,
          newOption: newOption,
          newTitle: newTitle,
          featureName: 'magicType'
        });
      };

      return MagicType;
    }(ToolboxFeature);

    var seriesOptGenreator = {
      'line': function (seriesType, seriesId, seriesModel, model) {
        if (seriesType === 'bar') {
          return merge({
            id: seriesId,
            type: 'line',
            // Preserve data related option
            data: seriesModel.get('data'),
            stack: seriesModel.get('stack'),
            markPoint: seriesModel.get('markPoint'),
            markLine: seriesModel.get('markLine')
          }, model.get(['option', 'line']) || {}, true);
        }
      },
      'bar': function (seriesType, seriesId, seriesModel, model) {
        if (seriesType === 'line') {
          return merge({
            id: seriesId,
            type: 'bar',
            // Preserve data related option
            data: seriesModel.get('data'),
            stack: seriesModel.get('stack'),
            markPoint: seriesModel.get('markPoint'),
            markLine: seriesModel.get('markLine')
          }, model.get(['option', 'bar']) || {}, true);
        }
      },
      'stack': function (seriesType, seriesId, seriesModel, model) {
        var isStack = seriesModel.get('stack') === INNER_STACK_KEYWORD;

        if (seriesType === 'line' || seriesType === 'bar') {
          model.setIconStatus('stack', isStack ? 'normal' : 'emphasis');
          return merge({
            id: seriesId,
            stack: isStack ? '' : INNER_STACK_KEYWORD
          }, model.get(['option', 'stack']) || {}, true);
        }
      }
    }; // TODO: SELF REGISTERED.

    registerAction({
      type: 'changeMagicType',
      event: 'magicTypeChanged',
      update: 'prepareAndUpdate'
    }, function (payload, ecModel) {
      ecModel.mergeOption(payload.newOption);
    });

    /* global document */

    var BLOCK_SPLITER = new Array(60).join('-');
    var ITEM_SPLITER = '\t';
    /**
     * Group series into two types
     *  1. on category axis, like line, bar
     *  2. others, like scatter, pie
     */

    function groupSeries(ecModel) {
      var seriesGroupByCategoryAxis = {};
      var otherSeries = [];
      var meta = [];
      ecModel.eachRawSeries(function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys && (coordSys.type === 'cartesian2d' || coordSys.type === 'polar')) {
          // TODO: TYPE Consider polar? Include polar may increase unecessary bundle size.
          var baseAxis = coordSys.getBaseAxis();

          if (baseAxis.type === 'category') {
            var key = baseAxis.dim + '_' + baseAxis.index;

            if (!seriesGroupByCategoryAxis[key]) {
              seriesGroupByCategoryAxis[key] = {
                categoryAxis: baseAxis,
                valueAxis: coordSys.getOtherAxis(baseAxis),
                series: []
              };
              meta.push({
                axisDim: baseAxis.dim,
                axisIndex: baseAxis.index
              });
            }

            seriesGroupByCategoryAxis[key].series.push(seriesModel);
          } else {
            otherSeries.push(seriesModel);
          }
        } else {
          otherSeries.push(seriesModel);
        }
      });
      return {
        seriesGroupByCategoryAxis: seriesGroupByCategoryAxis,
        other: otherSeries,
        meta: meta
      };
    }
    /**
     * Assemble content of series on cateogory axis
     * @inner
     */


    function assembleSeriesWithCategoryAxis(groups) {
      var tables = [];
      each(groups, function (group, key) {
        var categoryAxis = group.categoryAxis;
        var valueAxis = group.valueAxis;
        var valueAxisDim = valueAxis.dim;
        var headers = [' '].concat(map(group.series, function (series) {
          return series.name;
        })); // @ts-ignore TODO Polar

        var columns = [categoryAxis.model.getCategories()];
        each(group.series, function (series) {
          var rawData = series.getRawData();
          columns.push(series.getRawData().mapArray(rawData.mapDimension(valueAxisDim), function (val) {
            return val;
          }));
        }); // Assemble table content

        var lines = [headers.join(ITEM_SPLITER)];

        for (var i = 0; i < columns[0].length; i++) {
          var items = [];

          for (var j = 0; j < columns.length; j++) {
            items.push(columns[j][i]);
          }

          lines.push(items.join(ITEM_SPLITER));
        }

        tables.push(lines.join('\n'));
      });
      return tables.join('\n\n' + BLOCK_SPLITER + '\n\n');
    }
    /**
     * Assemble content of other series
     */


    function assembleOtherSeries(series) {
      return map(series, function (series) {
        var data = series.getRawData();
        var lines = [series.name];
        var vals = [];
        data.each(data.dimensions, function () {
          var argLen = arguments.length;
          var dataIndex = arguments[argLen - 1];
          var name = data.getName(dataIndex);

          for (var i = 0; i < argLen - 1; i++) {
            vals[i] = arguments[i];
          }

          lines.push((name ? name + ITEM_SPLITER : '') + vals.join(ITEM_SPLITER));
        });
        return lines.join('\n');
      }).join('\n\n' + BLOCK_SPLITER + '\n\n');
    }

    function getContentFromModel(ecModel) {
      var result = groupSeries(ecModel);
      return {
        value: filter([assembleSeriesWithCategoryAxis(result.seriesGroupByCategoryAxis), assembleOtherSeries(result.other)], function (str) {
          return !!str.replace(/[\n\t\s]/g, '');
        }).join('\n\n' + BLOCK_SPLITER + '\n\n'),
        meta: result.meta
      };
    }

    function trim$1(str) {
      return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
    }
    /**
     * If a block is tsv format
     */


    function isTSVFormat(block) {
      // Simple method to find out if a block is tsv format
      var firstLine = block.slice(0, block.indexOf('\n'));

      if (firstLine.indexOf(ITEM_SPLITER) >= 0) {
        return true;
      }
    }

    var itemSplitRegex = new RegExp('[' + ITEM_SPLITER + ']+', 'g');
    /**
     * @param {string} tsv
     * @return {Object}
     */

    function parseTSVContents(tsv) {
      var tsvLines = tsv.split(/\n+/g);
      var headers = trim$1(tsvLines.shift()).split(itemSplitRegex);
      var categories = [];
      var series = map(headers, function (header) {
        return {
          name: header,
          data: []
        };
      });

      for (var i = 0; i < tsvLines.length; i++) {
        var items = trim$1(tsvLines[i]).split(itemSplitRegex);
        categories.push(items.shift());

        for (var j = 0; j < items.length; j++) {
          series[j] && (series[j].data[i] = items[j]);
        }
      }

      return {
        series: series,
        categories: categories
      };
    }

    function parseListContents(str) {
      var lines = str.split(/\n+/g);
      var seriesName = trim$1(lines.shift());
      var data = [];

      for (var i = 0; i < lines.length; i++) {
        // if line is empty, ignore it.
        // there is a case that a user forgot to delete `\n`.
        var line = trim$1(lines[i]);

        if (!line) {
          continue;
        }

        var items = line.split(itemSplitRegex);
        var name_1 = '';
        var value = void 0;
        var hasName = false;

        if (isNaN(items[0])) {
          // First item is name
          hasName = true;
          name_1 = items[0];
          items = items.slice(1);
          data[i] = {
            name: name_1,
            value: []
          };
          value = data[i].value;
        } else {
          value = data[i] = [];
        }

        for (var j = 0; j < items.length; j++) {
          value.push(+items[j]);
        }

        if (value.length === 1) {
          hasName ? data[i].value = value[0] : data[i] = value[0];
        }
      }

      return {
        name: seriesName,
        data: data
      };
    }

    function parseContents(str, blockMetaList) {
      var blocks = str.split(new RegExp('\n*' + BLOCK_SPLITER + '\n*', 'g'));
      var newOption = {
        series: []
      };
      each(blocks, function (block, idx) {
        if (isTSVFormat(block)) {
          var result = parseTSVContents(block);
          var blockMeta = blockMetaList[idx];
          var axisKey = blockMeta.axisDim + 'Axis';

          if (blockMeta) {
            newOption[axisKey] = newOption[axisKey] || [];
            newOption[axisKey][blockMeta.axisIndex] = {
              data: result.categories
            };
            newOption.series = newOption.series.concat(result.series);
          }
        } else {
          var result = parseListContents(block);
          newOption.series.push(result);
        }
      });
      return newOption;
    }

    var DataView =
    /** @class */
    function (_super) {
      __extends(DataView, _super);

      function DataView() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      DataView.prototype.onclick = function (ecModel, api) {
        // FIXME: better way?
        setTimeout(function () {
          api.dispatchAction({
            type: 'hideTip'
          });
        });
        var container = api.getDom();
        var model = this.model;

        if (this._dom) {
          container.removeChild(this._dom);
        }

        var root = document.createElement('div'); // use padding to avoid 5px whitespace

        root.style.cssText = 'position:absolute;top:0;bottom:0;left:0;right:0;padding:5px';
        root.style.backgroundColor = model.get('backgroundColor') || '#fff'; // Create elements

        var header = document.createElement('h4');
        var lang = model.get('lang') || [];
        header.innerHTML = lang[0] || model.get('title');
        header.style.cssText = 'margin:10px 20px';
        header.style.color = model.get('textColor');
        var viewMain = document.createElement('div');
        var textarea = document.createElement('textarea');
        viewMain.style.cssText = 'overflow:auto';
        var optionToContent = model.get('optionToContent');
        var contentToOption = model.get('contentToOption');
        var result = getContentFromModel(ecModel);

        if (isFunction(optionToContent)) {
          var htmlOrDom = optionToContent(api.getOption());

          if (isString(htmlOrDom)) {
            viewMain.innerHTML = htmlOrDom;
          } else if (isDom(htmlOrDom)) {
            viewMain.appendChild(htmlOrDom);
          }
        } else {
          // Use default textarea
          textarea.readOnly = model.get('readOnly');
          var style = textarea.style; // eslint-disable-next-line max-len

          style.cssText = 'display:block;width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;resize:none;box-sizing:border-box;outline:none';
          style.color = model.get('textColor');
          style.borderColor = model.get('textareaBorderColor');
          style.backgroundColor = model.get('textareaColor');
          textarea.value = result.value;
          viewMain.appendChild(textarea);
        }

        var blockMetaList = result.meta;
        var buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = 'position:absolute;bottom:5px;left:0;right:0'; // eslint-disable-next-line max-len

        var buttonStyle = 'float:right;margin-right:20px;border:none;cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px';
        var closeButton = document.createElement('div');
        var refreshButton = document.createElement('div');
        buttonStyle += ';background-color:' + model.get('buttonColor');
        buttonStyle += ';color:' + model.get('buttonTextColor');
        var self = this;

        function close() {
          container.removeChild(root);
          self._dom = null;
        }

        addEventListener(closeButton, 'click', close);
        addEventListener(refreshButton, 'click', function () {
          if (contentToOption == null && optionToContent != null || contentToOption != null && optionToContent == null) {
            if ("development" !== 'production') {
              // eslint-disable-next-line
              warn('It seems you have just provided one of `contentToOption` and `optionToContent` functions but missed the other one. Data change is ignored.');
            }

            close();
            return;
          }

          var newOption;

          try {
            if (isFunction(contentToOption)) {
              newOption = contentToOption(viewMain, api.getOption());
            } else {
              newOption = parseContents(textarea.value, blockMetaList);
            }
          } catch (e) {
            close();
            throw new Error('Data view format error ' + e);
          }

          if (newOption) {
            api.dispatchAction({
              type: 'changeDataView',
              newOption: newOption
            });
          }

          close();
        });
        closeButton.innerHTML = lang[1];
        refreshButton.innerHTML = lang[2];
        refreshButton.style.cssText = closeButton.style.cssText = buttonStyle;
        !model.get('readOnly') && buttonContainer.appendChild(refreshButton);
        buttonContainer.appendChild(closeButton);
        root.appendChild(header);
        root.appendChild(viewMain);
        root.appendChild(buttonContainer);
        viewMain.style.height = container.clientHeight - 80 + 'px';
        container.appendChild(root);
        this._dom = root;
      };

      DataView.prototype.remove = function (ecModel, api) {
        this._dom && api.getDom().removeChild(this._dom);
      };

      DataView.prototype.dispose = function (ecModel, api) {
        this.remove(ecModel, api);
      };

      DataView.getDefaultOption = function (ecModel) {
        var defaultOption = {
          show: true,
          readOnly: false,
          optionToContent: null,
          contentToOption: null,
          // eslint-disable-next-line
          icon: 'M17.5,17.3H33 M17.5,17.3H33 M45.4,29.5h-28 M11.5,2v56H51V14.8L38.4,2H11.5z M38.4,2.2v12.7H51 M45.4,41.7h-28',
          title: ecModel.getLocaleModel().get(['toolbox', 'dataView', 'title']),
          lang: ecModel.getLocaleModel().get(['toolbox', 'dataView', 'lang']),
          backgroundColor: '#fff',
          textColor: '#000',
          textareaColor: '#fff',
          textareaBorderColor: '#333',
          buttonColor: '#c23531',
          buttonTextColor: '#fff'
        };
        return defaultOption;
      };

      return DataView;
    }(ToolboxFeature);
    /**
     * @inner
     */


    function tryMergeDataOption(newData, originalData) {
      return map(newData, function (newVal, idx) {
        var original = originalData && originalData[idx];

        if (isObject(original) && !isArray(original)) {
          var newValIsObject = isObject(newVal) && !isArray(newVal);

          if (!newValIsObject) {
            newVal = {
              value: newVal
            };
          } // original data has name but new data has no name


          var shouldDeleteName = original.name != null && newVal.name == null; // Original data has option

          newVal = defaults(newVal, original);
          shouldDeleteName && delete newVal.name;
          return newVal;
        } else {
          return newVal;
        }
      });
    } // TODO: SELF REGISTERED.


    registerAction({
      type: 'changeDataView',
      event: 'dataViewChanged',
      update: 'prepareAndUpdate'
    }, function (payload, ecModel) {
      var newSeriesOptList = [];
      each(payload.newOption.series, function (seriesOpt) {
        var seriesModel = ecModel.getSeriesByName(seriesOpt.name)[0];

        if (!seriesModel) {
          // New created series
          // Geuss the series type
          newSeriesOptList.push(extend({
            // Default is scatter
            type: 'scatter'
          }, seriesOpt));
        } else {
          var originalData = seriesModel.get('data');
          newSeriesOptList.push({
            name: seriesOpt.name,
            data: tryMergeDataOption(seriesOpt.data, originalData)
          });
        }
      });
      ecModel.mergeOption(defaults({
        series: newSeriesOptList
      }, payload.newOption));
    });

    var each$5 = each;
    var inner$b = makeInner();
    /**
     * @param ecModel
     * @param newSnapshot key is dataZoomId
     */

    function push(ecModel, newSnapshot) {
      var storedSnapshots = getStoreSnapshots(ecModel); // If previous dataZoom can not be found,
      // complete an range with current range.

      each$5(newSnapshot, function (batchItem, dataZoomId) {
        var i = storedSnapshots.length - 1;

        for (; i >= 0; i--) {
          var snapshot = storedSnapshots[i];

          if (snapshot[dataZoomId]) {
            break;
          }
        }

        if (i < 0) {
          // No origin range set, create one by current range.
          var dataZoomModel = ecModel.queryComponents({
            mainType: 'dataZoom',
            subType: 'select',
            id: dataZoomId
          })[0];

          if (dataZoomModel) {
            var percentRange = dataZoomModel.getPercentRange();
            storedSnapshots[0][dataZoomId] = {
              dataZoomId: dataZoomId,
              start: percentRange[0],
              end: percentRange[1]
            };
          }
        }
      });
      storedSnapshots.push(newSnapshot);
    }
    function pop(ecModel) {
      var storedSnapshots = getStoreSnapshots(ecModel);
      var head = storedSnapshots[storedSnapshots.length - 1];
      storedSnapshots.length > 1 && storedSnapshots.pop(); // Find top for all dataZoom.

      var snapshot = {};
      each$5(head, function (batchItem, dataZoomId) {
        for (var i = storedSnapshots.length - 1; i >= 0; i--) {
          batchItem = storedSnapshots[i][dataZoomId];

          if (batchItem) {
            snapshot[dataZoomId] = batchItem;
            break;
          }
        }
      });
      return snapshot;
    }
    function clear$1(ecModel) {
      inner$b(ecModel).snapshots = null;
    }
    function count(ecModel) {
      return getStoreSnapshots(ecModel).length;
    }
    /**
     * History length of each dataZoom may be different.
     * this._history[0] is used to store origin range.
     */

    function getStoreSnapshots(ecModel) {
      var store = inner$b(ecModel);

      if (!store.snapshots) {
        store.snapshots = [{}];
      }

      return store.snapshots;
    }

    var RestoreOption =
    /** @class */
    function (_super) {
      __extends(RestoreOption, _super);

      function RestoreOption() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      RestoreOption.prototype.onclick = function (ecModel, api) {
        clear$1(ecModel);
        api.dispatchAction({
          type: 'restore',
          from: this.uid
        });
      };

      RestoreOption.getDefaultOption = function (ecModel) {
        var defaultOption = {
          show: true,
          // eslint-disable-next-line
          icon: 'M3.8,33.4 M47,18.9h9.8V8.7 M56.3,20.1 C52.1,9,40.5,0.6,26.8,2.1C12.6,3.7,1.6,16.2,2.1,30.6 M13,41.1H3.1v10.2 M3.7,39.9c4.2,11.1,15.8,19.5,29.5,18 c14.2-1.6,25.2-14.1,24.7-28.5',
          title: ecModel.getLocaleModel().get(['toolbox', 'restore', 'title'])
        };
        return defaultOption;
      };

      return RestoreOption;
    }(ToolboxFeature); // TODO: SELF REGISTERED.


    registerAction({
      type: 'restore',
      event: 'restore',
      update: 'prepareAndUpdate'
    }, function (payload, ecModel) {
      ecModel.resetOption('recreate');
    });

    var ATTR = '\0_ec_interaction_mutex';
    function take(zr, resourceKey, userKey) {
      var store = getStore(zr);
      store[resourceKey] = userKey;
    }
    function release(zr, resourceKey, userKey) {
      var store = getStore(zr);
      var uKey = store[resourceKey];

      if (uKey === userKey) {
        store[resourceKey] = null;
      }
    }
    function isTaken(zr, resourceKey) {
      return !!getStore(zr)[resourceKey];
    }

    function getStore(zr) {
      return zr[ATTR] || (zr[ATTR] = {});
    }
    /**
     * payload: {
     *     type: 'takeGlobalCursor',
     *     key: 'dataZoomSelect', or 'brush', or ...,
     *         If no userKey, release global cursor.
     * }
     */
    // TODO: SELF REGISTERED.


    registerAction({
      type: 'takeGlobalCursor',
      event: 'globalCursorTaken',
      update: 'update'
    }, noop);

    var BRUSH_PANEL_GLOBAL = true;
    var mathMin$7 = Math.min;
    var mathMax$7 = Math.max;
    var mathPow$2 = Math.pow;
    var COVER_Z = 10000;
    var UNSELECT_THRESHOLD = 6;
    var MIN_RESIZE_LINE_WIDTH = 6;
    var MUTEX_RESOURCE_KEY = 'globalPan';
    var DIRECTION_MAP = {
      w: [0, 0],
      e: [0, 1],
      n: [1, 0],
      s: [1, 1]
    };
    var CURSOR_MAP = {
      w: 'ew',
      e: 'ew',
      n: 'ns',
      s: 'ns',
      ne: 'nesw',
      sw: 'nesw',
      nw: 'nwse',
      se: 'nwse'
    };
    var DEFAULT_BRUSH_OPT = {
      brushStyle: {
        lineWidth: 2,
        stroke: 'rgba(210,219,238,0.3)',
        fill: '#D2DBEE'
      },
      transformable: true,
      brushMode: 'single',
      removeOnClick: false
    };
    var baseUID = 0;
    /**
     * params:
     *     areas: Array.<Array>, coord relates to container group,
     *                             If no container specified, to global.
     *     opt {
     *         isEnd: boolean,
     *         removeOnClick: boolean
     *     }
     */

    var BrushController =
    /** @class */
    function (_super) {
      __extends(BrushController, _super);

      function BrushController(zr) {
        var _this = _super.call(this) || this;
        /**
         * @internal
         */


        _this._track = [];
        /**
         * @internal
         */

        _this._covers = [];
        _this._handlers = {};

        if ("development" !== 'production') {
          assert(zr);
        }

        _this._zr = zr;
        _this.group = new Group();
        _this._uid = 'brushController_' + baseUID++;
        each(pointerHandlers, function (handler, eventName) {
          this._handlers[eventName] = bind(handler, this);
        }, _this);
        return _this;
      }
      /**
       * If set to `false`, select disabled.
       */


      BrushController.prototype.enableBrush = function (brushOption) {
        if ("development" !== 'production') {
          assert(this._mounted);
        }

        this._brushType && this._doDisableBrush();
        brushOption.brushType && this._doEnableBrush(brushOption);
        return this;
      };

      BrushController.prototype._doEnableBrush = function (brushOption) {
        var zr = this._zr; // Consider roam, which takes globalPan too.

        if (!this._enableGlobalPan) {
          take(zr, MUTEX_RESOURCE_KEY, this._uid);
        }

        each(this._handlers, function (handler, eventName) {
          zr.on(eventName, handler);
        });
        this._brushType = brushOption.brushType;
        this._brushOption = merge(clone(DEFAULT_BRUSH_OPT), brushOption, true);
      };

      BrushController.prototype._doDisableBrush = function () {
        var zr = this._zr;
        release(zr, MUTEX_RESOURCE_KEY, this._uid);
        each(this._handlers, function (handler, eventName) {
          zr.off(eventName, handler);
        });
        this._brushType = this._brushOption = null;
      };
      /**
       * @param panelOpts If not pass, it is global brush.
       */


      BrushController.prototype.setPanels = function (panelOpts) {
        if (panelOpts && panelOpts.length) {
          var panels_1 = this._panels = {};
          each(panelOpts, function (panelOpts) {
            panels_1[panelOpts.panelId] = clone(panelOpts);
          });
        } else {
          this._panels = null;
        }

        return this;
      };

      BrushController.prototype.mount = function (opt) {
        opt = opt || {};

        if ("development" !== 'production') {
          this._mounted = true; // should be at first.
        }

        this._enableGlobalPan = opt.enableGlobalPan;
        var thisGroup = this.group;

        this._zr.add(thisGroup);

        thisGroup.attr({
          x: opt.x || 0,
          y: opt.y || 0,
          rotation: opt.rotation || 0,
          scaleX: opt.scaleX || 1,
          scaleY: opt.scaleY || 1
        });
        this._transform = thisGroup.getLocalTransform();
        return this;
      }; // eachCover(cb, context): void {
      //     each(this._covers, cb, context);
      // }

      /**
       * Update covers.
       * @param coverConfigList
       *        If coverConfigList is null/undefined, all covers removed.
       */


      BrushController.prototype.updateCovers = function (coverConfigList) {
        if ("development" !== 'production') {
          assert(this._mounted);
        }

        coverConfigList = map(coverConfigList, function (coverConfig) {
          return merge(clone(DEFAULT_BRUSH_OPT), coverConfig, true);
        });
        var tmpIdPrefix = '\0-brush-index-';
        var oldCovers = this._covers;
        var newCovers = this._covers = [];
        var controller = this;
        var creatingCover = this._creatingCover;
        new DataDiffer(oldCovers, coverConfigList, oldGetKey, getKey).add(addOrUpdate).update(addOrUpdate).remove(remove).execute();
        return this;

        function getKey(brushOption, index) {
          return (brushOption.id != null ? brushOption.id : tmpIdPrefix + index) + '-' + brushOption.brushType;
        }

        function oldGetKey(cover, index) {
          return getKey(cover.__brushOption, index);
        }

        function addOrUpdate(newIndex, oldIndex) {
          var newBrushInternal = coverConfigList[newIndex]; // Consider setOption in event listener of brushSelect,
          // where updating cover when creating should be forbiden.

          if (oldIndex != null && oldCovers[oldIndex] === creatingCover) {
            newCovers[newIndex] = oldCovers[oldIndex];
          } else {
            var cover = newCovers[newIndex] = oldIndex != null ? (oldCovers[oldIndex].__brushOption = newBrushInternal, oldCovers[oldIndex]) : endCreating(controller, createCover(controller, newBrushInternal));
            updateCoverAfterCreation(controller, cover);
          }
        }

        function remove(oldIndex) {
          if (oldCovers[oldIndex] !== creatingCover) {
            controller.group.remove(oldCovers[oldIndex]);
          }
        }
      };

      BrushController.prototype.unmount = function () {
        if ("development" !== 'production') {
          if (!this._mounted) {
            return;
          }
        }

        this.enableBrush(false); // container may 'removeAll' outside.

        clearCovers(this);

        this._zr.remove(this.group);

        if ("development" !== 'production') {
          this._mounted = false; // should be at last.
        }

        return this;
      };

      BrushController.prototype.dispose = function () {
        this.unmount();
        this.off();
      };

      return BrushController;
    }(Eventful);

    function createCover(controller, brushOption) {
      var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption);
      cover.__brushOption = brushOption;
      updateZ(cover, brushOption);
      controller.group.add(cover);
      return cover;
    }

    function endCreating(controller, creatingCover) {
      var coverRenderer = getCoverRenderer(creatingCover);

      if (coverRenderer.endCreating) {
        coverRenderer.endCreating(controller, creatingCover);
        updateZ(creatingCover, creatingCover.__brushOption);
      }

      return creatingCover;
    }

    function updateCoverShape(controller, cover) {
      var brushOption = cover.__brushOption;
      getCoverRenderer(cover).updateCoverShape(controller, cover, brushOption.range, brushOption);
    }

    function updateZ(cover, brushOption) {
      var z = brushOption.z;
      z == null && (z = COVER_Z);
      cover.traverse(function (el) {
        el.z = z;
        el.z2 = z; // Consider in given container.
      });
    }

    function updateCoverAfterCreation(controller, cover) {
      getCoverRenderer(cover).updateCommon(controller, cover);
      updateCoverShape(controller, cover);
    }

    function getCoverRenderer(cover) {
      return coverRenderers[cover.__brushOption.brushType];
    } // return target panel or `true` (means global panel)


    function getPanelByPoint(controller, e, localCursorPoint) {
      var panels = controller._panels;

      if (!panels) {
        return BRUSH_PANEL_GLOBAL; // Global panel
      }

      var panel;
      var transform = controller._transform;
      each(panels, function (pn) {
        pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn);
      });
      return panel;
    } // Return a panel or true


    function getPanelByCover(controller, cover) {
      var panels = controller._panels;

      if (!panels) {
        return BRUSH_PANEL_GLOBAL; // Global panel
      }

      var panelId = cover.__brushOption.panelId; // User may give cover without coord sys info,
      // which is then treated as global panel.

      return panelId != null ? panels[panelId] : BRUSH_PANEL_GLOBAL;
    }

    function clearCovers(controller) {
      var covers = controller._covers;
      var originalLength = covers.length;
      each(covers, function (cover) {
        controller.group.remove(cover);
      }, controller);
      covers.length = 0;
      return !!originalLength;
    }

    function trigger(controller, opt) {
      var areas = map(controller._covers, function (cover) {
        var brushOption = cover.__brushOption;
        var range = clone(brushOption.range);
        return {
          brushType: brushOption.brushType,
          panelId: brushOption.panelId,
          range: range
        };
      });
      controller.trigger('brush', {
        areas: areas,
        isEnd: !!opt.isEnd,
        removeOnClick: !!opt.removeOnClick
      });
    }

    function shouldShowCover(controller) {
      var track = controller._track;

      if (!track.length) {
        return false;
      }

      var p2 = track[track.length - 1];
      var p1 = track[0];
      var dx = p2[0] - p1[0];
      var dy = p2[1] - p1[1];
      var dist = mathPow$2(dx * dx + dy * dy, 0.5);
      return dist > UNSELECT_THRESHOLD;
    }

    function getTrackEnds(track) {
      var tail = track.length - 1;
      tail < 0 && (tail = 0);
      return [track[0], track[tail]];
    }

    function createBaseRectCover(rectRangeConverter, controller, brushOption, edgeNameSequences) {
      var cover = new Group();
      cover.add(new Rect({
        name: 'main',
        style: makeStyle(brushOption),
        silent: true,
        draggable: true,
        cursor: 'move',
        drift: curry(driftRect, rectRangeConverter, controller, cover, ['n', 's', 'w', 'e']),
        ondragend: curry(trigger, controller, {
          isEnd: true
        })
      }));
      each(edgeNameSequences, function (nameSequence) {
        cover.add(new Rect({
          name: nameSequence.join(''),
          style: {
            opacity: 0
          },
          draggable: true,
          silent: true,
          invisible: true,
          drift: curry(driftRect, rectRangeConverter, controller, cover, nameSequence),
          ondragend: curry(trigger, controller, {
            isEnd: true
          })
        }));
      });
      return cover;
    }

    function updateBaseRect(controller, cover, localRange, brushOption) {
      var lineWidth = brushOption.brushStyle.lineWidth || 0;
      var handleSize = mathMax$7(lineWidth, MIN_RESIZE_LINE_WIDTH);
      var x = localRange[0][0];
      var y = localRange[1][0];
      var xa = x - lineWidth / 2;
      var ya = y - lineWidth / 2;
      var x2 = localRange[0][1];
      var y2 = localRange[1][1];
      var x2a = x2 - handleSize + lineWidth / 2;
      var y2a = y2 - handleSize + lineWidth / 2;
      var width = x2 - x;
      var height = y2 - y;
      var widtha = width + lineWidth;
      var heighta = height + lineWidth;
      updateRectShape(controller, cover, 'main', x, y, width, height);

      if (brushOption.transformable) {
        updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta);
        updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta);
        updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize);
        updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize);
        updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize);
        updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize);
        updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize);
        updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize);
      }
    }

    function updateCommon(controller, cover) {
      var brushOption = cover.__brushOption;
      var transformable = brushOption.transformable;
      var mainEl = cover.childAt(0);
      mainEl.useStyle(makeStyle(brushOption));
      mainEl.attr({
        silent: !transformable,
        cursor: transformable ? 'move' : 'default'
      });
      each([['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']], function (nameSequence) {
        var el = cover.childOfName(nameSequence.join(''));
        var globalDir = nameSequence.length === 1 ? getGlobalDirection1(controller, nameSequence[0]) : getGlobalDirection2(controller, nameSequence);
        el && el.attr({
          silent: !transformable,
          invisible: !transformable,
          cursor: transformable ? CURSOR_MAP[globalDir] + '-resize' : null
        });
      });
    }

    function updateRectShape(controller, cover, name, x, y, w, h) {
      var el = cover.childOfName(name);
      el && el.setShape(pointsToRect(clipByPanel(controller, cover, [[x, y], [x + w, y + h]])));
    }

    function makeStyle(brushOption) {
      return defaults({
        strokeNoScale: true
      }, brushOption.brushStyle);
    }

    function formatRectRange(x, y, x2, y2) {
      var min = [mathMin$7(x, x2), mathMin$7(y, y2)];
      var max = [mathMax$7(x, x2), mathMax$7(y, y2)];
      return [[min[0], max[0]], [min[1], max[1]] // y range
      ];
    }

    function getTransform$1(controller) {
      return getTransform(controller.group);
    }

    function getGlobalDirection1(controller, localDirName) {
      var map = {
        w: 'left',
        e: 'right',
        n: 'top',
        s: 'bottom'
      };
      var inverseMap = {
        left: 'w',
        right: 'e',
        top: 'n',
        bottom: 's'
      };
      var dir = transformDirection(map[localDirName], getTransform$1(controller));
      return inverseMap[dir];
    }

    function getGlobalDirection2(controller, localDirNameSeq) {
      var globalDir = [getGlobalDirection1(controller, localDirNameSeq[0]), getGlobalDirection1(controller, localDirNameSeq[1])];
      (globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse();
      return globalDir.join('');
    }

    function driftRect(rectRangeConverter, controller, cover, dirNameSequence, dx, dy) {
      var brushOption = cover.__brushOption;
      var rectRange = rectRangeConverter.toRectRange(brushOption.range);
      var localDelta = toLocalDelta(controller, dx, dy);
      each(dirNameSequence, function (dirName) {
        var ind = DIRECTION_MAP[dirName];
        rectRange[ind[0]][ind[1]] += localDelta[ind[0]];
      });
      brushOption.range = rectRangeConverter.fromRectRange(formatRectRange(rectRange[0][0], rectRange[1][0], rectRange[0][1], rectRange[1][1]));
      updateCoverAfterCreation(controller, cover);
      trigger(controller, {
        isEnd: false
      });
    }

    function driftPolygon(controller, cover, dx, dy) {
      var range = cover.__brushOption.range;
      var localDelta = toLocalDelta(controller, dx, dy);
      each(range, function (point) {
        point[0] += localDelta[0];
        point[1] += localDelta[1];
      });
      updateCoverAfterCreation(controller, cover);
      trigger(controller, {
        isEnd: false
      });
    }

    function toLocalDelta(controller, dx, dy) {
      var thisGroup = controller.group;
      var localD = thisGroup.transformCoordToLocal(dx, dy);
      var localZero = thisGroup.transformCoordToLocal(0, 0);
      return [localD[0] - localZero[0], localD[1] - localZero[1]];
    }

    function clipByPanel(controller, cover, data) {
      var panel = getPanelByCover(controller, cover);
      return panel && panel !== BRUSH_PANEL_GLOBAL ? panel.clipPath(data, controller._transform) : clone(data);
    }

    function pointsToRect(points) {
      var xmin = mathMin$7(points[0][0], points[1][0]);
      var ymin = mathMin$7(points[0][1], points[1][1]);
      var xmax = mathMax$7(points[0][0], points[1][0]);
      var ymax = mathMax$7(points[0][1], points[1][1]);
      return {
        x: xmin,
        y: ymin,
        width: xmax - xmin,
        height: ymax - ymin
      };
    }

    function resetCursor(controller, e, localCursorPoint) {
      if ( // Check active
      !controller._brushType // resetCursor should be always called when mouse is in zr area,
      // but not called when mouse is out of zr area to avoid bad influence
      // if `mousemove`, `mouseup` are triggered from `document` event.
      || isOutsideZrArea(controller, e.offsetX, e.offsetY)) {
        return;
      }

      var zr = controller._zr;
      var covers = controller._covers;
      var currPanel = getPanelByPoint(controller, e, localCursorPoint); // Check whether in covers.

      if (!controller._dragging) {
        for (var i = 0; i < covers.length; i++) {
          var brushOption = covers[i].__brushOption;

          if (currPanel && (currPanel === BRUSH_PANEL_GLOBAL || brushOption.panelId === currPanel.panelId) && coverRenderers[brushOption.brushType].contain(covers[i], localCursorPoint[0], localCursorPoint[1])) {
            // Use cursor style set on cover.
            return;
          }
        }
      }

      currPanel && zr.setCursorStyle('crosshair');
    }

    function preventDefault(e) {
      var rawE = e.event;
      rawE.preventDefault && rawE.preventDefault();
    }

    function mainShapeContain(cover, x, y) {
      return cover.childOfName('main').contain(x, y);
    }

    function updateCoverByMouse(controller, e, localCursorPoint, isEnd) {
      var creatingCover = controller._creatingCover;
      var panel = controller._creatingPanel;
      var thisBrushOption = controller._brushOption;
      var eventParams;

      controller._track.push(localCursorPoint.slice());

      if (shouldShowCover(controller) || creatingCover) {
        if (panel && !creatingCover) {
          thisBrushOption.brushMode === 'single' && clearCovers(controller);
          var brushOption = clone(thisBrushOption);
          brushOption.brushType = determineBrushType(brushOption.brushType, panel);
          brushOption.panelId = panel === BRUSH_PANEL_GLOBAL ? null : panel.panelId;
          creatingCover = controller._creatingCover = createCover(controller, brushOption);

          controller._covers.push(creatingCover);
        }

        if (creatingCover) {
          var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)];
          var coverBrushOption = creatingCover.__brushOption;
          coverBrushOption.range = coverRenderer.getCreatingRange(clipByPanel(controller, creatingCover, controller._track));

          if (isEnd) {
            endCreating(controller, creatingCover);
            coverRenderer.updateCommon(controller, creatingCover);
          }

          updateCoverShape(controller, creatingCover);
          eventParams = {
            isEnd: isEnd
          };
        }
      } else if (isEnd && thisBrushOption.brushMode === 'single' && thisBrushOption.removeOnClick) {
        // Help user to remove covers easily, only by a tiny drag, in 'single' mode.
        // But a single click do not clear covers, because user may have casual
        // clicks (for example, click on other component and do not expect covers
        // disappear).
        // Only some cover removed, trigger action, but not every click trigger action.
        if (getPanelByPoint(controller, e, localCursorPoint) && clearCovers(controller)) {
          eventParams = {
            isEnd: isEnd,
            removeOnClick: true
          };
        }
      }

      return eventParams;
    }

    function determineBrushType(brushType, panel) {
      if (brushType === 'auto') {
        if ("development" !== 'production') {
          assert(panel && panel.defaultBrushType, 'MUST have defaultBrushType when brushType is "atuo"');
        }

        return panel.defaultBrushType;
      }

      return brushType;
    }

    var pointerHandlers = {
      mousedown: function (e) {
        if (this._dragging) {
          // In case some browser do not support globalOut,
          // and release mouse out side the browser.
          handleDragEnd(this, e);
        } else if (!e.target || !e.target.draggable) {
          preventDefault(e);
          var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
          this._creatingCover = null;
          var panel = this._creatingPanel = getPanelByPoint(this, e, localCursorPoint);

          if (panel) {
            this._dragging = true;
            this._track = [localCursorPoint.slice()];
          }
        }
      },
      mousemove: function (e) {
        var x = e.offsetX;
        var y = e.offsetY;
        var localCursorPoint = this.group.transformCoordToLocal(x, y);
        resetCursor(this, e, localCursorPoint);

        if (this._dragging) {
          preventDefault(e);
          var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);
          eventParams && trigger(this, eventParams);
        }
      },
      mouseup: function (e) {
        handleDragEnd(this, e);
      }
    };

    function handleDragEnd(controller, e) {
      if (controller._dragging) {
        preventDefault(e);
        var x = e.offsetX;
        var y = e.offsetY;
        var localCursorPoint = controller.group.transformCoordToLocal(x, y);
        var eventParams = updateCoverByMouse(controller, e, localCursorPoint, true);
        controller._dragging = false;
        controller._track = [];
        controller._creatingCover = null; // trigger event shoule be at final, after procedure will be nested.

        eventParams && trigger(controller, eventParams);
      }
    }

    function isOutsideZrArea(controller, x, y) {
      var zr = controller._zr;
      return x < 0 || x > zr.getWidth() || y < 0 || y > zr.getHeight();
    }
    /**
     * key: brushType
     */


    var coverRenderers = {
      lineX: getLineRenderer(0),
      lineY: getLineRenderer(1),
      rect: {
        createCover: function (controller, brushOption) {
          function returnInput(range) {
            return range;
          }

          return createBaseRectCover({
            toRectRange: returnInput,
            fromRectRange: returnInput
          }, controller, brushOption, [['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']]);
        },
        getCreatingRange: function (localTrack) {
          var ends = getTrackEnds(localTrack);
          return formatRectRange(ends[1][0], ends[1][1], ends[0][0], ends[0][1]);
        },
        updateCoverShape: function (controller, cover, localRange, brushOption) {
          updateBaseRect(controller, cover, localRange, brushOption);
        },
        updateCommon: updateCommon,
        contain: mainShapeContain
      },
      polygon: {
        createCover: function (controller, brushOption) {
          var cover = new Group(); // Do not use graphic.Polygon because graphic.Polyline do not close the
          // border of the shape when drawing, which is a better experience for user.

          cover.add(new Polyline({
            name: 'main',
            style: makeStyle(brushOption),
            silent: true
          }));
          return cover;
        },
        getCreatingRange: function (localTrack) {
          return localTrack;
        },
        endCreating: function (controller, cover) {
          cover.remove(cover.childAt(0)); // Use graphic.Polygon close the shape.

          cover.add(new Polygon({
            name: 'main',
            draggable: true,
            drift: curry(driftPolygon, controller, cover),
            ondragend: curry(trigger, controller, {
              isEnd: true
            })
          }));
        },
        updateCoverShape: function (controller, cover, localRange, brushOption) {
          cover.childAt(0).setShape({
            points: clipByPanel(controller, cover, localRange)
          });
        },
        updateCommon: updateCommon,
        contain: mainShapeContain
      }
    };

    function getLineRenderer(xyIndex) {
      return {
        createCover: function (controller, brushOption) {
          return createBaseRectCover({
            toRectRange: function (range) {
              var rectRange = [range, [0, 100]];
              xyIndex && rectRange.reverse();
              return rectRange;
            },
            fromRectRange: function (rectRange) {
              return rectRange[xyIndex];
            }
          }, controller, brushOption, [[['w'], ['e']], [['n'], ['s']]][xyIndex]);
        },
        getCreatingRange: function (localTrack) {
          var ends = getTrackEnds(localTrack);
          var min = mathMin$7(ends[0][xyIndex], ends[1][xyIndex]);
          var max = mathMax$7(ends[0][xyIndex], ends[1][xyIndex]);
          return [min, max];
        },
        updateCoverShape: function (controller, cover, localRange, brushOption) {
          var otherExtent; // If brushWidth not specified, fit the panel.

          var panel = getPanelByCover(controller, cover);

          if (panel !== BRUSH_PANEL_GLOBAL && panel.getLinearBrushOtherExtent) {
            otherExtent = panel.getLinearBrushOtherExtent(xyIndex);
          } else {
            var zr = controller._zr;
            otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]];
          }

          var rectRange = [localRange, otherExtent];
          xyIndex && rectRange.reverse();
          updateBaseRect(controller, cover, rectRange, brushOption);
        },
        updateCommon: updateCommon,
        contain: mainShapeContain
      };
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var IRRELEVANT_EXCLUDES = {
      'axisPointer': 1,
      'tooltip': 1,
      'brush': 1
    };
    /**
     * Avoid that: mouse click on a elements that is over geo or graph,
     * but roam is triggered.
     */

    function onIrrelevantElement(e, api, targetCoordSysModel) {
      var model = api.getComponentByElement(e.topTarget); // If model is axisModel, it works only if it is injected with coordinateSystem.

      var coordSys = model && model.coordinateSystem;
      return model && model !== targetCoordSysModel && !IRRELEVANT_EXCLUDES.hasOwnProperty(model.mainType) && coordSys && coordSys.model !== targetCoordSysModel;
    }

    function makeRectPanelClipPath(rect) {
      rect = normalizeRect(rect);
      return function (localPoints) {
        return clipPointsByRect(localPoints, rect);
      };
    }
    function makeLinearBrushOtherExtent(rect, specifiedXYIndex) {
      rect = normalizeRect(rect);
      return function (xyIndex) {
        var idx = specifiedXYIndex != null ? specifiedXYIndex : xyIndex;
        var brushWidth = idx ? rect.width : rect.height;
        var base = idx ? rect.x : rect.y;
        return [base, base + (brushWidth || 0)];
      };
    }
    function makeRectIsTargetByCursor(rect, api, targetModel) {
      var boundingRect = normalizeRect(rect);
      return function (e, localCursorPoint) {
        return boundingRect.contain(localCursorPoint[0], localCursorPoint[1]) && !onIrrelevantElement(e, api, targetModel);
      };
    } // Consider width/height is negative.

    function normalizeRect(rect) {
      return BoundingRect.create(rect);
    }

    // how to genarialize to more coordinate systems.

    var INCLUDE_FINDER_MAIN_TYPES = ['grid', 'xAxis', 'yAxis', 'geo', 'graph', 'polar', 'radiusAxis', 'angleAxis', 'bmap'];

    var BrushTargetManager =
    /** @class */
    function () {
      /**
       * @param finder contains Index/Id/Name of xAxis/yAxis/geo/grid
       *        Each can be {number|Array.<number>}. like: {xAxisIndex: [3, 4]}
       * @param opt.include include coordinate system types.
       */
      function BrushTargetManager(finder, ecModel, opt) {
        var _this = this;

        this._targetInfoList = [];
        var foundCpts = parseFinder$1(ecModel, finder);
        each(targetInfoBuilders, function (builder, type) {
          if (!opt || !opt.include || indexOf(opt.include, type) >= 0) {
            builder(foundCpts, _this._targetInfoList);
          }
        });
      }

      BrushTargetManager.prototype.setOutputRanges = function (areas, ecModel) {
        this.matchOutputRanges(areas, ecModel, function (area, coordRange, coordSys) {
          (area.coordRanges || (area.coordRanges = [])).push(coordRange); // area.coordRange is the first of area.coordRanges

          if (!area.coordRange) {
            area.coordRange = coordRange; // In 'category' axis, coord to pixel is not reversible, so we can not
            // rebuild range by coordRange accrately, which may bring trouble when
            // brushing only one item. So we use __rangeOffset to rebuilding range
            // by coordRange. And this it only used in brush component so it is no
            // need to be adapted to coordRanges.

            var result = coordConvert[area.brushType](0, coordSys, coordRange);
            area.__rangeOffset = {
              offset: diffProcessor[area.brushType](result.values, area.range, [1, 1]),
              xyMinMax: result.xyMinMax
            };
          }
        });
        return areas;
      };

      BrushTargetManager.prototype.matchOutputRanges = function (areas, ecModel, cb) {
        each(areas, function (area) {
          var targetInfo = this.findTargetInfo(area, ecModel);

          if (targetInfo && targetInfo !== true) {
            each(targetInfo.coordSyses, function (coordSys) {
              var result = coordConvert[area.brushType](1, coordSys, area.range, true);
              cb(area, result.values, coordSys, ecModel);
            });
          }
        }, this);
      };
      /**
       * the `areas` is `BrushModel.areas`.
       * Called in layout stage.
       * convert `area.coordRange` to global range and set panelId to `area.range`.
       */


      BrushTargetManager.prototype.setInputRanges = function (areas, ecModel) {
        each(areas, function (area) {
          var targetInfo = this.findTargetInfo(area, ecModel);

          if ("development" !== 'production') {
            assert(!targetInfo || targetInfo === true || area.coordRange, 'coordRange must be specified when coord index specified.');
            assert(!targetInfo || targetInfo !== true || area.range, 'range must be specified in global brush.');
          }

          area.range = area.range || []; // convert coordRange to global range and set panelId.

          if (targetInfo && targetInfo !== true) {
            area.panelId = targetInfo.panelId; // (1) area.range shoule always be calculate from coordRange but does
            // not keep its original value, for the sake of the dataZoom scenario,
            // where area.coordRange remains unchanged but area.range may be changed.
            // (2) Only support converting one coordRange to pixel range in brush
            // component. So do not consider `coordRanges`.
            // (3) About __rangeOffset, see comment above.

            var result = coordConvert[area.brushType](0, targetInfo.coordSys, area.coordRange);
            var rangeOffset = area.__rangeOffset;
            area.range = rangeOffset ? diffProcessor[area.brushType](result.values, rangeOffset.offset, getScales(result.xyMinMax, rangeOffset.xyMinMax)) : result.values;
          }
        }, this);
      };

      BrushTargetManager.prototype.makePanelOpts = function (api, getDefaultBrushType) {
        return map(this._targetInfoList, function (targetInfo) {
          var rect = targetInfo.getPanelRect();
          return {
            panelId: targetInfo.panelId,
            defaultBrushType: getDefaultBrushType ? getDefaultBrushType(targetInfo) : null,
            clipPath: makeRectPanelClipPath(rect),
            isTargetByCursor: makeRectIsTargetByCursor(rect, api, targetInfo.coordSysModel),
            getLinearBrushOtherExtent: makeLinearBrushOtherExtent(rect)
          };
        });
      };

      BrushTargetManager.prototype.controlSeries = function (area, seriesModel, ecModel) {
        // Check whether area is bound in coord, and series do not belong to that coord.
        // If do not do this check, some brush (like lineX) will controll all axes.
        var targetInfo = this.findTargetInfo(area, ecModel);
        return targetInfo === true || targetInfo && indexOf(targetInfo.coordSyses, seriesModel.coordinateSystem) >= 0;
      };
      /**
       * If return Object, a coord found.
       * If reutrn true, global found.
       * Otherwise nothing found.
       */


      BrushTargetManager.prototype.findTargetInfo = function (area, ecModel) {
        var targetInfoList = this._targetInfoList;
        var foundCpts = parseFinder$1(ecModel, area);

        for (var i = 0; i < targetInfoList.length; i++) {
          var targetInfo = targetInfoList[i];
          var areaPanelId = area.panelId;

          if (areaPanelId) {
            if (targetInfo.panelId === areaPanelId) {
              return targetInfo;
            }
          } else {
            for (var j = 0; j < targetInfoMatchers.length; j++) {
              if (targetInfoMatchers[j](foundCpts, targetInfo)) {
                return targetInfo;
              }
            }
          }
        }

        return true;
      };

      return BrushTargetManager;
    }();

    function formatMinMax(minMax) {
      minMax[0] > minMax[1] && minMax.reverse();
      return minMax;
    }

    function parseFinder$1(ecModel, finder) {
      return parseFinder(ecModel, finder, {
        includeMainTypes: INCLUDE_FINDER_MAIN_TYPES
      });
    }

    var targetInfoBuilders = {
      grid: function (foundCpts, targetInfoList) {
        var xAxisModels = foundCpts.xAxisModels;
        var yAxisModels = foundCpts.yAxisModels;
        var gridModels = foundCpts.gridModels; // Remove duplicated.

        var gridModelMap = createHashMap();
        var xAxesHas = {};
        var yAxesHas = {};

        if (!xAxisModels && !yAxisModels && !gridModels) {
          return;
        }

        each(xAxisModels, function (axisModel) {
          var gridModel = axisModel.axis.grid.model;
          gridModelMap.set(gridModel.id, gridModel);
          xAxesHas[gridModel.id] = true;
        });
        each(yAxisModels, function (axisModel) {
          var gridModel = axisModel.axis.grid.model;
          gridModelMap.set(gridModel.id, gridModel);
          yAxesHas[gridModel.id] = true;
        });
        each(gridModels, function (gridModel) {
          gridModelMap.set(gridModel.id, gridModel);
          xAxesHas[gridModel.id] = true;
          yAxesHas[gridModel.id] = true;
        });
        gridModelMap.each(function (gridModel) {
          var grid = gridModel.coordinateSystem;
          var cartesians = [];
          each(grid.getCartesians(), function (cartesian, index) {
            if (indexOf(xAxisModels, cartesian.getAxis('x').model) >= 0 || indexOf(yAxisModels, cartesian.getAxis('y').model) >= 0) {
              cartesians.push(cartesian);
            }
          });
          targetInfoList.push({
            panelId: 'grid--' + gridModel.id,
            gridModel: gridModel,
            coordSysModel: gridModel,
            // Use the first one as the representitive coordSys.
            coordSys: cartesians[0],
            coordSyses: cartesians,
            getPanelRect: panelRectBuilders.grid,
            xAxisDeclared: xAxesHas[gridModel.id],
            yAxisDeclared: yAxesHas[gridModel.id]
          });
        });
      },
      geo: function (foundCpts, targetInfoList) {
        each(foundCpts.geoModels, function (geoModel) {
          var coordSys = geoModel.coordinateSystem;
          targetInfoList.push({
            panelId: 'geo--' + geoModel.id,
            geoModel: geoModel,
            coordSysModel: geoModel,
            coordSys: coordSys,
            coordSyses: [coordSys],
            getPanelRect: panelRectBuilders.geo
          });
        });
      }
    };
    var targetInfoMatchers = [// grid
    function (foundCpts, targetInfo) {
      var xAxisModel = foundCpts.xAxisModel;
      var yAxisModel = foundCpts.yAxisModel;
      var gridModel = foundCpts.gridModel;
      !gridModel && xAxisModel && (gridModel = xAxisModel.axis.grid.model);
      !gridModel && yAxisModel && (gridModel = yAxisModel.axis.grid.model);
      return gridModel && gridModel === targetInfo.gridModel;
    }, // geo
    function (foundCpts, targetInfo) {
      var geoModel = foundCpts.geoModel;
      return geoModel && geoModel === targetInfo.geoModel;
    }];
    var panelRectBuilders = {
      grid: function () {
        // grid is not Transformable.
        return this.coordSys.master.getRect().clone();
      },
      geo: function () {
        var coordSys = this.coordSys;
        var rect = coordSys.getBoundingRect().clone(); // geo roam and zoom transform

        rect.applyTransform(getTransform(coordSys));
        return rect;
      }
    };
    var coordConvert = {
      lineX: curry(axisConvert, 0),
      lineY: curry(axisConvert, 1),
      rect: function (to, coordSys, rangeOrCoordRange, clamp) {
        var xminymin = to ? coordSys.pointToData([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]], clamp) : coordSys.dataToPoint([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]], clamp);
        var xmaxymax = to ? coordSys.pointToData([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]], clamp) : coordSys.dataToPoint([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]], clamp);
        var values = [formatMinMax([xminymin[0], xmaxymax[0]]), formatMinMax([xminymin[1], xmaxymax[1]])];
        return {
          values: values,
          xyMinMax: values
        };
      },
      polygon: function (to, coordSys, rangeOrCoordRange, clamp) {
        var xyMinMax = [[Infinity, -Infinity], [Infinity, -Infinity]];
        var values = map(rangeOrCoordRange, function (item) {
          var p = to ? coordSys.pointToData(item, clamp) : coordSys.dataToPoint(item, clamp);
          xyMinMax[0][0] = Math.min(xyMinMax[0][0], p[0]);
          xyMinMax[1][0] = Math.min(xyMinMax[1][0], p[1]);
          xyMinMax[0][1] = Math.max(xyMinMax[0][1], p[0]);
          xyMinMax[1][1] = Math.max(xyMinMax[1][1], p[1]);
          return p;
        });
        return {
          values: values,
          xyMinMax: xyMinMax
        };
      }
    };

    function axisConvert(axisNameIndex, to, coordSys, rangeOrCoordRange) {
      if ("development" !== 'production') {
        assert(coordSys.type === 'cartesian2d', 'lineX/lineY brush is available only in cartesian2d.');
      }

      var axis = coordSys.getAxis(['x', 'y'][axisNameIndex]);
      var values = formatMinMax(map([0, 1], function (i) {
        return to ? axis.coordToData(axis.toLocalCoord(rangeOrCoordRange[i]), true) : axis.toGlobalCoord(axis.dataToCoord(rangeOrCoordRange[i]));
      }));
      var xyMinMax = [];
      xyMinMax[axisNameIndex] = values;
      xyMinMax[1 - axisNameIndex] = [NaN, NaN];
      return {
        values: values,
        xyMinMax: xyMinMax
      };
    }

    var diffProcessor = {
      lineX: curry(axisDiffProcessor, 0),
      lineY: curry(axisDiffProcessor, 1),
      rect: function (values, refer, scales) {
        return [[values[0][0] - scales[0] * refer[0][0], values[0][1] - scales[0] * refer[0][1]], [values[1][0] - scales[1] * refer[1][0], values[1][1] - scales[1] * refer[1][1]]];
      },
      polygon: function (values, refer, scales) {
        return map(values, function (item, idx) {
          return [item[0] - scales[0] * refer[idx][0], item[1] - scales[1] * refer[idx][1]];
        });
      }
    };

    function axisDiffProcessor(axisNameIndex, values, refer, scales) {
      return [values[0] - scales[axisNameIndex] * refer[0], values[1] - scales[axisNameIndex] * refer[1]];
    } // We have to process scale caused by dataZoom manually,
    // although it might be not accurate.
    // Return [0~1, 0~1]


    function getScales(xyMinMaxCurr, xyMinMaxOrigin) {
      var sizeCurr = getSize$1(xyMinMaxCurr);
      var sizeOrigin = getSize$1(xyMinMaxOrigin);
      var scales = [sizeCurr[0] / sizeOrigin[0], sizeCurr[1] / sizeOrigin[1]];
      isNaN(scales[0]) && (scales[0] = 1);
      isNaN(scales[1]) && (scales[1] = 1);
      return scales;
    }

    function getSize$1(xyMinMax) {
      return xyMinMax ? [xyMinMax[0][1] - xyMinMax[0][0], xyMinMax[1][1] - xyMinMax[1][0]] : [NaN, NaN];
    }

    var each$6 = each;
    var DATA_ZOOM_ID_BASE = makeInternalComponentId('toolbox-dataZoom_');

    var DataZoomFeature =
    /** @class */
    function (_super) {
      __extends(DataZoomFeature, _super);

      function DataZoomFeature() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      DataZoomFeature.prototype.render = function (featureModel, ecModel, api, payload) {
        if (!this._brushController) {
          this._brushController = new BrushController(api.getZr());

          this._brushController.on('brush', bind(this._onBrush, this)).mount();
        }

        updateZoomBtnStatus(featureModel, ecModel, this, payload, api);
        updateBackBtnStatus(featureModel, ecModel);
      };

      DataZoomFeature.prototype.onclick = function (ecModel, api, type) {
        handlers[type].call(this);
      };

      DataZoomFeature.prototype.remove = function (ecModel, api) {
        this._brushController && this._brushController.unmount();
      };

      DataZoomFeature.prototype.dispose = function (ecModel, api) {
        this._brushController && this._brushController.dispose();
      };

      DataZoomFeature.prototype._onBrush = function (eventParam) {
        var areas = eventParam.areas;

        if (!eventParam.isEnd || !areas.length) {
          return;
        }

        var snapshot = {};
        var ecModel = this.ecModel;

        this._brushController.updateCovers([]); // remove cover


        var brushTargetManager = new BrushTargetManager(makeAxisFinder(this.model), ecModel, {
          include: ['grid']
        });
        brushTargetManager.matchOutputRanges(areas, ecModel, function (area, coordRange, coordSys) {
          if (coordSys.type !== 'cartesian2d') {
            return;
          }

          var brushType = area.brushType;

          if (brushType === 'rect') {
            setBatch('x', coordSys, coordRange[0]);
            setBatch('y', coordSys, coordRange[1]);
          } else {
            setBatch({
              lineX: 'x',
              lineY: 'y'
            }[brushType], coordSys, coordRange);
          }
        });
        push(ecModel, snapshot);

        this._dispatchZoomAction(snapshot);

        function setBatch(dimName, coordSys, minMax) {
          var axis = coordSys.getAxis(dimName);
          var axisModel = axis.model;
          var dataZoomModel = findDataZoom(dimName, axisModel, ecModel); // Restrict range.

          var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy(axisModel).getMinMaxSpan();

          if (minMaxSpan.minValueSpan != null || minMaxSpan.maxValueSpan != null) {
            minMax = sliderMove(0, minMax.slice(), axis.scale.getExtent(), 0, minMaxSpan.minValueSpan, minMaxSpan.maxValueSpan);
          }

          dataZoomModel && (snapshot[dataZoomModel.id] = {
            dataZoomId: dataZoomModel.id,
            startValue: minMax[0],
            endValue: minMax[1]
          });
        }

        function findDataZoom(dimName, axisModel, ecModel) {
          var found;
          ecModel.eachComponent({
            mainType: 'dataZoom',
            subType: 'select'
          }, function (dzModel) {
            var has = dzModel.getAxisModel(dimName, axisModel.componentIndex);
            has && (found = dzModel);
          });
          return found;
        }
      };

      DataZoomFeature.prototype._dispatchZoomAction = function (snapshot) {
        var batch = []; // Convert from hash map to array.

        each$6(snapshot, function (batchItem, dataZoomId) {
          batch.push(clone(batchItem));
        });
        batch.length && this.api.dispatchAction({
          type: 'dataZoom',
          from: this.uid,
          batch: batch
        });
      };

      DataZoomFeature.getDefaultOption = function (ecModel) {
        var defaultOption = {
          show: true,
          filterMode: 'filter',
          // Icon group
          icon: {
            zoom: 'M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1',
            back: 'M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26'
          },
          // `zoom`, `back`
          title: ecModel.getLocaleModel().get(['toolbox', 'dataZoom', 'title']),
          brushStyle: {
            borderWidth: 0,
            color: 'rgba(210,219,238,0.2)'
          }
        };
        return defaultOption;
      };

      return DataZoomFeature;
    }(ToolboxFeature);

    var handlers = {
      zoom: function () {
        var nextActive = !this._isZoomActive;
        this.api.dispatchAction({
          type: 'takeGlobalCursor',
          key: 'dataZoomSelect',
          dataZoomSelectActive: nextActive
        });
      },
      back: function () {
        this._dispatchZoomAction(pop(this.ecModel));
      }
    };

    function makeAxisFinder(dzFeatureModel) {
      var setting = {
        xAxisIndex: dzFeatureModel.get('xAxisIndex', true),
        yAxisIndex: dzFeatureModel.get('yAxisIndex', true),
        xAxisId: dzFeatureModel.get('xAxisId', true),
        yAxisId: dzFeatureModel.get('yAxisId', true)
      }; // If both `xAxisIndex` `xAxisId` not set, it means 'all'.
      // If both `yAxisIndex` `yAxisId` not set, it means 'all'.
      // Some old cases set like this below to close yAxis control but leave xAxis control:
      // `{ feature: { dataZoom: { yAxisIndex: false } }`.

      if (setting.xAxisIndex == null && setting.xAxisId == null) {
        setting.xAxisIndex = 'all';
      }

      if (setting.yAxisIndex == null && setting.yAxisId == null) {
        setting.yAxisIndex = 'all';
      }

      return setting;
    }

    function updateBackBtnStatus(featureModel, ecModel) {
      featureModel.setIconStatus('back', count(ecModel) > 1 ? 'emphasis' : 'normal');
    }

    function updateZoomBtnStatus(featureModel, ecModel, view, payload, api) {
      var zoomActive = view._isZoomActive;

      if (payload && payload.type === 'takeGlobalCursor') {
        zoomActive = payload.key === 'dataZoomSelect' ? payload.dataZoomSelectActive : false;
      }

      view._isZoomActive = zoomActive;
      featureModel.setIconStatus('zoom', zoomActive ? 'emphasis' : 'normal');
      var brushTargetManager = new BrushTargetManager(makeAxisFinder(featureModel), ecModel, {
        include: ['grid']
      });
      var panels = brushTargetManager.makePanelOpts(api, function (targetInfo) {
        return targetInfo.xAxisDeclared && !targetInfo.yAxisDeclared ? 'lineX' : !targetInfo.xAxisDeclared && targetInfo.yAxisDeclared ? 'lineY' : 'rect';
      });

      view._brushController.setPanels(panels).enableBrush(zoomActive && panels.length ? {
        brushType: 'auto',
        brushStyle: featureModel.getModel('brushStyle').getItemStyle()
      } : false);
    }

    registerInternalOptionCreator('dataZoom', function (ecModel) {
      var toolboxModel = ecModel.getComponent('toolbox', 0);
      var featureDataZoomPath = ['feature', 'dataZoom'];

      if (!toolboxModel || toolboxModel.get(featureDataZoomPath) == null) {
        return;
      }

      var dzFeatureModel = toolboxModel.getModel(featureDataZoomPath);
      var dzOptions = [];
      var finder = makeAxisFinder(dzFeatureModel);
      var finderResult = parseFinder(ecModel, finder);
      each$6(finderResult.xAxisModels, function (axisModel) {
        return buildInternalOptions(axisModel, 'xAxis', 'xAxisIndex');
      });
      each$6(finderResult.yAxisModels, function (axisModel) {
        return buildInternalOptions(axisModel, 'yAxis', 'yAxisIndex');
      });

      function buildInternalOptions(axisModel, axisMainType, axisIndexPropName) {
        var axisIndex = axisModel.componentIndex;
        var newOpt = {
          type: 'select',
          $fromToolbox: true,
          // Default to be filter
          filterMode: dzFeatureModel.get('filterMode', true) || 'filter',
          // Id for merge mapping.
          id: DATA_ZOOM_ID_BASE + axisMainType + axisIndex
        };
        newOpt[axisIndexPropName] = axisIndex;
        dzOptions.push(newOpt);
      }

      return dzOptions;
    });

    function install$b(registers) {
      registers.registerComponentModel(ToolboxModel);
      registers.registerComponentView(ToolboxView);
      registerFeature('saveAsImage', SaveAsImage);
      registerFeature('magicType', MagicType);
      registerFeature('dataView', DataView);
      registerFeature('dataZoom', DataZoomFeature);
      registerFeature('restore', RestoreOption);
      use(install$a);
    }

    var TooltipModel =
    /** @class */
    function (_super) {
      __extends(TooltipModel, _super);

      function TooltipModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TooltipModel.type;
        return _this;
      }

      TooltipModel.type = 'tooltip';
      TooltipModel.dependencies = ['axisPointer'];
      TooltipModel.defaultOption = {
        // zlevel: 0,
        z: 60,
        show: true,
        // tooltip main content
        showContent: true,
        // 'trigger' only works on coordinate system.
        // 'item' | 'axis' | 'none'
        trigger: 'item',
        // 'click' | 'mousemove' | 'none'
        triggerOn: 'mousemove|click',
        alwaysShowContent: false,
        displayMode: 'single',
        renderMode: 'auto',
        // whether restraint content inside viewRect.
        // If renderMode: 'richText', default true.
        // If renderMode: 'html', defaut false (for backward compat).
        confine: null,
        showDelay: 0,
        hideDelay: 100,
        // Animation transition time, unit is second
        transitionDuration: 0.4,
        enterable: false,
        backgroundColor: '#fff',
        // box shadow
        shadowBlur: 10,
        shadowColor: 'rgba(0, 0, 0, .2)',
        shadowOffsetX: 1,
        shadowOffsetY: 2,
        // tooltip border radius, unit is px, default is 4
        borderRadius: 4,
        // tooltip border width, unit is px, default is 0 (no border)
        borderWidth: 1,
        // Tooltip inside padding, default is 5 for all direction
        // Array is allowed to set up, right, bottom, left, same with css
        // The default value: See `tooltip/tooltipMarkup.ts#getPaddingFromTooltipModel`.
        padding: null,
        // Extra css text
        extraCssText: '',
        // axis indicator, trigger by axis
        axisPointer: {
          // default is line
          // legal values: 'line' | 'shadow' | 'cross'
          type: 'line',
          // Valid when type is line, appoint tooltip line locate on which line. Optional
          // legal values: 'x' | 'y' | 'angle' | 'radius' | 'auto'
          // default is 'auto', chose the axis which type is category.
          // for multiply y axis, cartesian coord chose x axis, polar chose angle axis
          axis: 'auto',
          animation: 'auto',
          animationDurationUpdate: 200,
          animationEasingUpdate: 'exponentialOut',
          crossStyle: {
            color: '#999',
            width: 1,
            type: 'dashed',
            // TODO formatter
            textStyle: {}
          } // lineStyle and shadowStyle should not be specified here,
          // otherwise it will always override those styles on option.axisPointer.

        },
        textStyle: {
          color: '#666',
          fontSize: 14
        }
      };
      return TooltipModel;
    }(ComponentModel);

    /* global document */

    function shouldTooltipConfine(tooltipModel) {
      var confineOption = tooltipModel.get('confine');
      return confineOption != null ? !!confineOption // In richText mode, the outside part can not be visible.
      : tooltipModel.get('renderMode') === 'richText';
    }

    function testStyle(styleProps) {
      if (!env.domSupported) {
        return;
      }

      var style = document.documentElement.style;

      for (var i = 0, len = styleProps.length; i < len; i++) {
        if (styleProps[i] in style) {
          return styleProps[i];
        }
      }
    }

    var TRANSFORM_VENDOR = testStyle(['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform']);
    var TRANSITION_VENDOR = testStyle(['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']);
    function toCSSVendorPrefix(styleVendor, styleProp) {
      if (!styleVendor) {
        return styleProp;
      }

      styleProp = toCamelCase(styleProp, true);
      var idx = styleVendor.indexOf(styleProp);
      styleVendor = idx === -1 ? styleProp : "-" + styleVendor.slice(0, idx) + "-" + styleProp;
      return styleVendor.toLowerCase();
    }
    function getComputedStyle(el, style) {
      var stl = el.currentStyle || document.defaultView && document.defaultView.getComputedStyle(el);
      return stl ? style ? stl[style] : stl : null;
    }

    /* global document, window */

    var CSS_TRANSITION_VENDOR = toCSSVendorPrefix(TRANSITION_VENDOR, 'transition');
    var CSS_TRANSFORM_VENDOR = toCSSVendorPrefix(TRANSFORM_VENDOR, 'transform'); // eslint-disable-next-line

    var gCssText = "position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;" + (env.transform3dSupported ? 'will-change:transform;' : '');

    function mirrorPos(pos) {
      pos = pos === 'left' ? 'right' : pos === 'right' ? 'left' : pos === 'top' ? 'bottom' : 'top';
      return pos;
    }

    function assembleArrow(tooltipModel, borderColor, arrowPosition) {
      if (!isString(arrowPosition) || arrowPosition === 'inside') {
        return '';
      }

      var backgroundColor = tooltipModel.get('backgroundColor');
      var borderWidth = tooltipModel.get('borderWidth');
      borderColor = convertToColorString(borderColor);
      var arrowPos = mirrorPos(arrowPosition);
      var arrowSize = Math.max(Math.round(borderWidth) * 1.5, 6);
      var positionStyle = '';
      var transformStyle = CSS_TRANSFORM_VENDOR + ':';
      var rotateDeg;

      if (indexOf(['left', 'right'], arrowPos) > -1) {
        positionStyle += 'top:50%';
        transformStyle += "translateY(-50%) rotate(" + (rotateDeg = arrowPos === 'left' ? -225 : -45) + "deg)";
      } else {
        positionStyle += 'left:50%';
        transformStyle += "translateX(-50%) rotate(" + (rotateDeg = arrowPos === 'top' ? 225 : 45) + "deg)";
      }

      var rotateRadian = rotateDeg * Math.PI / 180;
      var arrowWH = arrowSize + borderWidth;
      var rotatedWH = arrowWH * Math.abs(Math.cos(rotateRadian)) + arrowWH * Math.abs(Math.sin(rotateRadian));
      var arrowOffset = Math.round(((rotatedWH - Math.SQRT2 * borderWidth) / 2 + Math.SQRT2 * borderWidth - (rotatedWH - arrowWH) / 2) * 100) / 100;
      positionStyle += ";" + arrowPos + ":-" + arrowOffset + "px";
      var borderStyle = borderColor + " solid " + borderWidth + "px;";
      var styleCss = ["position:absolute;width:" + arrowSize + "px;height:" + arrowSize + "px;z-index:-1;", positionStyle + ";" + transformStyle + ";", "border-bottom:" + borderStyle, "border-right:" + borderStyle, "background-color:" + backgroundColor + ";"];
      return "<div style=\"" + styleCss.join('') + "\"></div>";
    }

    function assembleTransition(duration, onlyFade) {
      var transitionCurve = 'cubic-bezier(0.23,1,0.32,1)';
      var transitionOption = " " + duration / 2 + "s " + transitionCurve;
      var transitionText = "opacity" + transitionOption + ",visibility" + transitionOption;

      if (!onlyFade) {
        transitionOption = " " + duration + "s " + transitionCurve;
        transitionText += env.transformSupported ? "," + CSS_TRANSFORM_VENDOR + transitionOption : ",left" + transitionOption + ",top" + transitionOption;
      }

      return CSS_TRANSITION_VENDOR + ':' + transitionText;
    }

    function assembleTransform(x, y, toString) {
      // If using float on style, the final width of the dom might
      // keep changing slightly while mouse move. So `toFixed(0)` them.
      var x0 = x.toFixed(0) + 'px';
      var y0 = y.toFixed(0) + 'px'; // not support transform, use `left` and `top` instead.

      if (!env.transformSupported) {
        return toString ? "top:" + y0 + ";left:" + x0 + ";" : [['top', y0], ['left', x0]];
      } // support transform


      var is3d = env.transform3dSupported;
      var translate = "translate" + (is3d ? '3d' : '') + "(" + x0 + "," + y0 + (is3d ? ',0' : '') + ")";
      return toString ? 'top:0;left:0;' + CSS_TRANSFORM_VENDOR + ':' + translate + ';' : [['top', 0], ['left', 0], [TRANSFORM_VENDOR, translate]];
    }
    /**
     * @param {Object} textStyle
     * @return {string}
     * @inner
     */


    function assembleFont(textStyleModel) {
      var cssText = [];
      var fontSize = textStyleModel.get('fontSize');
      var color = textStyleModel.getTextColor();
      color && cssText.push('color:' + color);
      cssText.push('font:' + textStyleModel.getFont());
      fontSize // @ts-ignore, leave it to the tooltip refactor.
      && cssText.push('line-height:' + Math.round(fontSize * 3 / 2) + 'px');
      var shadowColor = textStyleModel.get('textShadowColor');
      var shadowBlur = textStyleModel.get('textShadowBlur') || 0;
      var shadowOffsetX = textStyleModel.get('textShadowOffsetX') || 0;
      var shadowOffsetY = textStyleModel.get('textShadowOffsetY') || 0;
      shadowColor && shadowBlur && cssText.push('text-shadow:' + shadowOffsetX + 'px ' + shadowOffsetY + 'px ' + shadowBlur + 'px ' + shadowColor);
      each(['decoration', 'align'], function (name) {
        var val = textStyleModel.get(name);
        val && cssText.push('text-' + name + ':' + val);
      });
      return cssText.join(';');
    }

    function assembleCssText(tooltipModel, enableTransition, onlyFade) {
      var cssText = [];
      var transitionDuration = tooltipModel.get('transitionDuration');
      var backgroundColor = tooltipModel.get('backgroundColor');
      var shadowBlur = tooltipModel.get('shadowBlur');
      var shadowColor = tooltipModel.get('shadowColor');
      var shadowOffsetX = tooltipModel.get('shadowOffsetX');
      var shadowOffsetY = tooltipModel.get('shadowOffsetY');
      var textStyleModel = tooltipModel.getModel('textStyle');
      var padding = getPaddingFromTooltipModel(tooltipModel, 'html');
      var boxShadow = shadowOffsetX + "px " + shadowOffsetY + "px " + shadowBlur + "px " + shadowColor;
      cssText.push('box-shadow:' + boxShadow); // Animation transition. Do not animate when transitionDuration is 0.

      enableTransition && transitionDuration && cssText.push(assembleTransition(transitionDuration, onlyFade));

      if (backgroundColor) {
        cssText.push('background-color:' + backgroundColor);
      } // Border style


      each(['width', 'color', 'radius'], function (name) {
        var borderName = 'border-' + name;
        var camelCase = toCamelCase(borderName);
        var val = tooltipModel.get(camelCase);
        val != null && cssText.push(borderName + ':' + val + (name === 'color' ? '' : 'px'));
      }); // Text style

      cssText.push(assembleFont(textStyleModel)); // Padding

      if (padding != null) {
        cssText.push('padding:' + normalizeCssArray$1(padding).join('px ') + 'px');
      }

      return cssText.join(';') + ';';
    } // If not able to make, do not modify the input `out`.


    function makeStyleCoord(out, zr, appendToBody, zrX, zrY) {
      var zrPainter = zr && zr.painter;

      if (appendToBody) {
        var zrViewportRoot = zrPainter && zrPainter.getViewportRoot();

        if (zrViewportRoot) {
          // Some APPs might use scale on body, so we support CSS transform here.
          transformLocalCoord(out, zrViewportRoot, document.body, zrX, zrY);
        }
      } else {
        out[0] = zrX;
        out[1] = zrY; // xy should be based on canvas root. But tooltipContent is
        // the sibling of canvas root. So padding of ec container
        // should be considered here.

        var viewportRootOffset = zrPainter && zrPainter.getViewportRootOffset();

        if (viewportRootOffset) {
          out[0] += viewportRootOffset.offsetLeft;
          out[1] += viewportRootOffset.offsetTop;
        }
      }

      out[2] = out[0] / zr.getWidth();
      out[3] = out[1] / zr.getHeight();
    }

    var TooltipHTMLContent =
    /** @class */
    function () {
      function TooltipHTMLContent(container, api, opt) {
        this._show = false;
        this._styleCoord = [0, 0, 0, 0];
        this._enterable = true;
        this._firstShow = true;
        this._longHide = true;

        if (env.wxa) {
          return null;
        }

        var el = document.createElement('div'); // TODO: TYPE

        el.domBelongToZr = true;
        this.el = el;
        var zr = this._zr = api.getZr();
        var appendToBody = this._appendToBody = opt && opt.appendToBody;
        makeStyleCoord(this._styleCoord, zr, appendToBody, api.getWidth() / 2, api.getHeight() / 2);

        if (appendToBody) {
          document.body.appendChild(el);
        } else {
          container.appendChild(el);
        }

        this._container = container; // FIXME
        // Is it needed to trigger zr event manually if
        // the browser do not support `pointer-events: none`.

        var self = this;

        el.onmouseenter = function () {
          // clear the timeout in hideLater and keep showing tooltip
          if (self._enterable) {
            clearTimeout(self._hideTimeout);
            self._show = true;
          }

          self._inContent = true;
        };

        el.onmousemove = function (e) {
          e = e || window.event;

          if (!self._enterable) {
            // `pointer-events: none` is set to tooltip content div
            // if `enterable` is set as `false`, and `el.onmousemove`
            // can not be triggered. But in browser that do not
            // support `pointer-events`, we need to do this:
            // Try trigger zrender event to avoid mouse
            // in and out shape too frequently
            var handler = zr.handler;
            var zrViewportRoot = zr.painter.getViewportRoot();
            normalizeEvent(zrViewportRoot, e, true);
            handler.dispatch('mousemove', e);
          }
        };

        el.onmouseleave = function () {
          // set `_inContent` to `false` before `hideLater`
          self._inContent = false;

          if (self._enterable) {
            if (self._show) {
              self.hideLater(self._hideDelay);
            }
          }
        };
      }
      /**
       * Update when tooltip is rendered
       */


      TooltipHTMLContent.prototype.update = function (tooltipModel) {
        // FIXME
        // Move this logic to ec main?
        var container = this._container;
        var position = getComputedStyle(container, 'position');
        var domStyle = container.style;

        if (domStyle.position !== 'absolute' && position !== 'absolute') {
          domStyle.position = 'relative';
        } // move tooltip if chart resized


        var alwaysShowContent = tooltipModel.get('alwaysShowContent');
        alwaysShowContent && this._moveIfResized(); // update className

        this.el.className = tooltipModel.get('className') || ''; // Hide the tooltip
        // PENDING
        // this.hide();
      };

      TooltipHTMLContent.prototype.show = function (tooltipModel, nearPointColor) {
        clearTimeout(this._hideTimeout);
        clearTimeout(this._longHideTimeout);
        var el = this.el;
        var style = el.style;
        var styleCoord = this._styleCoord;

        if (!el.innerHTML) {
          style.display = 'none';
        } else {
          style.cssText = gCssText + assembleCssText(tooltipModel, !this._firstShow, this._longHide) // initial transform
          + assembleTransform(styleCoord[0], styleCoord[1], true) + ("border-color:" + convertToColorString(nearPointColor) + ";") + (tooltipModel.get('extraCssText') || '') // If mouse occasionally move over the tooltip, a mouseout event will be
          // triggered by canvas, and cause some unexpectable result like dragging
          // stop, "unfocusAdjacency". Here `pointer-events: none` is used to solve
          // it. Although it is not supported by IE8~IE10, fortunately it is a rare
          // scenario.
          + (";pointer-events:" + (this._enterable ? 'auto' : 'none'));
        }

        this._show = true;
        this._firstShow = false;
        this._longHide = false;
      };

      TooltipHTMLContent.prototype.setContent = function (content, markers, tooltipModel, borderColor, arrowPosition) {
        var el = this.el;

        if (content == null) {
          if (self.trustedTypes && self.trustedTypes.createPolicy) {
            var policy = self.trustedTypes.createPolicy('TooltipHTMLFix1', {
              createHTML: function (_ignored) {
                return "";
              }
            });
            el.innerHTML = policy.createHTML('_ignored');
            return;
          } else {
            el.innerHTML = '';
            return;
          }
        }

        var arrow = '';

        if (isString(arrowPosition) && tooltipModel.get('trigger') === 'item' && !shouldTooltipConfine(tooltipModel)) {
          arrow = assembleArrow(tooltipModel, borderColor, arrowPosition);
        }

        if (isString(content)) {
          if (self.trustedTypes && self.trustedTypes.createPolicy) {
            var policy = self.trustedTypes.createPolicy('TooltipHTMLFix2', {
              createHTML: function (string) {
                return string;
              }
            });
            el.innerHTML = policy.createHTML(content + arrow);
          } else {
            el.innerHTML = content + arrow;
          }
        } else if (content) {
          // Clear previous
          if (self.trustedTypes && self.trustedTypes.createPolicy) {
            var policy = self.trustedTypes.createPolicy('TooltipHTMLFix3', {
              createHTML: function (_ignored) {
                return "";
              }
            });
            el.innerHTML = policy.createHTML('_ignored');
          } else {
            el.innerHTML = '';
          }

          if (!isArray(content)) {
            content = [content];
          }

          for (var i = 0; i < content.length; i++) {
            if (isDom(content[i]) && content[i].parentNode !== el) {
              el.appendChild(content[i]);
            }
          } // no arrow if empty


          if (arrow && el.childNodes.length) {
            // no need to create a new parent element, but it's not supported by IE 10 and older.
            // const arrowEl = document.createRange().createContextualFragment(arrow);
            var arrowEl = document.createElement('div');
            arrowEl.innerHTML = arrow;
            el.appendChild(arrowEl);
          }
        }
      };

      TooltipHTMLContent.prototype.setEnterable = function (enterable) {
        this._enterable = enterable;
      };

      TooltipHTMLContent.prototype.getSize = function () {
        var el = this.el;
        return [el.offsetWidth, el.offsetHeight];
      };

      TooltipHTMLContent.prototype.moveTo = function (zrX, zrY) {
        var styleCoord = this._styleCoord;
        makeStyleCoord(styleCoord, this._zr, this._appendToBody, zrX, zrY);

        if (styleCoord[0] != null && styleCoord[1] != null) {
          var style_1 = this.el.style;
          var transforms = assembleTransform(styleCoord[0], styleCoord[1]);
          each(transforms, function (transform) {
            style_1[transform[0]] = transform[1];
          });
        }
      };
      /**
       * when `alwaysShowContent` is true,
       * move the tooltip after chart resized
       */


      TooltipHTMLContent.prototype._moveIfResized = function () {
        // The ratio of left to width
        var ratioX = this._styleCoord[2]; // The ratio of top to height

        var ratioY = this._styleCoord[3];
        this.moveTo(ratioX * this._zr.getWidth(), ratioY * this._zr.getHeight());
      };

      TooltipHTMLContent.prototype.hide = function () {
        var _this = this;

        var style = this.el.style;
        style.visibility = 'hidden';
        style.opacity = '0';
        env.transform3dSupported && (style.willChange = '');
        this._show = false;
        this._longHideTimeout = setTimeout(function () {
          return _this._longHide = true;
        }, 500);
      };

      TooltipHTMLContent.prototype.hideLater = function (time) {
        if (this._show && !(this._inContent && this._enterable)) {
          if (time) {
            this._hideDelay = time; // Set show false to avoid invoke hideLater multiple times

            this._show = false;
            this._hideTimeout = setTimeout(bind(this.hide, this), time);
          } else {
            this.hide();
          }
        }
      };

      TooltipHTMLContent.prototype.isShow = function () {
        return this._show;
      };

      TooltipHTMLContent.prototype.dispose = function () {
        this.el.parentNode.removeChild(this.el);
      };

      return TooltipHTMLContent;
    }();

    var TooltipRichContent =
    /** @class */
    function () {
      function TooltipRichContent(api) {
        this._show = false;
        this._styleCoord = [0, 0, 0, 0];
        this._enterable = true;
        this._zr = api.getZr();
        makeStyleCoord$1(this._styleCoord, this._zr, api.getWidth() / 2, api.getHeight() / 2);
      }
      /**
       * Update when tooltip is rendered
       */


      TooltipRichContent.prototype.update = function (tooltipModel) {
        var alwaysShowContent = tooltipModel.get('alwaysShowContent');
        alwaysShowContent && this._moveIfResized();
      };

      TooltipRichContent.prototype.show = function () {
        if (this._hideTimeout) {
          clearTimeout(this._hideTimeout);
        }

        this.el.show();
        this._show = true;
      };
      /**
       * Set tooltip content
       */


      TooltipRichContent.prototype.setContent = function (content, markupStyleCreator, tooltipModel, borderColor, arrowPosition) {
        var _this = this;

        if (isObject(content)) {
          throwError("development" !== 'production' ? 'Passing DOM nodes as content is not supported in richText tooltip!' : '');
        }

        if (this.el) {
          this._zr.remove(this.el);
        }

        var textStyleModel = tooltipModel.getModel('textStyle');
        this.el = new ZRText({
          style: {
            rich: markupStyleCreator.richTextStyles,
            text: content,
            lineHeight: 22,
            borderWidth: 1,
            borderColor: borderColor,
            textShadowColor: textStyleModel.get('textShadowColor'),
            fill: tooltipModel.get(['textStyle', 'color']),
            padding: getPaddingFromTooltipModel(tooltipModel, 'richText'),
            verticalAlign: 'top',
            align: 'left'
          },
          z: tooltipModel.get('z')
        });
        each(['backgroundColor', 'borderRadius', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'], function (propName) {
          _this.el.style[propName] = tooltipModel.get(propName);
        });
        each(['textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY'], function (propName) {
          _this.el.style[propName] = textStyleModel.get(propName) || 0;
        });

        this._zr.add(this.el);

        var self = this;
        this.el.on('mouseover', function () {
          // clear the timeout in hideLater and keep showing tooltip
          if (self._enterable) {
            clearTimeout(self._hideTimeout);
            self._show = true;
          }

          self._inContent = true;
        });
        this.el.on('mouseout', function () {
          if (self._enterable) {
            if (self._show) {
              self.hideLater(self._hideDelay);
            }
          }

          self._inContent = false;
        });
      };

      TooltipRichContent.prototype.setEnterable = function (enterable) {
        this._enterable = enterable;
      };

      TooltipRichContent.prototype.getSize = function () {
        var el = this.el;
        var bounding = this.el.getBoundingRect(); // bounding rect does not include shadow. For renderMode richText,
        // if overflow, it will be cut. So calculate them accurately.

        var shadowOuterSize = calcShadowOuterSize(el.style);
        return [bounding.width + shadowOuterSize.left + shadowOuterSize.right, bounding.height + shadowOuterSize.top + shadowOuterSize.bottom];
      };

      TooltipRichContent.prototype.moveTo = function (x, y) {
        var el = this.el;

        if (el) {
          var styleCoord = this._styleCoord;
          makeStyleCoord$1(styleCoord, this._zr, x, y);
          x = styleCoord[0];
          y = styleCoord[1];
          var style = el.style;
          var borderWidth = mathMaxWith0(style.borderWidth || 0);
          var shadowOuterSize = calcShadowOuterSize(style); // rich text x, y do not include border.

          el.x = x + borderWidth + shadowOuterSize.left;
          el.y = y + borderWidth + shadowOuterSize.top;
          el.markRedraw();
        }
      };
      /**
       * when `alwaysShowContent` is true,
       * move the tooltip after chart resized
       */


      TooltipRichContent.prototype._moveIfResized = function () {
        // The ratio of left to width
        var ratioX = this._styleCoord[2]; // The ratio of top to height

        var ratioY = this._styleCoord[3];
        this.moveTo(ratioX * this._zr.getWidth(), ratioY * this._zr.getHeight());
      };

      TooltipRichContent.prototype.hide = function () {
        if (this.el) {
          this.el.hide();
        }

        this._show = false;
      };

      TooltipRichContent.prototype.hideLater = function (time) {
        if (this._show && !(this._inContent && this._enterable)) {
          if (time) {
            this._hideDelay = time; // Set show false to avoid invoke hideLater multiple times

            this._show = false;
            this._hideTimeout = setTimeout(bind(this.hide, this), time);
          } else {
            this.hide();
          }
        }
      };

      TooltipRichContent.prototype.isShow = function () {
        return this._show;
      };

      TooltipRichContent.prototype.dispose = function () {
        this._zr.remove(this.el);
      };

      return TooltipRichContent;
    }();

    function mathMaxWith0(val) {
      return Math.max(0, val);
    }

    function calcShadowOuterSize(style) {
      var shadowBlur = mathMaxWith0(style.shadowBlur || 0);
      var shadowOffsetX = mathMaxWith0(style.shadowOffsetX || 0);
      var shadowOffsetY = mathMaxWith0(style.shadowOffsetY || 0);
      return {
        left: mathMaxWith0(shadowBlur - shadowOffsetX),
        right: mathMaxWith0(shadowBlur + shadowOffsetX),
        top: mathMaxWith0(shadowBlur - shadowOffsetY),
        bottom: mathMaxWith0(shadowBlur + shadowOffsetY)
      };
    }

    function makeStyleCoord$1(out, zr, zrX, zrY) {
      out[0] = zrX;
      out[1] = zrY;
      out[2] = out[0] / zr.getWidth();
      out[3] = out[1] / zr.getHeight();
    }

    var proxyRect = new Rect({
      shape: {
        x: -1,
        y: -1,
        width: 2,
        height: 2
      }
    });

    var TooltipView =
    /** @class */
    function (_super) {
      __extends(TooltipView, _super);

      function TooltipView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TooltipView.type;
        return _this;
      }

      TooltipView.prototype.init = function (ecModel, api) {
        if (env.node || !api.getDom()) {
          return;
        }

        var tooltipModel = ecModel.getComponent('tooltip');
        var renderMode = this._renderMode = getTooltipRenderMode(tooltipModel.get('renderMode'));
        this._tooltipContent = renderMode === 'richText' ? new TooltipRichContent(api) : new TooltipHTMLContent(api.getDom(), api, {
          appendToBody: tooltipModel.get('appendToBody', true)
        });
      };

      TooltipView.prototype.render = function (tooltipModel, ecModel, api) {
        if (env.node || !api.getDom()) {
          return;
        } // Reset


        this.group.removeAll();
        this._tooltipModel = tooltipModel;
        this._ecModel = ecModel;
        this._api = api;
        /**
         * @private
         * @type {boolean}
         */

        this._alwaysShowContent = tooltipModel.get('alwaysShowContent');
        var tooltipContent = this._tooltipContent;
        tooltipContent.update(tooltipModel);
        tooltipContent.setEnterable(tooltipModel.get('enterable'));

        this._initGlobalListener();

        this._keepShow(); // PENDING
        // `mousemove` event will be triggered very frequently when the mouse moves fast,
        // which causes that the `updatePosition` function was also called frequently.
        // In Chrome with devtools open and Firefox, tooltip looks laggy and shakes. See #14695 #16101
        // To avoid frequent triggering,
        // consider throttling it in 50ms when transition is enabled


        if (this._renderMode !== 'richText' && tooltipModel.get('transitionDuration')) {
          createOrUpdate(this, '_updatePosition', 50, 'fixRate');
        } else {
          clear(this, '_updatePosition');
        }
      };

      TooltipView.prototype._initGlobalListener = function () {
        var tooltipModel = this._tooltipModel;
        var triggerOn = tooltipModel.get('triggerOn');
        register('itemTooltip', this._api, bind(function (currTrigger, e, dispatchAction) {
          // If 'none', it is not controlled by mouse totally.
          if (triggerOn !== 'none') {
            if (triggerOn.indexOf(currTrigger) >= 0) {
              this._tryShow(e, dispatchAction);
            } else if (currTrigger === 'leave') {
              this._hide(dispatchAction);
            }
          }
        }, this));
      };

      TooltipView.prototype._keepShow = function () {
        var tooltipModel = this._tooltipModel;
        var ecModel = this._ecModel;
        var api = this._api;
        var triggerOn = tooltipModel.get('triggerOn'); // Try to keep the tooltip show when refreshing

        if (this._lastX != null && this._lastY != null // When user is willing to control tooltip totally using API,
        // self.manuallyShowTip({x, y}) might cause tooltip hide,
        // which is not expected.
        && triggerOn !== 'none' && triggerOn !== 'click') {
          var self_1 = this;
          clearTimeout(this._refreshUpdateTimeout);
          this._refreshUpdateTimeout = setTimeout(function () {
            // Show tip next tick after other charts are rendered
            // In case highlight action has wrong result
            // FIXME
            !api.isDisposed() && self_1.manuallyShowTip(tooltipModel, ecModel, api, {
              x: self_1._lastX,
              y: self_1._lastY,
              dataByCoordSys: self_1._lastDataByCoordSys
            });
          });
        }
      };
      /**
       * Show tip manually by
       * dispatchAction({
       *     type: 'showTip',
       *     x: 10,
       *     y: 10
       * });
       * Or
       * dispatchAction({
       *      type: 'showTip',
       *      seriesIndex: 0,
       *      dataIndex or dataIndexInside or name
       * });
       *
       *  TODO Batch
       */


      TooltipView.prototype.manuallyShowTip = function (tooltipModel, ecModel, api, payload) {
        if (payload.from === this.uid || env.node || !api.getDom()) {
          return;
        }

        var dispatchAction = makeDispatchAction$1(payload, api); // Reset ticket

        this._ticket = ''; // When triggered from axisPointer.

        var dataByCoordSys = payload.dataByCoordSys;
        var cmptRef = findComponentReference(payload, ecModel, api);

        if (cmptRef) {
          var rect = cmptRef.el.getBoundingRect().clone();
          rect.applyTransform(cmptRef.el.transform);

          this._tryShow({
            offsetX: rect.x + rect.width / 2,
            offsetY: rect.y + rect.height / 2,
            target: cmptRef.el,
            position: payload.position,
            // When manully trigger, the mouse is not on the el, so we'd better to
            // position tooltip on the bottom of the el and display arrow is possible.
            positionDefault: 'bottom'
          }, dispatchAction);
        } else if (payload.tooltip && payload.x != null && payload.y != null) {
          var el = proxyRect;
          el.x = payload.x;
          el.y = payload.y;
          el.update();
          getECData(el).tooltipConfig = {
            name: null,
            option: payload.tooltip
          }; // Manually show tooltip while view is not using zrender elements.

          this._tryShow({
            offsetX: payload.x,
            offsetY: payload.y,
            target: el
          }, dispatchAction);
        } else if (dataByCoordSys) {
          this._tryShow({
            offsetX: payload.x,
            offsetY: payload.y,
            position: payload.position,
            dataByCoordSys: dataByCoordSys,
            tooltipOption: payload.tooltipOption
          }, dispatchAction);
        } else if (payload.seriesIndex != null) {
          if (this._manuallyAxisShowTip(tooltipModel, ecModel, api, payload)) {
            return;
          }

          var pointInfo = findPointFromSeries(payload, ecModel);
          var cx = pointInfo.point[0];
          var cy = pointInfo.point[1];

          if (cx != null && cy != null) {
            this._tryShow({
              offsetX: cx,
              offsetY: cy,
              target: pointInfo.el,
              position: payload.position,
              // When manully trigger, the mouse is not on the el, so we'd better to
              // position tooltip on the bottom of the el and display arrow is possible.
              positionDefault: 'bottom'
            }, dispatchAction);
          }
        } else if (payload.x != null && payload.y != null) {
          // FIXME
          // should wrap dispatchAction like `axisPointer/globalListener` ?
          api.dispatchAction({
            type: 'updateAxisPointer',
            x: payload.x,
            y: payload.y
          });

          this._tryShow({
            offsetX: payload.x,
            offsetY: payload.y,
            position: payload.position,
            target: api.getZr().findHover(payload.x, payload.y).target
          }, dispatchAction);
        }
      };

      TooltipView.prototype.manuallyHideTip = function (tooltipModel, ecModel, api, payload) {
        var tooltipContent = this._tooltipContent;

        if (!this._alwaysShowContent && this._tooltipModel) {
          tooltipContent.hideLater(this._tooltipModel.get('hideDelay'));
        }

        this._lastX = this._lastY = this._lastDataByCoordSys = null;

        if (payload.from !== this.uid) {
          this._hide(makeDispatchAction$1(payload, api));
        }
      }; // Be compatible with previous design, that is, when tooltip.type is 'axis' and
      // dispatchAction 'showTip' with seriesIndex and dataIndex will trigger axis pointer
      // and tooltip.


      TooltipView.prototype._manuallyAxisShowTip = function (tooltipModel, ecModel, api, payload) {
        var seriesIndex = payload.seriesIndex;
        var dataIndex = payload.dataIndex; // @ts-ignore

        var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo;

        if (seriesIndex == null || dataIndex == null || coordSysAxesInfo == null) {
          return;
        }

        var seriesModel = ecModel.getSeriesByIndex(seriesIndex);

        if (!seriesModel) {
          return;
        }

        var data = seriesModel.getData();
        var tooltipCascadedModel = buildTooltipModel([data.getItemModel(dataIndex), seriesModel, (seriesModel.coordinateSystem || {}).model], this._tooltipModel);

        if (tooltipCascadedModel.get('trigger') !== 'axis') {
          return;
        }

        api.dispatchAction({
          type: 'updateAxisPointer',
          seriesIndex: seriesIndex,
          dataIndex: dataIndex,
          position: payload.position
        });
        return true;
      };

      TooltipView.prototype._tryShow = function (e, dispatchAction) {
        var el = e.target;
        var tooltipModel = this._tooltipModel;

        if (!tooltipModel) {
          return;
        } // Save mouse x, mouse y. So we can try to keep showing the tip if chart is refreshed


        this._lastX = e.offsetX;
        this._lastY = e.offsetY;
        var dataByCoordSys = e.dataByCoordSys;

        if (dataByCoordSys && dataByCoordSys.length) {
          this._showAxisTooltip(dataByCoordSys, e);
        } else if (el) {
          this._lastDataByCoordSys = null;
          var seriesDispatcher_1;
          var cmptDispatcher_1;
          findEventDispatcher(el, function (target) {
            // Always show item tooltip if mouse is on the element with dataIndex
            if (getECData(target).dataIndex != null) {
              seriesDispatcher_1 = target;
              return true;
            } // Tooltip provided directly. Like legend.


            if (getECData(target).tooltipConfig != null) {
              cmptDispatcher_1 = target;
              return true;
            }
          }, true);

          if (seriesDispatcher_1) {
            this._showSeriesItemTooltip(e, seriesDispatcher_1, dispatchAction);
          } else if (cmptDispatcher_1) {
            this._showComponentItemTooltip(e, cmptDispatcher_1, dispatchAction);
          } else {
            this._hide(dispatchAction);
          }
        } else {
          this._lastDataByCoordSys = null;

          this._hide(dispatchAction);
        }
      };

      TooltipView.prototype._showOrMove = function (tooltipModel, cb) {
        // showDelay is used in this case: tooltip.enterable is set
        // as true. User intent to move mouse into tooltip and click
        // something. `showDelay` makes it easier to enter the content
        // but tooltip do not move immediately.
        var delay = tooltipModel.get('showDelay');
        cb = bind(cb, this);
        clearTimeout(this._showTimout);
        delay > 0 ? this._showTimout = setTimeout(cb, delay) : cb();
      };

      TooltipView.prototype._showAxisTooltip = function (dataByCoordSys, e) {
        var ecModel = this._ecModel;
        var globalTooltipModel = this._tooltipModel;
        var point = [e.offsetX, e.offsetY];
        var singleTooltipModel = buildTooltipModel([e.tooltipOption], globalTooltipModel);
        var renderMode = this._renderMode;
        var cbParamsList = [];
        var articleMarkup = createTooltipMarkup('section', {
          blocks: [],
          noHeader: true
        }); // Only for legacy: `Serise['formatTooltip']` returns a string.

        var markupTextArrLegacy = [];
        var markupStyleCreator = new TooltipMarkupStyleCreator();
        each(dataByCoordSys, function (itemCoordSys) {
          each(itemCoordSys.dataByAxis, function (axisItem) {
            var axisModel = ecModel.getComponent(axisItem.axisDim + 'Axis', axisItem.axisIndex);
            var axisValue = axisItem.value;

            if (!axisModel || axisValue == null) {
              return;
            }

            var axisValueLabel = getValueLabel(axisValue, axisModel.axis, ecModel, axisItem.seriesDataIndices, axisItem.valueLabelOpt);
            var axisSectionMarkup = createTooltipMarkup('section', {
              header: axisValueLabel,
              noHeader: !trim(axisValueLabel),
              sortBlocks: true,
              blocks: []
            });
            articleMarkup.blocks.push(axisSectionMarkup);
            each(axisItem.seriesDataIndices, function (idxItem) {
              var series = ecModel.getSeriesByIndex(idxItem.seriesIndex);
              var dataIndex = idxItem.dataIndexInside;
              var cbParams = series.getDataParams(dataIndex); // Can't find data.

              if (cbParams.dataIndex < 0) {
                return;
              }

              cbParams.axisDim = axisItem.axisDim;
              cbParams.axisIndex = axisItem.axisIndex;
              cbParams.axisType = axisItem.axisType;
              cbParams.axisId = axisItem.axisId;
              cbParams.axisValue = getAxisRawValue(axisModel.axis, {
                value: axisValue
              });
              cbParams.axisValueLabel = axisValueLabel; // Pre-create marker style for makers. Users can assemble richText
              // text in `formatter` callback and use those markers style.

              cbParams.marker = markupStyleCreator.makeTooltipMarker('item', convertToColorString(cbParams.color), renderMode);
              var seriesTooltipResult = normalizeTooltipFormatResult(series.formatTooltip(dataIndex, true, null));
              var frag = seriesTooltipResult.frag;

              if (frag) {
                var valueFormatter = buildTooltipModel([series], globalTooltipModel).get('valueFormatter');
                axisSectionMarkup.blocks.push(valueFormatter ? extend({
                  valueFormatter: valueFormatter
                }, frag) : frag);
              }

              if (seriesTooltipResult.text) {
                markupTextArrLegacy.push(seriesTooltipResult.text);
              }

              cbParamsList.push(cbParams);
            });
          });
        }); // In most cases, the second axis is displays upper on the first one.
        // So we reverse it to look better.

        articleMarkup.blocks.reverse();
        markupTextArrLegacy.reverse();
        var positionExpr = e.position;
        var orderMode = singleTooltipModel.get('order');
        var builtMarkupText = buildTooltipMarkup(articleMarkup, markupStyleCreator, renderMode, orderMode, ecModel.get('useUTC'), singleTooltipModel.get('textStyle'));
        builtMarkupText && markupTextArrLegacy.unshift(builtMarkupText);
        var blockBreak = renderMode === 'richText' ? '\n\n' : '<br/>';
        var allMarkupText = markupTextArrLegacy.join(blockBreak);

        this._showOrMove(singleTooltipModel, function () {
          if (this._updateContentNotChangedOnAxis(dataByCoordSys, cbParamsList)) {
            this._updatePosition(singleTooltipModel, positionExpr, point[0], point[1], this._tooltipContent, cbParamsList);
          } else {
            this._showTooltipContent(singleTooltipModel, allMarkupText, cbParamsList, Math.random() + '', point[0], point[1], positionExpr, null, markupStyleCreator);
          }
        }); // Do not trigger events here, because this branch only be entered
        // from dispatchAction.

      };

      TooltipView.prototype._showSeriesItemTooltip = function (e, dispatcher, dispatchAction) {
        var ecModel = this._ecModel;
        var ecData = getECData(dispatcher); // Use dataModel in element if possible
        // Used when mouseover on a element like markPoint or edge
        // In which case, the data is not main data in series.

        var seriesIndex = ecData.seriesIndex;
        var seriesModel = ecModel.getSeriesByIndex(seriesIndex); // For example, graph link.

        var dataModel = ecData.dataModel || seriesModel;
        var dataIndex = ecData.dataIndex;
        var dataType = ecData.dataType;
        var data = dataModel.getData(dataType);
        var renderMode = this._renderMode;
        var positionDefault = e.positionDefault;
        var tooltipModel = buildTooltipModel([data.getItemModel(dataIndex), dataModel, seriesModel && (seriesModel.coordinateSystem || {}).model], this._tooltipModel, positionDefault ? {
          position: positionDefault
        } : null);
        var tooltipTrigger = tooltipModel.get('trigger');

        if (tooltipTrigger != null && tooltipTrigger !== 'item') {
          return;
        }

        var params = dataModel.getDataParams(dataIndex, dataType);
        var markupStyleCreator = new TooltipMarkupStyleCreator(); // Pre-create marker style for makers. Users can assemble richText
        // text in `formatter` callback and use those markers style.

        params.marker = markupStyleCreator.makeTooltipMarker('item', convertToColorString(params.color), renderMode);
        var seriesTooltipResult = normalizeTooltipFormatResult(dataModel.formatTooltip(dataIndex, false, dataType));
        var orderMode = tooltipModel.get('order');
        var valueFormatter = tooltipModel.get('valueFormatter');
        var frag = seriesTooltipResult.frag;
        var markupText = frag ? buildTooltipMarkup(valueFormatter ? extend({
          valueFormatter: valueFormatter
        }, frag) : frag, markupStyleCreator, renderMode, orderMode, ecModel.get('useUTC'), tooltipModel.get('textStyle')) : seriesTooltipResult.text;
        var asyncTicket = 'item_' + dataModel.name + '_' + dataIndex;

        this._showOrMove(tooltipModel, function () {
          this._showTooltipContent(tooltipModel, markupText, params, asyncTicket, e.offsetX, e.offsetY, e.position, e.target, markupStyleCreator);
        }); // FIXME
        // duplicated showtip if manuallyShowTip is called from dispatchAction.


        dispatchAction({
          type: 'showTip',
          dataIndexInside: dataIndex,
          dataIndex: data.getRawIndex(dataIndex),
          seriesIndex: seriesIndex,
          from: this.uid
        });
      };

      TooltipView.prototype._showComponentItemTooltip = function (e, el, dispatchAction) {
        var ecData = getECData(el);
        var tooltipConfig = ecData.tooltipConfig;
        var tooltipOpt = tooltipConfig.option || {};

        if (isString(tooltipOpt)) {
          var content = tooltipOpt;
          tooltipOpt = {
            content: content,
            // Fixed formatter
            formatter: content
          };
        }

        var tooltipModelCascade = [tooltipOpt];

        var cmpt = this._ecModel.getComponent(ecData.componentMainType, ecData.componentIndex);

        if (cmpt) {
          tooltipModelCascade.push(cmpt);
        } // In most cases, component tooltip formatter has different params with series tooltip formatter,
        // so that they can not share the same formatter. Since the global tooltip formatter is used for series
        // by convension, we do not use it as the default formatter for component.


        tooltipModelCascade.push({
          formatter: tooltipOpt.content
        });
        var positionDefault = e.positionDefault;
        var subTooltipModel = buildTooltipModel(tooltipModelCascade, this._tooltipModel, positionDefault ? {
          position: positionDefault
        } : null);
        var defaultHtml = subTooltipModel.get('content');
        var asyncTicket = Math.random() + ''; // PENDING: this case do not support richText style yet.

        var markupStyleCreator = new TooltipMarkupStyleCreator(); // Do not check whether `trigger` is 'none' here, because `trigger`
        // only works on coordinate system. In fact, we have not found case
        // that requires setting `trigger` nothing on component yet.

        this._showOrMove(subTooltipModel, function () {
          // Use formatterParams from element defined in component
          // Avoid users modify it.
          var formatterParams = clone(subTooltipModel.get('formatterParams') || {});

          this._showTooltipContent(subTooltipModel, defaultHtml, formatterParams, asyncTicket, e.offsetX, e.offsetY, e.position, el, markupStyleCreator);
        }); // If not dispatch showTip, tip may be hide triggered by axis.


        dispatchAction({
          type: 'showTip',
          from: this.uid
        });
      };

      TooltipView.prototype._showTooltipContent = function ( // Use Model<TooltipOption> insteadof TooltipModel because this model may be from series or other options.
      // Instead of top level tooltip.
      tooltipModel, defaultHtml, params, asyncTicket, x, y, positionExpr, el, markupStyleCreator) {
        // Reset ticket
        this._ticket = '';

        if (!tooltipModel.get('showContent') || !tooltipModel.get('show')) {
          return;
        }

        var tooltipContent = this._tooltipContent;
        tooltipContent.setEnterable(tooltipModel.get('enterable'));
        var formatter = tooltipModel.get('formatter');
        positionExpr = positionExpr || tooltipModel.get('position');
        var html = defaultHtml;

        var nearPoint = this._getNearestPoint([x, y], params, tooltipModel.get('trigger'), tooltipModel.get('borderColor'));

        var nearPointColor = nearPoint.color;

        if (formatter) {
          if (isString(formatter)) {
            var useUTC = tooltipModel.ecModel.get('useUTC');
            var params0 = isArray(params) ? params[0] : params;
            var isTimeAxis = params0 && params0.axisType && params0.axisType.indexOf('time') >= 0;
            html = formatter;

            if (isTimeAxis) {
              html = format(params0.axisValue, html, useUTC);
            }

            html = formatTpl(html, params, true);
          } else if (isFunction(formatter)) {
            var callback = bind(function (cbTicket, html) {
              if (cbTicket === this._ticket) {
                tooltipContent.setContent(html, markupStyleCreator, tooltipModel, nearPointColor, positionExpr);

                this._updatePosition(tooltipModel, positionExpr, x, y, tooltipContent, params, el);
              }
            }, this);
            this._ticket = asyncTicket;
            html = formatter(params, asyncTicket, callback);
          } else {
            html = formatter;
          }
        }

        tooltipContent.setContent(html, markupStyleCreator, tooltipModel, nearPointColor, positionExpr);
        tooltipContent.show(tooltipModel, nearPointColor);

        this._updatePosition(tooltipModel, positionExpr, x, y, tooltipContent, params, el);
      };

      TooltipView.prototype._getNearestPoint = function (point, tooltipDataParams, trigger, borderColor) {
        if (trigger === 'axis' || isArray(tooltipDataParams)) {
          return {
            color: borderColor || (this._renderMode === 'html' ? '#fff' : 'none')
          };
        }

        if (!isArray(tooltipDataParams)) {
          return {
            color: borderColor || tooltipDataParams.color || tooltipDataParams.borderColor
          };
        }
      };

      TooltipView.prototype._updatePosition = function (tooltipModel, positionExpr, x, // Mouse x
      y, // Mouse y
      content, params, el) {
        var viewWidth = this._api.getWidth();

        var viewHeight = this._api.getHeight();

        positionExpr = positionExpr || tooltipModel.get('position');
        var contentSize = content.getSize();
        var align = tooltipModel.get('align');
        var vAlign = tooltipModel.get('verticalAlign');
        var rect = el && el.getBoundingRect().clone();
        el && rect.applyTransform(el.transform);

        if (isFunction(positionExpr)) {
          // Callback of position can be an array or a string specify the position
          positionExpr = positionExpr([x, y], params, content.el, rect, {
            viewSize: [viewWidth, viewHeight],
            contentSize: contentSize.slice()
          });
        }

        if (isArray(positionExpr)) {
          x = parsePercent$1(positionExpr[0], viewWidth);
          y = parsePercent$1(positionExpr[1], viewHeight);
        } else if (isObject(positionExpr)) {
          var boxLayoutPosition = positionExpr;
          boxLayoutPosition.width = contentSize[0];
          boxLayoutPosition.height = contentSize[1];
          var layoutRect = getLayoutRect(boxLayoutPosition, {
            width: viewWidth,
            height: viewHeight
          });
          x = layoutRect.x;
          y = layoutRect.y;
          align = null; // When positionExpr is left/top/right/bottom,
          // align and verticalAlign will not work.

          vAlign = null;
        } // Specify tooltip position by string 'top' 'bottom' 'left' 'right' around graphic element
        else if (isString(positionExpr) && el) {
            var pos = calcTooltipPosition(positionExpr, rect, contentSize, tooltipModel.get('borderWidth'));
            x = pos[0];
            y = pos[1];
          } else {
            var pos = refixTooltipPosition(x, y, content, viewWidth, viewHeight, align ? null : 20, vAlign ? null : 20);
            x = pos[0];
            y = pos[1];
          }

        align && (x -= isCenterAlign(align) ? contentSize[0] / 2 : align === 'right' ? contentSize[0] : 0);
        vAlign && (y -= isCenterAlign(vAlign) ? contentSize[1] / 2 : vAlign === 'bottom' ? contentSize[1] : 0);

        if (shouldTooltipConfine(tooltipModel)) {
          var pos = confineTooltipPosition(x, y, content, viewWidth, viewHeight);
          x = pos[0];
          y = pos[1];
        }

        content.moveTo(x, y);
      }; // FIXME
      // Should we remove this but leave this to user?


      TooltipView.prototype._updateContentNotChangedOnAxis = function (dataByCoordSys, cbParamsList) {
        var lastCoordSys = this._lastDataByCoordSys;
        var lastCbParamsList = this._cbParamsList;
        var contentNotChanged = !!lastCoordSys && lastCoordSys.length === dataByCoordSys.length;
        contentNotChanged && each(lastCoordSys, function (lastItemCoordSys, indexCoordSys) {
          var lastDataByAxis = lastItemCoordSys.dataByAxis || [];
          var thisItemCoordSys = dataByCoordSys[indexCoordSys] || {};
          var thisDataByAxis = thisItemCoordSys.dataByAxis || [];
          contentNotChanged = contentNotChanged && lastDataByAxis.length === thisDataByAxis.length;
          contentNotChanged && each(lastDataByAxis, function (lastItem, indexAxis) {
            var thisItem = thisDataByAxis[indexAxis] || {};
            var lastIndices = lastItem.seriesDataIndices || [];
            var newIndices = thisItem.seriesDataIndices || [];
            contentNotChanged = contentNotChanged && lastItem.value === thisItem.value && lastItem.axisType === thisItem.axisType && lastItem.axisId === thisItem.axisId && lastIndices.length === newIndices.length;
            contentNotChanged && each(lastIndices, function (lastIdxItem, j) {
              var newIdxItem = newIndices[j];
              contentNotChanged = contentNotChanged && lastIdxItem.seriesIndex === newIdxItem.seriesIndex && lastIdxItem.dataIndex === newIdxItem.dataIndex;
            }); // check is cbParams data value changed

            lastCbParamsList && each(lastItem.seriesDataIndices, function (idxItem) {
              var seriesIdx = idxItem.seriesIndex;
              var cbParams = cbParamsList[seriesIdx];
              var lastCbParams = lastCbParamsList[seriesIdx];

              if (cbParams && lastCbParams && lastCbParams.data !== cbParams.data) {
                contentNotChanged = false;
              }
            });
          });
        });
        this._lastDataByCoordSys = dataByCoordSys;
        this._cbParamsList = cbParamsList;
        return !!contentNotChanged;
      };

      TooltipView.prototype._hide = function (dispatchAction) {
        // Do not directly hideLater here, because this behavior may be prevented
        // in dispatchAction when showTip is dispatched.
        // FIXME
        // duplicated hideTip if manuallyHideTip is called from dispatchAction.
        this._lastDataByCoordSys = null;
        dispatchAction({
          type: 'hideTip',
          from: this.uid
        });
      };

      TooltipView.prototype.dispose = function (ecModel, api) {
        if (env.node || !api.getDom()) {
          return;
        }

        clear(this, '_updatePosition');

        this._tooltipContent.dispose();

        unregister('itemTooltip', api);
      };

      TooltipView.type = 'tooltip';
      return TooltipView;
    }(ComponentView);
    /**
     * From top to bottom. (the last one should be globalTooltipModel);
     */


    function buildTooltipModel(modelCascade, globalTooltipModel, defaultTooltipOption) {
      // Last is always tooltip model.
      var ecModel = globalTooltipModel.ecModel;
      var resultModel;

      if (defaultTooltipOption) {
        resultModel = new Model(defaultTooltipOption, ecModel, ecModel);
        resultModel = new Model(globalTooltipModel.option, resultModel, ecModel);
      } else {
        resultModel = globalTooltipModel;
      }

      for (var i = modelCascade.length - 1; i >= 0; i--) {
        var tooltipOpt = modelCascade[i];

        if (tooltipOpt) {
          if (tooltipOpt instanceof Model) {
            tooltipOpt = tooltipOpt.get('tooltip', true);
          } // In each data item tooltip can be simply write:
          // {
          //  value: 10,
          //  tooltip: 'Something you need to know'
          // }


          if (isString(tooltipOpt)) {
            tooltipOpt = {
              formatter: tooltipOpt
            };
          }

          if (tooltipOpt) {
            resultModel = new Model(tooltipOpt, resultModel, ecModel);
          }
        }
      }

      return resultModel;
    }

    function makeDispatchAction$1(payload, api) {
      return payload.dispatchAction || bind(api.dispatchAction, api);
    }

    function refixTooltipPosition(x, y, content, viewWidth, viewHeight, gapH, gapV) {
      var size = content.getSize();
      var width = size[0];
      var height = size[1];

      if (gapH != null) {
        // Add extra 2 pixels for this case:
        // At present the "values" in defaut tooltip are using CSS `float: right`.
        // When the right edge of the tooltip box is on the right side of the
        // viewport, the `float` layout might push the "values" to the second line.
        if (x + width + gapH + 2 > viewWidth) {
          x -= width + gapH;
        } else {
          x += gapH;
        }
      }

      if (gapV != null) {
        if (y + height + gapV > viewHeight) {
          y -= height + gapV;
        } else {
          y += gapV;
        }
      }

      return [x, y];
    }

    function confineTooltipPosition(x, y, content, viewWidth, viewHeight) {
      var size = content.getSize();
      var width = size[0];
      var height = size[1];
      x = Math.min(x + width, viewWidth) - width;
      y = Math.min(y + height, viewHeight) - height;
      x = Math.max(x, 0);
      y = Math.max(y, 0);
      return [x, y];
    }

    function calcTooltipPosition(position, rect, contentSize, borderWidth) {
      var domWidth = contentSize[0];
      var domHeight = contentSize[1];
      var offset = Math.ceil(Math.SQRT2 * borderWidth) + 8;
      var x = 0;
      var y = 0;
      var rectWidth = rect.width;
      var rectHeight = rect.height;

      switch (position) {
        case 'inside':
          x = rect.x + rectWidth / 2 - domWidth / 2;
          y = rect.y + rectHeight / 2 - domHeight / 2;
          break;

        case 'top':
          x = rect.x + rectWidth / 2 - domWidth / 2;
          y = rect.y - domHeight - offset;
          break;

        case 'bottom':
          x = rect.x + rectWidth / 2 - domWidth / 2;
          y = rect.y + rectHeight + offset;
          break;

        case 'left':
          x = rect.x - domWidth - offset;
          y = rect.y + rectHeight / 2 - domHeight / 2;
          break;

        case 'right':
          x = rect.x + rectWidth + offset;
          y = rect.y + rectHeight / 2 - domHeight / 2;
      }

      return [x, y];
    }

    function isCenterAlign(align) {
      return align === 'center' || align === 'middle';
    }
    /**
     * Find target component by payload like:
     * ```js
     * { legendId: 'some_id', name: 'xxx' }
     * { toolboxIndex: 1, name: 'xxx' }
     * { geoName: 'some_name', name: 'xxx' }
     * ```
     * PENDING: at present only
     *
     * If not found, return null/undefined.
     */


    function findComponentReference(payload, ecModel, api) {
      var queryOptionMap = preParseFinder(payload).queryOptionMap;
      var componentMainType = queryOptionMap.keys()[0];

      if (!componentMainType || componentMainType === 'series') {
        return;
      }

      var queryResult = queryReferringComponents(ecModel, componentMainType, queryOptionMap.get(componentMainType), {
        useDefault: false,
        enableAll: false,
        enableNone: false
      });
      var model = queryResult.models[0];

      if (!model) {
        return;
      }

      var view = api.getViewOfComponentModel(model);
      var el;
      view.group.traverse(function (subEl) {
        var tooltipConfig = getECData(subEl).tooltipConfig;

        if (tooltipConfig && tooltipConfig.name === payload.name) {
          el = subEl;
          return true; // stop
        }
      });

      if (el) {
        return {
          componentMainType: componentMainType,
          componentIndex: model.componentIndex,
          el: el
        };
      }
    }

    function install$c(registers) {
      use(install$7);
      registers.registerComponentModel(TooltipModel);
      registers.registerComponentView(TooltipView);
      /**
       * @action
       * @property {string} type
       * @property {number} seriesIndex
       * @property {number} dataIndex
       * @property {number} [x]
       * @property {number} [y]
       */

      registers.registerAction({
        type: 'showTip',
        event: 'showTip',
        update: 'tooltip:manuallyShowTip'
      }, noop);
      registers.registerAction({
        type: 'hideTip',
        event: 'hideTip',
        update: 'tooltip:manuallyHideTip'
      }, noop);
    }

    var TitleModel =
    /** @class */
    function (_super) {
      __extends(TitleModel, _super);

      function TitleModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TitleModel.type;
        _this.layoutMode = {
          type: 'box',
          ignoreSize: true
        };
        return _this;
      }

      TitleModel.type = 'title';
      TitleModel.defaultOption = {
        // zlevel: 0,
        z: 6,
        show: true,
        text: '',
        target: 'blank',
        subtext: '',
        subtarget: 'blank',
        left: 0,
        top: 0,
        backgroundColor: 'rgba(0,0,0,0)',
        borderColor: '#ccc',
        borderWidth: 0,
        padding: 5,
        itemGap: 10,
        textStyle: {
          fontSize: 18,
          fontWeight: 'bold',
          color: '#464646'
        },
        subtextStyle: {
          fontSize: 12,
          color: '#6E7079'
        }
      };
      return TitleModel;
    }(ComponentModel); // View


    var TitleView =
    /** @class */
    function (_super) {
      __extends(TitleView, _super);

      function TitleView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TitleView.type;
        return _this;
      }

      TitleView.prototype.render = function (titleModel, ecModel, api) {
        this.group.removeAll();

        if (!titleModel.get('show')) {
          return;
        }

        var group = this.group;
        var textStyleModel = titleModel.getModel('textStyle');
        var subtextStyleModel = titleModel.getModel('subtextStyle');
        var textAlign = titleModel.get('textAlign');
        var textVerticalAlign = retrieve2(titleModel.get('textBaseline'), titleModel.get('textVerticalAlign'));
        var textEl = new ZRText({
          style: createTextStyle(textStyleModel, {
            text: titleModel.get('text'),
            fill: textStyleModel.getTextColor()
          }, {
            disableBox: true
          }),
          z2: 10
        });
        var textRect = textEl.getBoundingRect();
        var subText = titleModel.get('subtext');
        var subTextEl = new ZRText({
          style: createTextStyle(subtextStyleModel, {
            text: subText,
            fill: subtextStyleModel.getTextColor(),
            y: textRect.height + titleModel.get('itemGap'),
            verticalAlign: 'top'
          }, {
            disableBox: true
          }),
          z2: 10
        });
        var link = titleModel.get('link');
        var sublink = titleModel.get('sublink');
        var triggerEvent = titleModel.get('triggerEvent', true);
        textEl.silent = !link && !triggerEvent;
        subTextEl.silent = !sublink && !triggerEvent;

        if (link) {
          textEl.on('click', function () {
            windowOpen(link, '_' + titleModel.get('target'));
          });
        }

        if (sublink) {
          subTextEl.on('click', function () {
            windowOpen(sublink, '_' + titleModel.get('subtarget'));
          });
        }

        getECData(textEl).eventData = getECData(subTextEl).eventData = triggerEvent ? {
          componentType: 'title',
          componentIndex: titleModel.componentIndex
        } : null;
        group.add(textEl);
        subText && group.add(subTextEl); // If no subText, but add subTextEl, there will be an empty line.

        var groupRect = group.getBoundingRect();
        var layoutOption = titleModel.getBoxLayoutParams();
        layoutOption.width = groupRect.width;
        layoutOption.height = groupRect.height;
        var layoutRect = getLayoutRect(layoutOption, {
          width: api.getWidth(),
          height: api.getHeight()
        }, titleModel.get('padding')); // Adjust text align based on position

        if (!textAlign) {
          // Align left if title is on the left. center and right is same
          textAlign = titleModel.get('left') || titleModel.get('right'); // @ts-ignore

          if (textAlign === 'middle') {
            textAlign = 'center';
          } // Adjust layout by text align


          if (textAlign === 'right') {
            layoutRect.x += layoutRect.width;
          } else if (textAlign === 'center') {
            layoutRect.x += layoutRect.width / 2;
          }
        }

        if (!textVerticalAlign) {
          textVerticalAlign = titleModel.get('top') || titleModel.get('bottom'); // @ts-ignore

          if (textVerticalAlign === 'center') {
            textVerticalAlign = 'middle';
          }

          if (textVerticalAlign === 'bottom') {
            layoutRect.y += layoutRect.height;
          } else if (textVerticalAlign === 'middle') {
            layoutRect.y += layoutRect.height / 2;
          }

          textVerticalAlign = textVerticalAlign || 'top';
        }

        group.x = layoutRect.x;
        group.y = layoutRect.y;
        group.markRedraw();
        var alignStyle = {
          align: textAlign,
          verticalAlign: textVerticalAlign
        };
        textEl.setStyle(alignStyle);
        subTextEl.setStyle(alignStyle); // Render background
        // Get groupRect again because textAlign has been changed

        groupRect = group.getBoundingRect();
        var padding = layoutRect.margin;
        var style = titleModel.getItemStyle(['color', 'opacity']);
        style.fill = titleModel.get('backgroundColor');
        var rect = new Rect({
          shape: {
            x: groupRect.x - padding[3],
            y: groupRect.y - padding[0],
            width: groupRect.width + padding[1] + padding[3],
            height: groupRect.height + padding[0] + padding[2],
            r: titleModel.get('borderRadius')
          },
          style: style,
          subPixelOptimize: true,
          silent: true
        });
        group.add(rect);
      };

      TitleView.type = 'title';
      return TitleView;
    }(ComponentView);

    function install$d(registers) {
      registers.registerComponentModel(TitleModel);
      registers.registerComponentView(TitleView);
    }

    function checkMarkerInSeries(seriesOpts, markerType) {
      if (!seriesOpts) {
        return false;
      }

      var seriesOptArr = isArray(seriesOpts) ? seriesOpts : [seriesOpts];

      for (var idx = 0; idx < seriesOptArr.length; idx++) {
        if (seriesOptArr[idx] && seriesOptArr[idx][markerType]) {
          return true;
        }
      }

      return false;
    }

    function fillLabel(opt) {
      defaultEmphasis(opt, 'label', ['show']);
    } // { [componentType]: MarkerModel }


    var inner$c = makeInner();

    var MarkerModel =
    /** @class */
    function (_super) {
      __extends(MarkerModel, _super);

      function MarkerModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkerModel.type;
        /**
         * If marker model is created by self from series
         */

        _this.createdBySelf = false;
        return _this;
      }
      /**
       * @overrite
       */


      MarkerModel.prototype.init = function (option, parentModel, ecModel) {
        if ("development" !== 'production') {
          if (this.type === 'marker') {
            throw new Error('Marker component is abstract component. Use markLine, markPoint, markArea instead.');
          }
        }

        this.mergeDefaultAndTheme(option, ecModel);

        this._mergeOption(option, ecModel, false, true);
      };

      MarkerModel.prototype.isAnimationEnabled = function () {
        if (env.node) {
          return false;
        }

        var hostSeries = this.__hostSeries;
        return this.getShallow('animation') && hostSeries && hostSeries.isAnimationEnabled();
      };
      /**
       * @overrite
       */


      MarkerModel.prototype.mergeOption = function (newOpt, ecModel) {
        this._mergeOption(newOpt, ecModel, false, false);
      };

      MarkerModel.prototype._mergeOption = function (newOpt, ecModel, createdBySelf, isInit) {
        var componentType = this.mainType;

        if (!createdBySelf) {
          ecModel.eachSeries(function (seriesModel) {
            // mainType can be markPoint, markLine, markArea
            var markerOpt = seriesModel.get(this.mainType, true);
            var markerModel = inner$c(seriesModel)[componentType];

            if (!markerOpt || !markerOpt.data) {
              inner$c(seriesModel)[componentType] = null;
              return;
            }

            if (!markerModel) {
              if (isInit) {
                // Default label emphasis `position` and `show`
                fillLabel(markerOpt);
              }

              each(markerOpt.data, function (item) {
                // FIXME Overwrite fillLabel method ?
                if (item instanceof Array) {
                  fillLabel(item[0]);
                  fillLabel(item[1]);
                } else {
                  fillLabel(item);
                }
              });
              markerModel = this.createMarkerModelFromSeries(markerOpt, this, ecModel); // markerModel = new ImplementedMarkerModel(
              //     markerOpt, this, ecModel
              // );

              extend(markerModel, {
                mainType: this.mainType,
                // Use the same series index and name
                seriesIndex: seriesModel.seriesIndex,
                name: seriesModel.name,
                createdBySelf: true
              });
              markerModel.__hostSeries = seriesModel;
            } else {
              markerModel._mergeOption(markerOpt, ecModel, true);
            }

            inner$c(seriesModel)[componentType] = markerModel;
          }, this);
        }
      };

      MarkerModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        var data = this.getData();
        var value = this.getRawValue(dataIndex);
        var itemName = data.getName(dataIndex);
        return createTooltipMarkup('section', {
          header: this.name,
          blocks: [createTooltipMarkup('nameValue', {
            name: itemName,
            value: value,
            noName: !itemName,
            noValue: value == null
          })]
        });
      };

      MarkerModel.prototype.getData = function () {
        return this._data;
      };

      MarkerModel.prototype.setData = function (data) {
        this._data = data;
      };

      MarkerModel.getMarkerModelFromSeries = function (seriesModel, // Support three types of markers. Strict check.
      componentType) {
        return inner$c(seriesModel)[componentType];
      };

      MarkerModel.type = 'marker';
      MarkerModel.dependencies = ['series', 'grid', 'polar', 'geo'];
      return MarkerModel;
    }(ComponentModel);

    mixin(MarkerModel, DataFormatMixin.prototype);

    var MarkPointModel =
    /** @class */
    function (_super) {
      __extends(MarkPointModel, _super);

      function MarkPointModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkPointModel.type;
        return _this;
      }

      MarkPointModel.prototype.createMarkerModelFromSeries = function (markerOpt, masterMarkerModel, ecModel) {
        return new MarkPointModel(markerOpt, masterMarkerModel, ecModel);
      };

      MarkPointModel.type = 'markPoint';
      MarkPointModel.defaultOption = {
        // zlevel: 0,
        z: 5,
        symbol: 'pin',
        symbolSize: 50,
        // symbolRotate: 0,
        // symbolOffset: [0, 0]
        tooltip: {
          trigger: 'item'
        },
        label: {
          show: true,
          position: 'inside'
        },
        itemStyle: {
          borderWidth: 2
        },
        emphasis: {
          label: {
            show: true
          }
        }
      };
      return MarkPointModel;
    }(MarkerModel);

    function hasXOrY(item) {
      return !(isNaN(parseFloat(item.x)) && isNaN(parseFloat(item.y)));
    }

    function hasXAndY(item) {
      return !isNaN(parseFloat(item.x)) && !isNaN(parseFloat(item.y));
    }

    function markerTypeCalculatorWithExtent(markerType, data, otherDataDim, targetDataDim, otherCoordIndex, targetCoordIndex) {
      var coordArr = [];
      var stacked = isDimensionStacked(data, targetDataDim
      /* , otherDataDim */
      );
      var calcDataDim = stacked ? data.getCalculationInfo('stackResultDimension') : targetDataDim;
      var value = numCalculate(data, calcDataDim, markerType);
      var dataIndex = data.indicesOfNearest(calcDataDim, value)[0];
      coordArr[otherCoordIndex] = data.get(otherDataDim, dataIndex);
      coordArr[targetCoordIndex] = data.get(calcDataDim, dataIndex);
      var coordArrValue = data.get(targetDataDim, dataIndex); // Make it simple, do not visit all stacked value to count precision.

      var precision = getPrecision(data.get(targetDataDim, dataIndex));
      precision = Math.min(precision, 20);

      if (precision >= 0) {
        coordArr[targetCoordIndex] = +coordArr[targetCoordIndex].toFixed(precision);
      }

      return [coordArr, coordArrValue];
    } // TODO Specified percent


    var markerTypeCalculator = {
      min: curry(markerTypeCalculatorWithExtent, 'min'),
      max: curry(markerTypeCalculatorWithExtent, 'max'),
      average: curry(markerTypeCalculatorWithExtent, 'average'),
      median: curry(markerTypeCalculatorWithExtent, 'median')
    };
    /**
     * Transform markPoint data item to format used in List by do the following
     * 1. Calculate statistic like `max`, `min`, `average`
     * 2. Convert `item.xAxis`, `item.yAxis` to `item.coord` array
     */

    function dataTransform(seriesModel, item) {
      if (!item) {
        return;
      }

      var data = seriesModel.getData();
      var coordSys = seriesModel.coordinateSystem;
      var dims = coordSys.dimensions; // 1. If not specify the position with pixel directly
      // 2. If `coord` is not a data array. Which uses `xAxis`,
      // `yAxis` to specify the coord on each dimension
      // parseFloat first because item.x and item.y can be percent string like '20%'

      if (!hasXAndY(item) && !isArray(item.coord) && coordSys) {
        var axisInfo = getAxisInfo$1(item, data, coordSys, seriesModel); // Clone the option
        // Transform the properties xAxis, yAxis, radiusAxis, angleAxis, geoCoord to value

        item = clone(item);

        if (item.type && markerTypeCalculator[item.type] && axisInfo.baseAxis && axisInfo.valueAxis) {
          var otherCoordIndex = indexOf(dims, axisInfo.baseAxis.dim);
          var targetCoordIndex = indexOf(dims, axisInfo.valueAxis.dim);
          var coordInfo = markerTypeCalculator[item.type](data, axisInfo.baseDataDim, axisInfo.valueDataDim, otherCoordIndex, targetCoordIndex);
          item.coord = coordInfo[0]; // Force to use the value of calculated value.
          // let item use the value without stack.

          item.value = coordInfo[1];
        } else {
          // FIXME Only has one of xAxis and yAxis.
          item.coord = [item.xAxis != null ? item.xAxis : item.radiusAxis, item.yAxis != null ? item.yAxis : item.angleAxis];
        }
      } // x y is provided


      if (item.coord == null) {
        item.coord = [];
      } else {
        // Each coord support max, min, average
        var coord = item.coord;

        for (var i = 0; i < 2; i++) {
          if (markerTypeCalculator[coord[i]]) {
            coord[i] = numCalculate(data, data.mapDimension(dims[i]), coord[i]);
          }
        }
      }

      return item;
    }
    function getAxisInfo$1(item, data, coordSys, seriesModel) {
      var ret = {};

      if (item.valueIndex != null || item.valueDim != null) {
        ret.valueDataDim = item.valueIndex != null ? data.getDimension(item.valueIndex) : item.valueDim;
        ret.valueAxis = coordSys.getAxis(dataDimToCoordDim(seriesModel, ret.valueDataDim));
        ret.baseAxis = coordSys.getOtherAxis(ret.valueAxis);
        ret.baseDataDim = data.mapDimension(ret.baseAxis.dim);
      } else {
        ret.baseAxis = seriesModel.getBaseAxis();
        ret.valueAxis = coordSys.getOtherAxis(ret.baseAxis);
        ret.baseDataDim = data.mapDimension(ret.baseAxis.dim);
        ret.valueDataDim = data.mapDimension(ret.valueAxis.dim);
      }

      return ret;
    }

    function dataDimToCoordDim(seriesModel, dataDim) {
      var dimItem = seriesModel.getData().getDimensionInfo(dataDim);
      return dimItem && dimItem.coordDim;
    }
    /**
     * Filter data which is out of coordinateSystem range
     * [dataFilter description]
     */


    function dataFilter$1( // Currently only polar and cartesian has containData.
    coordSys, item) {
      // Always return true if there is no coordSys
      return coordSys && coordSys.containData && item.coord && !hasXOrY(item) ? coordSys.containData(item.coord) : true;
    }
    function zoneFilter( // Currently only polar and cartesian has containData.
    coordSys, item1, item2) {
      // Always return true if there is no coordSys
      return coordSys && coordSys.containZone && item1.coord && item2.coord && !hasXOrY(item1) && !hasXOrY(item2) ? coordSys.containZone(item1.coord, item2.coord) : true;
    }
    function createMarkerDimValueGetter(inCoordSys, dims) {
      return inCoordSys ? function (item, dimName, dataIndex, dimIndex) {
        var rawVal = dimIndex < 2 // x, y, radius, angle
        ? item.coord && item.coord[dimIndex] : item.value;
        return parseDataValue(rawVal, dims[dimIndex]);
      } : function (item, dimName, dataIndex, dimIndex) {
        return parseDataValue(item.value, dims[dimIndex]);
      };
    }
    function numCalculate(data, valueDataDim, type) {
      if (type === 'average') {
        var sum_1 = 0;
        var count_1 = 0;
        data.each(valueDataDim, function (val, idx) {
          if (!isNaN(val)) {
            sum_1 += val;
            count_1++;
          }
        });
        return sum_1 / count_1;
      } else if (type === 'median') {
        return data.getMedian(valueDataDim);
      } else {
        // max & min
        return data.getDataExtent(valueDataDim)[type === 'max' ? 1 : 0];
      }
    }

    var inner$d = makeInner();

    var MarkerView =
    /** @class */
    function (_super) {
      __extends(MarkerView, _super);

      function MarkerView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkerView.type;
        return _this;
      }

      MarkerView.prototype.init = function () {
        this.markerGroupMap = createHashMap();
      };

      MarkerView.prototype.render = function (markerModel, ecModel, api) {
        var _this = this;

        var markerGroupMap = this.markerGroupMap;
        markerGroupMap.each(function (item) {
          inner$d(item).keep = false;
        });
        ecModel.eachSeries(function (seriesModel) {
          var markerModel = MarkerModel.getMarkerModelFromSeries(seriesModel, _this.type);
          markerModel && _this.renderSeries(seriesModel, markerModel, ecModel, api);
        });
        markerGroupMap.each(function (item) {
          !inner$d(item).keep && _this.group.remove(item.group);
        });
      };

      MarkerView.prototype.markKeep = function (drawGroup) {
        inner$d(drawGroup).keep = true;
      };

      MarkerView.prototype.toggleBlurSeries = function (seriesModelList, isBlur) {
        var _this = this;

        each(seriesModelList, function (seriesModel) {
          var markerModel = MarkerModel.getMarkerModelFromSeries(seriesModel, _this.type);

          if (markerModel) {
            var data = markerModel.getData();
            data.eachItemGraphicEl(function (el) {
              if (el) {
                isBlur ? enterBlur(el) : leaveBlur(el);
              }
            });
          }
        });
      };

      MarkerView.type = 'marker';
      return MarkerView;
    }(ComponentView);

    function updateMarkerLayout(mpData, seriesModel, api) {
      var coordSys = seriesModel.coordinateSystem;
      mpData.each(function (idx) {
        var itemModel = mpData.getItemModel(idx);
        var point;
        var xPx = parsePercent$1(itemModel.get('x'), api.getWidth());
        var yPx = parsePercent$1(itemModel.get('y'), api.getHeight());

        if (!isNaN(xPx) && !isNaN(yPx)) {
          point = [xPx, yPx];
        } // Chart like bar may have there own marker positioning logic
        else if (seriesModel.getMarkerPosition) {
            // Use the getMarkerPosition
            point = seriesModel.getMarkerPosition(mpData.getValues(mpData.dimensions, idx));
          } else if (coordSys) {
            var x = mpData.get(coordSys.dimensions[0], idx);
            var y = mpData.get(coordSys.dimensions[1], idx);
            point = coordSys.dataToPoint([x, y]);
          } // Use x, y if has any


        if (!isNaN(xPx)) {
          point[0] = xPx;
        }

        if (!isNaN(yPx)) {
          point[1] = yPx;
        }

        mpData.setItemLayout(idx, point);
      });
    }

    var MarkPointView =
    /** @class */
    function (_super) {
      __extends(MarkPointView, _super);

      function MarkPointView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkPointView.type;
        return _this;
      }

      MarkPointView.prototype.updateTransform = function (markPointModel, ecModel, api) {
        ecModel.eachSeries(function (seriesModel) {
          var mpModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markPoint');

          if (mpModel) {
            updateMarkerLayout(mpModel.getData(), seriesModel, api);
            this.markerGroupMap.get(seriesModel.id).updateLayout();
          }
        }, this);
      };

      MarkPointView.prototype.renderSeries = function (seriesModel, mpModel, ecModel, api) {
        var coordSys = seriesModel.coordinateSystem;
        var seriesId = seriesModel.id;
        var seriesData = seriesModel.getData();
        var symbolDrawMap = this.markerGroupMap;
        var symbolDraw = symbolDrawMap.get(seriesId) || symbolDrawMap.set(seriesId, new SymbolDraw());
        var mpData = createData(coordSys, seriesModel, mpModel); // FIXME

        mpModel.setData(mpData);
        updateMarkerLayout(mpModel.getData(), seriesModel, api);
        mpData.each(function (idx) {
          var itemModel = mpData.getItemModel(idx);
          var symbol = itemModel.getShallow('symbol');
          var symbolSize = itemModel.getShallow('symbolSize');
          var symbolRotate = itemModel.getShallow('symbolRotate');
          var symbolOffset = itemModel.getShallow('symbolOffset');
          var symbolKeepAspect = itemModel.getShallow('symbolKeepAspect'); // TODO: refactor needed: single data item should not support callback function

          if (isFunction(symbol) || isFunction(symbolSize) || isFunction(symbolRotate) || isFunction(symbolOffset)) {
            var rawIdx = mpModel.getRawValue(idx);
            var dataParams = mpModel.getDataParams(idx);

            if (isFunction(symbol)) {
              symbol = symbol(rawIdx, dataParams);
            }

            if (isFunction(symbolSize)) {
              // FIXME 这里不兼容 ECharts 2.x，2.x 貌似参数是整个数据？
              symbolSize = symbolSize(rawIdx, dataParams);
            }

            if (isFunction(symbolRotate)) {
              symbolRotate = symbolRotate(rawIdx, dataParams);
            }

            if (isFunction(symbolOffset)) {
              symbolOffset = symbolOffset(rawIdx, dataParams);
            }
          }

          var style = itemModel.getModel('itemStyle').getItemStyle();
          var color = getVisualFromData(seriesData, 'color');

          if (!style.fill) {
            style.fill = color;
          }

          mpData.setItemVisual(idx, {
            symbol: symbol,
            symbolSize: symbolSize,
            symbolRotate: symbolRotate,
            symbolOffset: symbolOffset,
            symbolKeepAspect: symbolKeepAspect,
            style: style
          });
        }); // TODO Text are wrong

        symbolDraw.updateData(mpData);
        this.group.add(symbolDraw.group); // Set host model for tooltip
        // FIXME

        mpData.eachItemGraphicEl(function (el) {
          el.traverse(function (child) {
            getECData(child).dataModel = mpModel;
          });
        });
        this.markKeep(symbolDraw);
        symbolDraw.group.silent = mpModel.get('silent') || seriesModel.get('silent');
      };

      MarkPointView.type = 'markPoint';
      return MarkPointView;
    }(MarkerView);

    function createData(coordSys, seriesModel, mpModel) {
      var coordDimsInfos;

      if (coordSys) {
        coordDimsInfos = map(coordSys && coordSys.dimensions, function (coordDim) {
          var info = seriesModel.getData().getDimensionInfo(seriesModel.getData().mapDimension(coordDim)) || {}; // In map series data don't have lng and lat dimension. Fallback to same with coordSys

          return extend(extend({}, info), {
            name: coordDim,
            // DON'T use ordinalMeta to parse and collect ordinal.
            ordinalMeta: null
          });
        });
      } else {
        coordDimsInfos = [{
          name: 'value',
          type: 'float'
        }];
      }

      var mpData = new SeriesData(coordDimsInfos, mpModel);
      var dataOpt = map(mpModel.get('data'), curry(dataTransform, seriesModel));

      if (coordSys) {
        dataOpt = filter(dataOpt, curry(dataFilter$1, coordSys));
      }

      var dimValueGetter = createMarkerDimValueGetter(!!coordSys, coordDimsInfos);
      mpData.initData(dataOpt, null, dimValueGetter);
      return mpData;
    }

    function install$e(registers) {
      registers.registerComponentModel(MarkPointModel);
      registers.registerComponentView(MarkPointView);
      registers.registerPreprocessor(function (opt) {
        if (checkMarkerInSeries(opt.series, 'markPoint')) {
          // Make sure markPoint component is enabled
          opt.markPoint = opt.markPoint || {};
        }
      });
    }

    var MarkLineModel =
    /** @class */
    function (_super) {
      __extends(MarkLineModel, _super);

      function MarkLineModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkLineModel.type;
        return _this;
      }

      MarkLineModel.prototype.createMarkerModelFromSeries = function (markerOpt, masterMarkerModel, ecModel) {
        return new MarkLineModel(markerOpt, masterMarkerModel, ecModel);
      };

      MarkLineModel.type = 'markLine';
      MarkLineModel.defaultOption = {
        // zlevel: 0,
        z: 5,
        symbol: ['circle', 'arrow'],
        symbolSize: [8, 16],
        // symbolRotate: 0,
        symbolOffset: 0,
        precision: 2,
        tooltip: {
          trigger: 'item'
        },
        label: {
          show: true,
          position: 'end',
          distance: 5
        },
        lineStyle: {
          type: 'dashed'
        },
        emphasis: {
          label: {
            show: true
          },
          lineStyle: {
            width: 3
          }
        },
        animationEasing: 'linear'
      };
      return MarkLineModel;
    }(MarkerModel);

    var straightLineProto = Line.prototype;
    var bezierCurveProto = BezierCurve.prototype;

    var StraightLineShape =
    /** @class */
    function () {
      function StraightLineShape() {
        // Start point
        this.x1 = 0;
        this.y1 = 0; // End point

        this.x2 = 0;
        this.y2 = 0;
        this.percent = 1;
      }

      return StraightLineShape;
    }();

    var CurveShape =
    /** @class */
    function (_super) {
      __extends(CurveShape, _super);

      function CurveShape() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      return CurveShape;
    }(StraightLineShape);

    function isStraightLine(shape) {
      return isNaN(+shape.cpx1) || isNaN(+shape.cpy1);
    }

    var ECLinePath =
    /** @class */
    function (_super) {
      __extends(ECLinePath, _super);

      function ECLinePath(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'ec-line';
        return _this;
      }

      ECLinePath.prototype.getDefaultStyle = function () {
        return {
          stroke: '#000',
          fill: null
        };
      };

      ECLinePath.prototype.getDefaultShape = function () {
        return new StraightLineShape();
      };

      ECLinePath.prototype.buildPath = function (ctx, shape) {
        if (isStraightLine(shape)) {
          straightLineProto.buildPath.call(this, ctx, shape);
        } else {
          bezierCurveProto.buildPath.call(this, ctx, shape);
        }
      };

      ECLinePath.prototype.pointAt = function (t) {
        if (isStraightLine(this.shape)) {
          return straightLineProto.pointAt.call(this, t);
        } else {
          return bezierCurveProto.pointAt.call(this, t);
        }
      };

      ECLinePath.prototype.tangentAt = function (t) {
        var shape = this.shape;
        var p = isStraightLine(shape) ? [shape.x2 - shape.x1, shape.y2 - shape.y1] : bezierCurveProto.tangentAt.call(this, t);
        return normalize(p, p);
      };

      return ECLinePath;
    }(Path);

    var SYMBOL_CATEGORIES = ['fromSymbol', 'toSymbol'];

    function makeSymbolTypeKey(symbolCategory) {
      return '_' + symbolCategory + 'Type';
    }
    /**
     * @inner
     */


    function createSymbol$1(name, lineData, idx) {
      var symbolType = lineData.getItemVisual(idx, name);

      if (!symbolType || symbolType === 'none') {
        return;
      }

      var symbolSize = lineData.getItemVisual(idx, name + 'Size');
      var symbolRotate = lineData.getItemVisual(idx, name + 'Rotate');
      var symbolOffset = lineData.getItemVisual(idx, name + 'Offset');
      var symbolKeepAspect = lineData.getItemVisual(idx, name + 'KeepAspect');
      var symbolSizeArr = normalizeSymbolSize(symbolSize);
      var symbolOffsetArr = normalizeSymbolOffset(symbolOffset || 0, symbolSizeArr);
      var symbolPath = createSymbol(symbolType, -symbolSizeArr[0] / 2 + symbolOffsetArr[0], -symbolSizeArr[1] / 2 + symbolOffsetArr[1], symbolSizeArr[0], symbolSizeArr[1], null, symbolKeepAspect);
      symbolPath.__specifiedRotation = symbolRotate == null || isNaN(symbolRotate) ? void 0 : +symbolRotate * Math.PI / 180 || 0;
      symbolPath.name = name;
      return symbolPath;
    }

    function createLine(points) {
      var line = new ECLinePath({
        name: 'line',
        subPixelOptimize: true
      });
      setLinePoints(line.shape, points);
      return line;
    }

    function setLinePoints(targetShape, points) {
      targetShape.x1 = points[0][0];
      targetShape.y1 = points[0][1];
      targetShape.x2 = points[1][0];
      targetShape.y2 = points[1][1];
      targetShape.percent = 1;
      var cp1 = points[2];

      if (cp1) {
        targetShape.cpx1 = cp1[0];
        targetShape.cpy1 = cp1[1];
      } else {
        targetShape.cpx1 = NaN;
        targetShape.cpy1 = NaN;
      }
    }

    var Line$1 =
    /** @class */
    function (_super) {
      __extends(Line, _super);

      function Line(lineData, idx, seriesScope) {
        var _this = _super.call(this) || this;

        _this._createLine(lineData, idx, seriesScope);

        return _this;
      }

      Line.prototype._createLine = function (lineData, idx, seriesScope) {
        var seriesModel = lineData.hostModel;
        var linePoints = lineData.getItemLayout(idx);
        var line = createLine(linePoints);
        line.shape.percent = 0;
        initProps(line, {
          shape: {
            percent: 1
          }
        }, seriesModel, idx);
        this.add(line);
        each(SYMBOL_CATEGORIES, function (symbolCategory) {
          var symbol = createSymbol$1(symbolCategory, lineData, idx); // symbols must added after line to make sure
          // it will be updated after line#update.
          // Or symbol position and rotation update in line#beforeUpdate will be one frame slow

          this.add(symbol);
          this[makeSymbolTypeKey(symbolCategory)] = lineData.getItemVisual(idx, symbolCategory);
        }, this);

        this._updateCommonStl(lineData, idx, seriesScope);
      }; // TODO More strict on the List type in parameters?


      Line.prototype.updateData = function (lineData, idx, seriesScope) {
        var seriesModel = lineData.hostModel;
        var line = this.childOfName('line');
        var linePoints = lineData.getItemLayout(idx);
        var target = {
          shape: {}
        };
        setLinePoints(target.shape, linePoints);
        updateProps(line, target, seriesModel, idx);
        each(SYMBOL_CATEGORIES, function (symbolCategory) {
          var symbolType = lineData.getItemVisual(idx, symbolCategory);
          var key = makeSymbolTypeKey(symbolCategory); // Symbol changed

          if (this[key] !== symbolType) {
            this.remove(this.childOfName(symbolCategory));
            var symbol = createSymbol$1(symbolCategory, lineData, idx);
            this.add(symbol);
          }

          this[key] = symbolType;
        }, this);

        this._updateCommonStl(lineData, idx, seriesScope);
      };

      Line.prototype.getLinePath = function () {
        return this.childAt(0);
      };

      Line.prototype._updateCommonStl = function (lineData, idx, seriesScope) {
        var seriesModel = lineData.hostModel;
        var line = this.childOfName('line');
        var emphasisLineStyle = seriesScope && seriesScope.emphasisLineStyle;
        var blurLineStyle = seriesScope && seriesScope.blurLineStyle;
        var selectLineStyle = seriesScope && seriesScope.selectLineStyle;
        var labelStatesModels = seriesScope && seriesScope.labelStatesModels;
        var emphasisDisabled = seriesScope && seriesScope.emphasisDisabled;
        var focus = seriesScope && seriesScope.focus;
        var blurScope = seriesScope && seriesScope.blurScope; // Optimization for large dataset

        if (!seriesScope || lineData.hasItemOption) {
          var itemModel = lineData.getItemModel(idx);
          var emphasisModel = itemModel.getModel('emphasis');
          emphasisLineStyle = emphasisModel.getModel('lineStyle').getLineStyle();
          blurLineStyle = itemModel.getModel(['blur', 'lineStyle']).getLineStyle();
          selectLineStyle = itemModel.getModel(['select', 'lineStyle']).getLineStyle();
          emphasisDisabled = emphasisModel.get('disabled');
          focus = emphasisModel.get('focus');
          blurScope = emphasisModel.get('blurScope');
          labelStatesModels = getLabelStatesModels(itemModel);
        }

        var lineStyle = lineData.getItemVisual(idx, 'style');
        var visualColor = lineStyle.stroke;
        line.useStyle(lineStyle);
        line.style.fill = null;
        line.style.strokeNoScale = true;
        line.ensureState('emphasis').style = emphasisLineStyle;
        line.ensureState('blur').style = blurLineStyle;
        line.ensureState('select').style = selectLineStyle; // Update symbol

        each(SYMBOL_CATEGORIES, function (symbolCategory) {
          var symbol = this.childOfName(symbolCategory);

          if (symbol) {
            // Share opacity and color with line.
            symbol.setColor(visualColor);
            symbol.style.opacity = lineStyle.opacity;

            for (var i = 0; i < SPECIAL_STATES.length; i++) {
              var stateName = SPECIAL_STATES[i];
              var lineState = line.getState(stateName);

              if (lineState) {
                var lineStateStyle = lineState.style || {};
                var state = symbol.ensureState(stateName);
                var stateStyle = state.style || (state.style = {});

                if (lineStateStyle.stroke != null) {
                  stateStyle[symbol.__isEmptyBrush ? 'stroke' : 'fill'] = lineStateStyle.stroke;
                }

                if (lineStateStyle.opacity != null) {
                  stateStyle.opacity = lineStateStyle.opacity;
                }
              }
            }

            symbol.markRedraw();
          }
        }, this);
        var rawVal = seriesModel.getRawValue(idx);
        setLabelStyle(this, labelStatesModels, {
          labelDataIndex: idx,
          labelFetcher: {
            getFormattedLabel: function (dataIndex, stateName) {
              return seriesModel.getFormattedLabel(dataIndex, stateName, lineData.dataType);
            }
          },
          inheritColor: visualColor || '#000',
          defaultOpacity: lineStyle.opacity,
          defaultText: (rawVal == null ? lineData.getName(idx) : isFinite(rawVal) ? round(rawVal) : rawVal) + ''
        });
        var label = this.getTextContent(); // Always set `textStyle` even if `normalStyle.text` is null, because default
        // values have to be set on `normalStyle`.

        if (label) {
          var labelNormalModel = labelStatesModels.normal;
          label.__align = label.style.align;
          label.__verticalAlign = label.style.verticalAlign; // 'start', 'middle', 'end'

          label.__position = labelNormalModel.get('position') || 'middle';
          var distance = labelNormalModel.get('distance');

          if (!isArray(distance)) {
            distance = [distance, distance];
          }

          label.__labelDistance = distance;
        }

        this.setTextConfig({
          position: null,
          local: true,
          inside: false // Can't be inside for stroke element.

        });
        toggleHoverEmphasis(this, focus, blurScope, emphasisDisabled);
      };

      Line.prototype.highlight = function () {
        enterEmphasis(this);
      };

      Line.prototype.downplay = function () {
        leaveEmphasis(this);
      };

      Line.prototype.updateLayout = function (lineData, idx) {
        this.setLinePoints(lineData.getItemLayout(idx));
      };

      Line.prototype.setLinePoints = function (points) {
        var linePath = this.childOfName('line');
        setLinePoints(linePath.shape, points);
        linePath.dirty();
      };

      Line.prototype.beforeUpdate = function () {
        var lineGroup = this;
        var symbolFrom = lineGroup.childOfName('fromSymbol');
        var symbolTo = lineGroup.childOfName('toSymbol');
        var label = lineGroup.getTextContent(); // Quick reject

        if (!symbolFrom && !symbolTo && (!label || label.ignore)) {
          return;
        }

        var invScale = 1;
        var parentNode = this.parent;

        while (parentNode) {
          if (parentNode.scaleX) {
            invScale /= parentNode.scaleX;
          }

          parentNode = parentNode.parent;
        }

        var line = lineGroup.childOfName('line'); // If line not changed
        // FIXME Parent scale changed

        if (!this.__dirty && !line.__dirty) {
          return;
        }

        var percent = line.shape.percent;
        var fromPos = line.pointAt(0);
        var toPos = line.pointAt(percent);
        var d = sub([], toPos, fromPos);
        normalize(d, d);

        function setSymbolRotation(symbol, percent) {
          // Fix #12388
          // when symbol is set to be 'arrow' in markLine,
          // symbolRotate value will be ignored, and compulsively use tangent angle.
          // rotate by default if symbol rotation is not specified
          var specifiedRotation = symbol.__specifiedRotation;

          if (specifiedRotation == null) {
            var tangent = line.tangentAt(percent);
            symbol.attr('rotation', (percent === 1 ? -1 : 1) * Math.PI / 2 - Math.atan2(tangent[1], tangent[0]));
          } else {
            symbol.attr('rotation', specifiedRotation);
          }
        }

        if (symbolFrom) {
          symbolFrom.setPosition(fromPos);
          setSymbolRotation(symbolFrom, 0);
          symbolFrom.scaleX = symbolFrom.scaleY = invScale * percent;
          symbolFrom.markRedraw();
        }

        if (symbolTo) {
          symbolTo.setPosition(toPos);
          setSymbolRotation(symbolTo, 1);
          symbolTo.scaleX = symbolTo.scaleY = invScale * percent;
          symbolTo.markRedraw();
        }

        if (label && !label.ignore) {
          label.x = label.y = 0;
          label.originX = label.originY = 0;
          var textAlign = void 0;
          var textVerticalAlign = void 0;
          var distance = label.__labelDistance;
          var distanceX = distance[0] * invScale;
          var distanceY = distance[1] * invScale;
          var halfPercent = percent / 2;
          var tangent = line.tangentAt(halfPercent);
          var n = [tangent[1], -tangent[0]];
          var cp = line.pointAt(halfPercent);

          if (n[1] > 0) {
            n[0] = -n[0];
            n[1] = -n[1];
          }

          var dir = tangent[0] < 0 ? -1 : 1;

          if (label.__position !== 'start' && label.__position !== 'end') {
            var rotation = -Math.atan2(tangent[1], tangent[0]);

            if (toPos[0] < fromPos[0]) {
              rotation = Math.PI + rotation;
            }

            label.rotation = rotation;
          }

          var dy = void 0;

          switch (label.__position) {
            case 'insideStartTop':
            case 'insideMiddleTop':
            case 'insideEndTop':
            case 'middle':
              dy = -distanceY;
              textVerticalAlign = 'bottom';
              break;

            case 'insideStartBottom':
            case 'insideMiddleBottom':
            case 'insideEndBottom':
              dy = distanceY;
              textVerticalAlign = 'top';
              break;

            default:
              dy = 0;
              textVerticalAlign = 'middle';
          }

          switch (label.__position) {
            case 'end':
              label.x = d[0] * distanceX + toPos[0];
              label.y = d[1] * distanceY + toPos[1];
              textAlign = d[0] > 0.8 ? 'left' : d[0] < -0.8 ? 'right' : 'center';
              textVerticalAlign = d[1] > 0.8 ? 'top' : d[1] < -0.8 ? 'bottom' : 'middle';
              break;

            case 'start':
              label.x = -d[0] * distanceX + fromPos[0];
              label.y = -d[1] * distanceY + fromPos[1];
              textAlign = d[0] > 0.8 ? 'right' : d[0] < -0.8 ? 'left' : 'center';
              textVerticalAlign = d[1] > 0.8 ? 'bottom' : d[1] < -0.8 ? 'top' : 'middle';
              break;

            case 'insideStartTop':
            case 'insideStart':
            case 'insideStartBottom':
              label.x = distanceX * dir + fromPos[0];
              label.y = fromPos[1] + dy;
              textAlign = tangent[0] < 0 ? 'right' : 'left';
              label.originX = -distanceX * dir;
              label.originY = -dy;
              break;

            case 'insideMiddleTop':
            case 'insideMiddle':
            case 'insideMiddleBottom':
            case 'middle':
              label.x = cp[0];
              label.y = cp[1] + dy;
              textAlign = 'center';
              label.originY = -dy;
              break;

            case 'insideEndTop':
            case 'insideEnd':
            case 'insideEndBottom':
              label.x = -distanceX * dir + toPos[0];
              label.y = toPos[1] + dy;
              textAlign = tangent[0] >= 0 ? 'right' : 'left';
              label.originX = distanceX * dir;
              label.originY = -dy;
              break;
          }

          label.scaleX = label.scaleY = invScale;
          label.setStyle({
            // Use the user specified text align and baseline first
            verticalAlign: label.__verticalAlign || textVerticalAlign,
            align: label.__align || textAlign
          });
        }
      };

      return Line;
    }(Group);

    var LineDraw =
    /** @class */
    function () {
      function LineDraw(LineCtor) {
        this.group = new Group();
        this._LineCtor = LineCtor || Line$1;
      }

      LineDraw.prototype.updateData = function (lineData) {
        var _this = this; // Remove progressive els.


        this._progressiveEls = null;
        var lineDraw = this;
        var group = lineDraw.group;
        var oldLineData = lineDraw._lineData;
        lineDraw._lineData = lineData; // There is no oldLineData only when first rendering or switching from
        // stream mode to normal mode, where previous elements should be removed.

        if (!oldLineData) {
          group.removeAll();
        }

        var seriesScope = makeSeriesScope$1(lineData);
        lineData.diff(oldLineData).add(function (idx) {
          _this._doAdd(lineData, idx, seriesScope);
        }).update(function (newIdx, oldIdx) {
          _this._doUpdate(oldLineData, lineData, oldIdx, newIdx, seriesScope);
        }).remove(function (idx) {
          group.remove(oldLineData.getItemGraphicEl(idx));
        }).execute();
      };

      LineDraw.prototype.updateLayout = function () {
        var lineData = this._lineData; // Do not support update layout in incremental mode.

        if (!lineData) {
          return;
        }

        lineData.eachItemGraphicEl(function (el, idx) {
          el.updateLayout(lineData, idx);
        }, this);
      };

      LineDraw.prototype.incrementalPrepareUpdate = function (lineData) {
        this._seriesScope = makeSeriesScope$1(lineData);
        this._lineData = null;
        this.group.removeAll();
      };

      LineDraw.prototype.incrementalUpdate = function (taskParams, lineData) {
        this._progressiveEls = [];

        function updateIncrementalAndHover(el) {
          if (!el.isGroup && !isEffectObject(el)) {
            el.incremental = true;
            el.ensureState('emphasis').hoverLayer = true;
          }
        }

        for (var idx = taskParams.start; idx < taskParams.end; idx++) {
          var itemLayout = lineData.getItemLayout(idx);

          if (lineNeedsDraw(itemLayout)) {
            var el = new this._LineCtor(lineData, idx, this._seriesScope);
            el.traverse(updateIncrementalAndHover);
            this.group.add(el);
            lineData.setItemGraphicEl(idx, el);

            this._progressiveEls.push(el);
          }
        }
      };

      LineDraw.prototype.remove = function () {
        this.group.removeAll();
      };

      LineDraw.prototype.eachRendered = function (cb) {
        traverseElements(this._progressiveEls || this.group, cb);
      };

      LineDraw.prototype._doAdd = function (lineData, idx, seriesScope) {
        var itemLayout = lineData.getItemLayout(idx);

        if (!lineNeedsDraw(itemLayout)) {
          return;
        }

        var el = new this._LineCtor(lineData, idx, seriesScope);
        lineData.setItemGraphicEl(idx, el);
        this.group.add(el);
      };

      LineDraw.prototype._doUpdate = function (oldLineData, newLineData, oldIdx, newIdx, seriesScope) {
        var itemEl = oldLineData.getItemGraphicEl(oldIdx);

        if (!lineNeedsDraw(newLineData.getItemLayout(newIdx))) {
          this.group.remove(itemEl);
          return;
        }

        if (!itemEl) {
          itemEl = new this._LineCtor(newLineData, newIdx, seriesScope);
        } else {
          itemEl.updateData(newLineData, newIdx, seriesScope);
        }

        newLineData.setItemGraphicEl(newIdx, itemEl);
        this.group.add(itemEl);
      };

      return LineDraw;
    }();

    function isEffectObject(el) {
      return el.animators && el.animators.length > 0;
    }

    function makeSeriesScope$1(lineData) {
      var hostModel = lineData.hostModel;
      var emphasisModel = hostModel.getModel('emphasis');
      return {
        lineStyle: hostModel.getModel('lineStyle').getLineStyle(),
        emphasisLineStyle: emphasisModel.getModel(['lineStyle']).getLineStyle(),
        blurLineStyle: hostModel.getModel(['blur', 'lineStyle']).getLineStyle(),
        selectLineStyle: hostModel.getModel(['select', 'lineStyle']).getLineStyle(),
        emphasisDisabled: emphasisModel.get('disabled'),
        blurScope: emphasisModel.get('blurScope'),
        focus: emphasisModel.get('focus'),
        labelStatesModels: getLabelStatesModels(hostModel)
      };
    }

    function isPointNaN(pt) {
      return isNaN(pt[0]) || isNaN(pt[1]);
    }

    function lineNeedsDraw(pts) {
      return pts && !isPointNaN(pts[0]) && !isPointNaN(pts[1]);
    }

    var inner$e = makeInner();

    var markLineTransform = function (seriesModel, coordSys, mlModel, item) {
      var data = seriesModel.getData();
      var itemArray;

      if (!isArray(item)) {
        // Special type markLine like 'min', 'max', 'average', 'median'
        var mlType = item.type;

        if (mlType === 'min' || mlType === 'max' || mlType === 'average' || mlType === 'median' // In case
        // data: [{
        //   yAxis: 10
        // }]
        || item.xAxis != null || item.yAxis != null) {
          var valueAxis = void 0;
          var value = void 0;

          if (item.yAxis != null || item.xAxis != null) {
            valueAxis = coordSys.getAxis(item.yAxis != null ? 'y' : 'x');
            value = retrieve(item.yAxis, item.xAxis);
          } else {
            var axisInfo = getAxisInfo$1(item, data, coordSys, seriesModel);
            valueAxis = axisInfo.valueAxis;
            var valueDataDim = getStackedDimension(data, axisInfo.valueDataDim);
            value = numCalculate(data, valueDataDim, mlType);
          }

          var valueIndex = valueAxis.dim === 'x' ? 0 : 1;
          var baseIndex = 1 - valueIndex; // Normized to 2d data with start and end point

          var mlFrom = clone(item);
          var mlTo = {
            coord: []
          };
          mlFrom.type = null;
          mlFrom.coord = [];
          mlFrom.coord[baseIndex] = -Infinity;
          mlTo.coord[baseIndex] = Infinity;
          var precision = mlModel.get('precision');

          if (precision >= 0 && isNumber(value)) {
            value = +value.toFixed(Math.min(precision, 20));
          }

          mlFrom.coord[valueIndex] = mlTo.coord[valueIndex] = value;
          itemArray = [mlFrom, mlTo, {
            type: mlType,
            valueIndex: item.valueIndex,
            // Force to use the value of calculated value.
            value: value
          }];
        } else {
          // Invalid data
          if ("development" !== 'production') {
            logError('Invalid markLine data.');
          }

          itemArray = [];
        }
      } else {
        itemArray = item;
      }

      var normalizedItem = [dataTransform(seriesModel, itemArray[0]), dataTransform(seriesModel, itemArray[1]), extend({}, itemArray[2])]; // Avoid line data type is extended by from(to) data type

      normalizedItem[2].type = normalizedItem[2].type || null; // Merge from option and to option into line option

      merge(normalizedItem[2], normalizedItem[0]);
      merge(normalizedItem[2], normalizedItem[1]);
      return normalizedItem;
    };

    function isInfinity(val) {
      return !isNaN(val) && !isFinite(val);
    } // If a markLine has one dim


    function ifMarkLineHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) {
      var otherDimIndex = 1 - dimIndex;
      var dimName = coordSys.dimensions[dimIndex];
      return isInfinity(fromCoord[otherDimIndex]) && isInfinity(toCoord[otherDimIndex]) && fromCoord[dimIndex] === toCoord[dimIndex] && coordSys.getAxis(dimName).containData(fromCoord[dimIndex]);
    }

    function markLineFilter(coordSys, item) {
      if (coordSys.type === 'cartesian2d') {
        var fromCoord = item[0].coord;
        var toCoord = item[1].coord; // In case
        // {
        //  markLine: {
        //    data: [{ yAxis: 2 }]
        //  }
        // }

        if (fromCoord && toCoord && (ifMarkLineHasOnlyDim(1, fromCoord, toCoord, coordSys) || ifMarkLineHasOnlyDim(0, fromCoord, toCoord, coordSys))) {
          return true;
        }
      }

      return dataFilter$1(coordSys, item[0]) && dataFilter$1(coordSys, item[1]);
    }

    function updateSingleMarkerEndLayout(data, idx, isFrom, seriesModel, api) {
      var coordSys = seriesModel.coordinateSystem;
      var itemModel = data.getItemModel(idx);
      var point;
      var xPx = parsePercent$1(itemModel.get('x'), api.getWidth());
      var yPx = parsePercent$1(itemModel.get('y'), api.getHeight());

      if (!isNaN(xPx) && !isNaN(yPx)) {
        point = [xPx, yPx];
      } else {
        // Chart like bar may have there own marker positioning logic
        if (seriesModel.getMarkerPosition) {
          // Use the getMarkerPosition
          point = seriesModel.getMarkerPosition(data.getValues(data.dimensions, idx));
        } else {
          var dims = coordSys.dimensions;
          var x = data.get(dims[0], idx);
          var y = data.get(dims[1], idx);
          point = coordSys.dataToPoint([x, y]);
        } // Expand line to the edge of grid if value on one axis is Inifnity
        // In case
        //  markLine: {
        //    data: [{
        //      yAxis: 2
        //      // or
        //      type: 'average'
        //    }]
        //  }


        if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
          // TODO: TYPE ts@4.1 may still infer it as Axis instead of Axis2D. Not sure if it's a bug
          var xAxis = coordSys.getAxis('x');
          var yAxis = coordSys.getAxis('y');
          var dims = coordSys.dimensions;

          if (isInfinity(data.get(dims[0], idx))) {
            point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[isFrom ? 0 : 1]);
          } else if (isInfinity(data.get(dims[1], idx))) {
            point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[isFrom ? 0 : 1]);
          }
        } // Use x, y if has any


        if (!isNaN(xPx)) {
          point[0] = xPx;
        }

        if (!isNaN(yPx)) {
          point[1] = yPx;
        }
      }

      data.setItemLayout(idx, point);
    }

    var MarkLineView =
    /** @class */
    function (_super) {
      __extends(MarkLineView, _super);

      function MarkLineView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkLineView.type;
        return _this;
      }

      MarkLineView.prototype.updateTransform = function (markLineModel, ecModel, api) {
        ecModel.eachSeries(function (seriesModel) {
          var mlModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markLine');

          if (mlModel) {
            var mlData_1 = mlModel.getData();
            var fromData_1 = inner$e(mlModel).from;
            var toData_1 = inner$e(mlModel).to; // Update visual and layout of from symbol and to symbol

            fromData_1.each(function (idx) {
              updateSingleMarkerEndLayout(fromData_1, idx, true, seriesModel, api);
              updateSingleMarkerEndLayout(toData_1, idx, false, seriesModel, api);
            }); // Update layout of line

            mlData_1.each(function (idx) {
              mlData_1.setItemLayout(idx, [fromData_1.getItemLayout(idx), toData_1.getItemLayout(idx)]);
            });
            this.markerGroupMap.get(seriesModel.id).updateLayout();
          }
        }, this);
      };

      MarkLineView.prototype.renderSeries = function (seriesModel, mlModel, ecModel, api) {
        var coordSys = seriesModel.coordinateSystem;
        var seriesId = seriesModel.id;
        var seriesData = seriesModel.getData();
        var lineDrawMap = this.markerGroupMap;
        var lineDraw = lineDrawMap.get(seriesId) || lineDrawMap.set(seriesId, new LineDraw());
        this.group.add(lineDraw.group);
        var mlData = createList$1(coordSys, seriesModel, mlModel);
        var fromData = mlData.from;
        var toData = mlData.to;
        var lineData = mlData.line;
        inner$e(mlModel).from = fromData;
        inner$e(mlModel).to = toData; // Line data for tooltip and formatter

        mlModel.setData(lineData); // TODO
        // Functionally, `symbolSize` & `symbolOffset` can also be 2D array now.
        // But the related logic and type definition are not finished yet.
        // Finish it if required

        var symbolType = mlModel.get('symbol');
        var symbolSize = mlModel.get('symbolSize');
        var symbolRotate = mlModel.get('symbolRotate');
        var symbolOffset = mlModel.get('symbolOffset'); // TODO: support callback function like markPoint

        if (!isArray(symbolType)) {
          symbolType = [symbolType, symbolType];
        }

        if (!isArray(symbolSize)) {
          symbolSize = [symbolSize, symbolSize];
        }

        if (!isArray(symbolRotate)) {
          symbolRotate = [symbolRotate, symbolRotate];
        }

        if (!isArray(symbolOffset)) {
          symbolOffset = [symbolOffset, symbolOffset];
        } // Update visual and layout of from symbol and to symbol


        mlData.from.each(function (idx) {
          updateDataVisualAndLayout(fromData, idx, true);
          updateDataVisualAndLayout(toData, idx, false);
        }); // Update visual and layout of line

        lineData.each(function (idx) {
          var lineStyle = lineData.getItemModel(idx).getModel('lineStyle').getLineStyle(); // lineData.setItemVisual(idx, {
          //     color: lineColor || fromData.getItemVisual(idx, 'color')
          // });

          lineData.setItemLayout(idx, [fromData.getItemLayout(idx), toData.getItemLayout(idx)]);

          if (lineStyle.stroke == null) {
            lineStyle.stroke = fromData.getItemVisual(idx, 'style').fill;
          }

          lineData.setItemVisual(idx, {
            fromSymbolKeepAspect: fromData.getItemVisual(idx, 'symbolKeepAspect'),
            fromSymbolOffset: fromData.getItemVisual(idx, 'symbolOffset'),
            fromSymbolRotate: fromData.getItemVisual(idx, 'symbolRotate'),
            fromSymbolSize: fromData.getItemVisual(idx, 'symbolSize'),
            fromSymbol: fromData.getItemVisual(idx, 'symbol'),
            toSymbolKeepAspect: toData.getItemVisual(idx, 'symbolKeepAspect'),
            toSymbolOffset: toData.getItemVisual(idx, 'symbolOffset'),
            toSymbolRotate: toData.getItemVisual(idx, 'symbolRotate'),
            toSymbolSize: toData.getItemVisual(idx, 'symbolSize'),
            toSymbol: toData.getItemVisual(idx, 'symbol'),
            style: lineStyle
          });
        });
        lineDraw.updateData(lineData); // Set host model for tooltip
        // FIXME

        mlData.line.eachItemGraphicEl(function (el) {
          getECData(el).dataModel = mlModel;
          el.traverse(function (child) {
            getECData(child).dataModel = mlModel;
          });
        });

        function updateDataVisualAndLayout(data, idx, isFrom) {
          var itemModel = data.getItemModel(idx);
          updateSingleMarkerEndLayout(data, idx, isFrom, seriesModel, api);
          var style = itemModel.getModel('itemStyle').getItemStyle();

          if (style.fill == null) {
            style.fill = getVisualFromData(seriesData, 'color');
          }

          data.setItemVisual(idx, {
            symbolKeepAspect: itemModel.get('symbolKeepAspect'),
            // `0` should be considered as a valid value, so use `retrieve2` instead of `||`
            symbolOffset: retrieve2(itemModel.get('symbolOffset', true), symbolOffset[isFrom ? 0 : 1]),
            symbolRotate: retrieve2(itemModel.get('symbolRotate', true), symbolRotate[isFrom ? 0 : 1]),
            // TODO: when 2d array is supported, it should ignore parent
            symbolSize: retrieve2(itemModel.get('symbolSize'), symbolSize[isFrom ? 0 : 1]),
            symbol: retrieve2(itemModel.get('symbol', true), symbolType[isFrom ? 0 : 1]),
            style: style
          });
        }

        this.markKeep(lineDraw);
        lineDraw.group.silent = mlModel.get('silent') || seriesModel.get('silent');
      };

      MarkLineView.type = 'markLine';
      return MarkLineView;
    }(MarkerView);

    function createList$1(coordSys, seriesModel, mlModel) {
      var coordDimsInfos;

      if (coordSys) {
        coordDimsInfos = map(coordSys && coordSys.dimensions, function (coordDim) {
          var info = seriesModel.getData().getDimensionInfo(seriesModel.getData().mapDimension(coordDim)) || {}; // In map series data don't have lng and lat dimension. Fallback to same with coordSys

          return extend(extend({}, info), {
            name: coordDim,
            // DON'T use ordinalMeta to parse and collect ordinal.
            ordinalMeta: null
          });
        });
      } else {
        coordDimsInfos = [{
          name: 'value',
          type: 'float'
        }];
      }

      var fromData = new SeriesData(coordDimsInfos, mlModel);
      var toData = new SeriesData(coordDimsInfos, mlModel); // No dimensions

      var lineData = new SeriesData([], mlModel);
      var optData = map(mlModel.get('data'), curry(markLineTransform, seriesModel, coordSys, mlModel));

      if (coordSys) {
        optData = filter(optData, curry(markLineFilter, coordSys));
      }

      var dimValueGetter = createMarkerDimValueGetter(!!coordSys, coordDimsInfos);
      fromData.initData(map(optData, function (item) {
        return item[0];
      }), null, dimValueGetter);
      toData.initData(map(optData, function (item) {
        return item[1];
      }), null, dimValueGetter);
      lineData.initData(map(optData, function (item) {
        return item[2];
      }));
      lineData.hasItemOption = true;
      return {
        from: fromData,
        to: toData,
        line: lineData
      };
    }

    function install$f(registers) {
      registers.registerComponentModel(MarkLineModel);
      registers.registerComponentView(MarkLineView);
      registers.registerPreprocessor(function (opt) {
        if (checkMarkerInSeries(opt.series, 'markLine')) {
          // Make sure markLine component is enabled
          opt.markLine = opt.markLine || {};
        }
      });
    }

    var MarkAreaModel =
    /** @class */
    function (_super) {
      __extends(MarkAreaModel, _super);

      function MarkAreaModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkAreaModel.type;
        return _this;
      }

      MarkAreaModel.prototype.createMarkerModelFromSeries = function (markerOpt, masterMarkerModel, ecModel) {
        return new MarkAreaModel(markerOpt, masterMarkerModel, ecModel);
      };

      MarkAreaModel.type = 'markArea';
      MarkAreaModel.defaultOption = {
        // zlevel: 0,
        // PENDING
        z: 1,
        tooltip: {
          trigger: 'item'
        },
        // markArea should fixed on the coordinate system
        animation: false,
        label: {
          show: true,
          position: 'top'
        },
        itemStyle: {
          // color and borderColor default to use color from series
          // color: 'auto'
          // borderColor: 'auto'
          borderWidth: 0
        },
        emphasis: {
          label: {
            show: true,
            position: 'top'
          }
        }
      };
      return MarkAreaModel;
    }(MarkerModel);

    var inner$f = makeInner();

    var markAreaTransform = function (seriesModel, coordSys, maModel, item) {
      // item may be null
      var item0 = item[0];
      var item1 = item[1];

      if (!item0 || !item1) {
        return;
      }

      var lt = dataTransform(seriesModel, item0);
      var rb = dataTransform(seriesModel, item1); // FIXME make sure lt is less than rb

      var ltCoord = lt.coord;
      var rbCoord = rb.coord;
      ltCoord[0] = retrieve(ltCoord[0], -Infinity);
      ltCoord[1] = retrieve(ltCoord[1], -Infinity);
      rbCoord[0] = retrieve(rbCoord[0], Infinity);
      rbCoord[1] = retrieve(rbCoord[1], Infinity); // Merge option into one

      var result = mergeAll([{}, lt, rb]);
      result.coord = [lt.coord, rb.coord];
      result.x0 = lt.x;
      result.y0 = lt.y;
      result.x1 = rb.x;
      result.y1 = rb.y;
      return result;
    };

    function isInfinity$1(val) {
      return !isNaN(val) && !isFinite(val);
    } // If a markArea has one dim


    function ifMarkAreaHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) {
      var otherDimIndex = 1 - dimIndex;
      return isInfinity$1(fromCoord[otherDimIndex]) && isInfinity$1(toCoord[otherDimIndex]);
    }

    function markAreaFilter(coordSys, item) {
      var fromCoord = item.coord[0];
      var toCoord = item.coord[1];
      var item0 = {
        coord: fromCoord,
        x: item.x0,
        y: item.y0
      };
      var item1 = {
        coord: toCoord,
        x: item.x1,
        y: item.y1
      };

      if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
        // In case
        // {
        //  markArea: {
        //    data: [{ yAxis: 2 }]
        //  }
        // }
        if (fromCoord && toCoord && (ifMarkAreaHasOnlyDim(1, fromCoord, toCoord) || ifMarkAreaHasOnlyDim(0, fromCoord, toCoord))) {
          return true;
        } // Directly returning true may also do the work,
        // because markArea will not be shown automatically
        // when it's not included in coordinate system.
        // But filtering ahead can avoid keeping rendering markArea
        // when there are too many of them.


        return zoneFilter(coordSys, item0, item1);
      }

      return dataFilter$1(coordSys, item0) || dataFilter$1(coordSys, item1);
    } // dims can be ['x0', 'y0'], ['x1', 'y1'], ['x0', 'y1'], ['x1', 'y0']


    function getSingleMarkerEndPoint(data, idx, dims, seriesModel, api) {
      var coordSys = seriesModel.coordinateSystem;
      var itemModel = data.getItemModel(idx);
      var point;
      var xPx = parsePercent$1(itemModel.get(dims[0]), api.getWidth());
      var yPx = parsePercent$1(itemModel.get(dims[1]), api.getHeight());

      if (!isNaN(xPx) && !isNaN(yPx)) {
        point = [xPx, yPx];
      } else {
        // Chart like bar may have there own marker positioning logic
        if (seriesModel.getMarkerPosition) {
          // Consider the case that user input the right-bottom point first
          // Pick the larger x and y as 'x1' and 'y1'
          var pointValue0 = data.getValues(['x0', 'y0'], idx);
          var pointValue1 = data.getValues(['x1', 'y1'], idx);
          var clampPointValue0 = coordSys.clampData(pointValue0);
          var clampPointValue1 = coordSys.clampData(pointValue1);
          var pointValue = [];

          if (dims[0] === 'x0') {
            pointValue[0] = clampPointValue0[0] > clampPointValue1[0] ? pointValue1[0] : pointValue0[0];
          } else {
            pointValue[0] = clampPointValue0[0] > clampPointValue1[0] ? pointValue0[0] : pointValue1[0];
          }

          if (dims[1] === 'y0') {
            pointValue[1] = clampPointValue0[1] > clampPointValue1[1] ? pointValue1[1] : pointValue0[1];
          } else {
            pointValue[1] = clampPointValue0[1] > clampPointValue1[1] ? pointValue0[1] : pointValue1[1];
          } // Use the getMarkerPosition


          point = seriesModel.getMarkerPosition(pointValue, dims, true);
        } else {
          var x = data.get(dims[0], idx);
          var y = data.get(dims[1], idx);
          var pt = [x, y];
          coordSys.clampData && coordSys.clampData(pt, pt);
          point = coordSys.dataToPoint(pt, true);
        }

        if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
          // TODO: TYPE ts@4.1 may still infer it as Axis instead of Axis2D. Not sure if it's a bug
          var xAxis = coordSys.getAxis('x');
          var yAxis = coordSys.getAxis('y');
          var x = data.get(dims[0], idx);
          var y = data.get(dims[1], idx);

          if (isInfinity$1(x)) {
            point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[dims[0] === 'x0' ? 0 : 1]);
          } else if (isInfinity$1(y)) {
            point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[dims[1] === 'y0' ? 0 : 1]);
          }
        } // Use x, y if has any


        if (!isNaN(xPx)) {
          point[0] = xPx;
        }

        if (!isNaN(yPx)) {
          point[1] = yPx;
        }
      }

      return point;
    }

    var dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']];

    var MarkAreaView =
    /** @class */
    function (_super) {
      __extends(MarkAreaView, _super);

      function MarkAreaView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkAreaView.type;
        return _this;
      }

      MarkAreaView.prototype.updateTransform = function (markAreaModel, ecModel, api) {
        ecModel.eachSeries(function (seriesModel) {
          var maModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markArea');

          if (maModel) {
            var areaData_1 = maModel.getData();
            areaData_1.each(function (idx) {
              var points = map(dimPermutations, function (dim) {
                return getSingleMarkerEndPoint(areaData_1, idx, dim, seriesModel, api);
              }); // Layout

              areaData_1.setItemLayout(idx, points);
              var el = areaData_1.getItemGraphicEl(idx);
              el.setShape('points', points);
            });
          }
        }, this);
      };

      MarkAreaView.prototype.renderSeries = function (seriesModel, maModel, ecModel, api) {
        var coordSys = seriesModel.coordinateSystem;
        var seriesId = seriesModel.id;
        var seriesData = seriesModel.getData();
        var areaGroupMap = this.markerGroupMap;
        var polygonGroup = areaGroupMap.get(seriesId) || areaGroupMap.set(seriesId, {
          group: new Group()
        });
        this.group.add(polygonGroup.group);
        this.markKeep(polygonGroup);
        var areaData = createList$2(coordSys, seriesModel, maModel); // Line data for tooltip and formatter

        maModel.setData(areaData); // Update visual and layout of line

        areaData.each(function (idx) {
          // Layout
          var points = map(dimPermutations, function (dim) {
            return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api);
          });
          var xAxisScale = coordSys.getAxis('x').scale;
          var yAxisScale = coordSys.getAxis('y').scale;
          var xAxisExtent = xAxisScale.getExtent();
          var yAxisExtent = yAxisScale.getExtent();
          var xPointExtent = [xAxisScale.parse(areaData.get('x0', idx)), xAxisScale.parse(areaData.get('x1', idx))];
          var yPointExtent = [yAxisScale.parse(areaData.get('y0', idx)), yAxisScale.parse(areaData.get('y1', idx))];
          asc(xPointExtent);
          asc(yPointExtent);
          var overlapped = !(xAxisExtent[0] > xPointExtent[1] || xAxisExtent[1] < xPointExtent[0] || yAxisExtent[0] > yPointExtent[1] || yAxisExtent[1] < yPointExtent[0]); // If none of the area is inside coordSys, allClipped is set to be true
          // in layout so that label will not be displayed. See #12591

          var allClipped = !overlapped;
          areaData.setItemLayout(idx, {
            points: points,
            allClipped: allClipped
          });
          var style = areaData.getItemModel(idx).getModel('itemStyle').getItemStyle();
          var color$1 = getVisualFromData(seriesData, 'color');

          if (!style.fill) {
            style.fill = color$1;

            if (isString(style.fill)) {
              style.fill = modifyAlpha(style.fill, 0.4);
            }
          }

          if (!style.stroke) {
            style.stroke = color$1;
          } // Visual


          areaData.setItemVisual(idx, 'style', style);
        });
        areaData.diff(inner$f(polygonGroup).data).add(function (idx) {
          var layout = areaData.getItemLayout(idx);

          if (!layout.allClipped) {
            var polygon = new Polygon({
              shape: {
                points: layout.points
              }
            });
            areaData.setItemGraphicEl(idx, polygon);
            polygonGroup.group.add(polygon);
          }
        }).update(function (newIdx, oldIdx) {
          var polygon = inner$f(polygonGroup).data.getItemGraphicEl(oldIdx);
          var layout = areaData.getItemLayout(newIdx);

          if (!layout.allClipped) {
            if (polygon) {
              updateProps(polygon, {
                shape: {
                  points: layout.points
                }
              }, maModel, newIdx);
            } else {
              polygon = new Polygon({
                shape: {
                  points: layout.points
                }
              });
            }

            areaData.setItemGraphicEl(newIdx, polygon);
            polygonGroup.group.add(polygon);
          } else if (polygon) {
            polygonGroup.group.remove(polygon);
          }
        }).remove(function (idx) {
          var polygon = inner$f(polygonGroup).data.getItemGraphicEl(idx);
          polygonGroup.group.remove(polygon);
        }).execute();
        areaData.eachItemGraphicEl(function (polygon, idx) {
          var itemModel = areaData.getItemModel(idx);
          var style = areaData.getItemVisual(idx, 'style');
          polygon.useStyle(areaData.getItemVisual(idx, 'style'));
          setLabelStyle(polygon, getLabelStatesModels(itemModel), {
            labelFetcher: maModel,
            labelDataIndex: idx,
            defaultText: areaData.getName(idx) || '',
            inheritColor: isString(style.fill) ? modifyAlpha(style.fill, 1) : '#000'
          });
          setStatesStylesFromModel(polygon, itemModel);
          toggleHoverEmphasis(polygon, null, null, itemModel.get(['emphasis', 'disabled']));
          getECData(polygon).dataModel = maModel;
        });
        inner$f(polygonGroup).data = areaData;
        polygonGroup.group.silent = maModel.get('silent') || seriesModel.get('silent');
      };

      MarkAreaView.type = 'markArea';
      return MarkAreaView;
    }(MarkerView);

    function createList$2(coordSys, seriesModel, maModel) {
      var areaData;
      var dataDims;
      var dims = ['x0', 'y0', 'x1', 'y1'];

      if (coordSys) {
        var coordDimsInfos_1 = map(coordSys && coordSys.dimensions, function (coordDim) {
          var data = seriesModel.getData();
          var info = data.getDimensionInfo(data.mapDimension(coordDim)) || {}; // In map series data don't have lng and lat dimension. Fallback to same with coordSys

          return extend(extend({}, info), {
            name: coordDim,
            // DON'T use ordinalMeta to parse and collect ordinal.
            ordinalMeta: null
          });
        });
        dataDims = map(dims, function (dim, idx) {
          return {
            name: dim,
            type: coordDimsInfos_1[idx % 2].type
          };
        });
        areaData = new SeriesData(dataDims, maModel);
      } else {
        dataDims = [{
          name: 'value',
          type: 'float'
        }];
        areaData = new SeriesData(dataDims, maModel);
      }

      var optData = map(maModel.get('data'), curry(markAreaTransform, seriesModel, coordSys, maModel));

      if (coordSys) {
        optData = filter(optData, curry(markAreaFilter, coordSys));
      }

      var dimValueGetter = coordSys ? function (item, dimName, dataIndex, dimIndex) {
        // TODO should convert to ParsedValue?
        var rawVal = item.coord[Math.floor(dimIndex / 2)][dimIndex % 2];
        return parseDataValue(rawVal, dataDims[dimIndex]);
      } : function (item, dimName, dataIndex, dimIndex) {
        return parseDataValue(item.value, dataDims[dimIndex]);
      };
      areaData.initData(optData, null, dimValueGetter);
      areaData.hasItemOption = true;
      return areaData;
    }

    function install$g(registers) {
      registers.registerComponentModel(MarkAreaModel);
      registers.registerComponentView(MarkAreaView);
      registers.registerPreprocessor(function (opt) {
        if (checkMarkerInSeries(opt.series, 'markArea')) {
          // Make sure markArea component is enabled
          opt.markArea = opt.markArea || {};
        }
      });
    }

    var getDefaultSelectorOptions = function (ecModel, type) {
      if (type === 'all') {
        return {
          type: 'all',
          title: ecModel.getLocaleModel().get(['legend', 'selector', 'all'])
        };
      } else if (type === 'inverse') {
        return {
          type: 'inverse',
          title: ecModel.getLocaleModel().get(['legend', 'selector', 'inverse'])
        };
      }
    };

    var LegendModel =
    /** @class */
    function (_super) {
      __extends(LegendModel, _super);

      function LegendModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = LegendModel.type;
        _this.layoutMode = {
          type: 'box',
          // legend.width/height are maxWidth/maxHeight actually,
          // whereas real width/height is calculated by its content.
          // (Setting {left: 10, right: 10} does not make sense).
          // So consider the case:
          // `setOption({legend: {left: 10});`
          // then `setOption({legend: {right: 10});`
          // The previous `left` should be cleared by setting `ignoreSize`.
          ignoreSize: true
        };
        return _this;
      }

      LegendModel.prototype.init = function (option, parentModel, ecModel) {
        this.mergeDefaultAndTheme(option, ecModel);
        option.selected = option.selected || {};

        this._updateSelector(option);
      };

      LegendModel.prototype.mergeOption = function (option, ecModel) {
        _super.prototype.mergeOption.call(this, option, ecModel);

        this._updateSelector(option);
      };

      LegendModel.prototype._updateSelector = function (option) {
        var selector = option.selector;
        var ecModel = this.ecModel;

        if (selector === true) {
          selector = option.selector = ['all', 'inverse'];
        }

        if (isArray(selector)) {
          each(selector, function (item, index) {
            isString(item) && (item = {
              type: item
            });
            selector[index] = merge(item, getDefaultSelectorOptions(ecModel, item.type));
          });
        }
      };

      LegendModel.prototype.optionUpdated = function () {
        this._updateData(this.ecModel);

        var legendData = this._data; // If selectedMode is single, try to select one

        if (legendData[0] && this.get('selectedMode') === 'single') {
          var hasSelected = false; // If has any selected in option.selected

          for (var i = 0; i < legendData.length; i++) {
            var name_1 = legendData[i].get('name');

            if (this.isSelected(name_1)) {
              // Force to unselect others
              this.select(name_1);
              hasSelected = true;
              break;
            }
          } // Try select the first if selectedMode is single


          !hasSelected && this.select(legendData[0].get('name'));
        }
      };

      LegendModel.prototype._updateData = function (ecModel) {
        var potentialData = [];
        var availableNames = [];
        ecModel.eachRawSeries(function (seriesModel) {
          var seriesName = seriesModel.name;
          availableNames.push(seriesName);
          var isPotential;

          if (seriesModel.legendVisualProvider) {
            var provider = seriesModel.legendVisualProvider;
            var names = provider.getAllNames();

            if (!ecModel.isSeriesFiltered(seriesModel)) {
              availableNames = availableNames.concat(names);
            }

            if (names.length) {
              potentialData = potentialData.concat(names);
            } else {
              isPotential = true;
            }
          } else {
            isPotential = true;
          }

          if (isPotential && isNameSpecified(seriesModel)) {
            potentialData.push(seriesModel.name);
          }
        });
        /**
         * @type {Array.<string>}
         * @private
         */

        this._availableNames = availableNames; // If legend.data is not specified in option, use availableNames as data,
        // which is convenient for user preparing option.

        var rawData = this.get('data') || potentialData;
        var legendNameMap = createHashMap();
        var legendData = map(rawData, function (dataItem) {
          // Can be string or number
          if (isString(dataItem) || isNumber(dataItem)) {
            dataItem = {
              name: dataItem
            };
          }

          if (legendNameMap.get(dataItem.name)) {
            // remove legend name duplicate
            return null;
          }

          legendNameMap.set(dataItem.name, true);
          return new Model(dataItem, this, this.ecModel);
        }, this);
        /**
         * @type {Array.<module:echarts/model/Model>}
         * @private
         */

        this._data = filter(legendData, function (item) {
          return !!item;
        });
      };

      LegendModel.prototype.getData = function () {
        return this._data;
      };

      LegendModel.prototype.select = function (name) {
        var selected = this.option.selected;
        var selectedMode = this.get('selectedMode');

        if (selectedMode === 'single') {
          var data = this._data;
          each(data, function (dataItem) {
            selected[dataItem.get('name')] = false;
          });
        }

        selected[name] = true;
      };

      LegendModel.prototype.unSelect = function (name) {
        if (this.get('selectedMode') !== 'single') {
          this.option.selected[name] = false;
        }
      };

      LegendModel.prototype.toggleSelected = function (name) {
        var selected = this.option.selected; // Default is true

        if (!selected.hasOwnProperty(name)) {
          selected[name] = true;
        }

        this[selected[name] ? 'unSelect' : 'select'](name);
      };

      LegendModel.prototype.allSelect = function () {
        var data = this._data;
        var selected = this.option.selected;
        each(data, function (dataItem) {
          selected[dataItem.get('name', true)] = true;
        });
      };

      LegendModel.prototype.inverseSelect = function () {
        var data = this._data;
        var selected = this.option.selected;
        each(data, function (dataItem) {
          var name = dataItem.get('name', true); // Initially, default value is true

          if (!selected.hasOwnProperty(name)) {
            selected[name] = true;
          }

          selected[name] = !selected[name];
        });
      };

      LegendModel.prototype.isSelected = function (name) {
        var selected = this.option.selected;
        return !(selected.hasOwnProperty(name) && !selected[name]) && indexOf(this._availableNames, name) >= 0;
      };

      LegendModel.prototype.getOrient = function () {
        return this.get('orient') === 'vertical' ? {
          index: 1,
          name: 'vertical'
        } : {
          index: 0,
          name: 'horizontal'
        };
      };

      LegendModel.type = 'legend.plain';
      LegendModel.dependencies = ['series'];
      LegendModel.defaultOption = {
        // zlevel: 0,
        z: 4,
        show: true,
        orient: 'horizontal',
        left: 'center',
        // right: 'center',
        top: 0,
        // bottom: null,
        align: 'auto',
        backgroundColor: 'rgba(0,0,0,0)',
        borderColor: '#ccc',
        borderRadius: 0,
        borderWidth: 0,
        padding: 5,
        itemGap: 10,
        itemWidth: 25,
        itemHeight: 14,
        symbolRotate: 'inherit',
        symbolKeepAspect: true,
        inactiveColor: '#ccc',
        inactiveBorderColor: '#ccc',
        inactiveBorderWidth: 'auto',
        itemStyle: {
          color: 'inherit',
          opacity: 'inherit',
          borderColor: 'inherit',
          borderWidth: 'auto',
          borderCap: 'inherit',
          borderJoin: 'inherit',
          borderDashOffset: 'inherit',
          borderMiterLimit: 'inherit'
        },
        lineStyle: {
          width: 'auto',
          color: 'inherit',
          inactiveColor: '#ccc',
          inactiveWidth: 2,
          opacity: 'inherit',
          type: 'inherit',
          cap: 'inherit',
          join: 'inherit',
          dashOffset: 'inherit',
          miterLimit: 'inherit'
        },
        textStyle: {
          color: '#333'
        },
        selectedMode: true,
        selector: false,
        selectorLabel: {
          show: true,
          borderRadius: 10,
          padding: [3, 5, 3, 5],
          fontSize: 12,
          fontFamily: 'sans-serif',
          color: '#666',
          borderWidth: 1,
          borderColor: '#666'
        },
        emphasis: {
          selectorLabel: {
            show: true,
            color: '#eee',
            backgroundColor: '#666'
          }
        },
        selectorPosition: 'auto',
        selectorItemGap: 7,
        selectorButtonGap: 10,
        tooltip: {
          show: false
        }
      };
      return LegendModel;
    }(ComponentModel);

    var curry$1 = curry;
    var each$7 = each;
    var Group$1 = Group;

    var LegendView =
    /** @class */
    function (_super) {
      __extends(LegendView, _super);

      function LegendView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = LegendView.type;
        _this.newlineDisabled = false;
        return _this;
      }

      LegendView.prototype.init = function () {
        this.group.add(this._contentGroup = new Group$1());
        this.group.add(this._selectorGroup = new Group$1());
        this._isFirstRender = true;
      };
      /**
       * @protected
       */


      LegendView.prototype.getContentGroup = function () {
        return this._contentGroup;
      };
      /**
       * @protected
       */


      LegendView.prototype.getSelectorGroup = function () {
        return this._selectorGroup;
      };
      /**
       * @override
       */


      LegendView.prototype.render = function (legendModel, ecModel, api) {
        var isFirstRender = this._isFirstRender;
        this._isFirstRender = false;
        this.resetInner();

        if (!legendModel.get('show', true)) {
          return;
        }

        var itemAlign = legendModel.get('align');
        var orient = legendModel.get('orient');

        if (!itemAlign || itemAlign === 'auto') {
          itemAlign = legendModel.get('left') === 'right' && orient === 'vertical' ? 'right' : 'left';
        } // selector has been normalized to an array in model


        var selector = legendModel.get('selector', true);
        var selectorPosition = legendModel.get('selectorPosition', true);

        if (selector && (!selectorPosition || selectorPosition === 'auto')) {
          selectorPosition = orient === 'horizontal' ? 'end' : 'start';
        }

        this.renderInner(itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition); // Perform layout.

        var positionInfo = legendModel.getBoxLayoutParams();
        var viewportSize = {
          width: api.getWidth(),
          height: api.getHeight()
        };
        var padding = legendModel.get('padding');
        var maxSize = getLayoutRect(positionInfo, viewportSize, padding);
        var mainRect = this.layoutInner(legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition); // Place mainGroup, based on the calculated `mainRect`.

        var layoutRect = getLayoutRect(defaults({
          width: mainRect.width,
          height: mainRect.height
        }, positionInfo), viewportSize, padding);
        this.group.x = layoutRect.x - mainRect.x;
        this.group.y = layoutRect.y - mainRect.y;
        this.group.markRedraw(); // Render background after group is layout.

        this.group.add(this._backgroundEl = makeBackground(mainRect, legendModel));
      };

      LegendView.prototype.resetInner = function () {
        this.getContentGroup().removeAll();
        this._backgroundEl && this.group.remove(this._backgroundEl);
        this.getSelectorGroup().removeAll();
      };

      LegendView.prototype.renderInner = function (itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition) {
        var contentGroup = this.getContentGroup();
        var legendDrawnMap = createHashMap();
        var selectMode = legendModel.get('selectedMode');
        var excludeSeriesId = [];
        ecModel.eachRawSeries(function (seriesModel) {
          !seriesModel.get('legendHoverLink') && excludeSeriesId.push(seriesModel.id);
        });
        each$7(legendModel.getData(), function (legendItemModel, dataIndex) {
          var name = legendItemModel.get('name'); // Use empty string or \n as a newline string

          if (!this.newlineDisabled && (name === '' || name === '\n')) {
            var g = new Group$1(); // @ts-ignore

            g.newline = true;
            contentGroup.add(g);
            return;
          } // Representitive series.


          var seriesModel = ecModel.getSeriesByName(name)[0];

          if (legendDrawnMap.get(name)) {
            // Have been drawn
            return;
          } // Legend to control series.


          if (seriesModel) {
            var data = seriesModel.getData();
            var lineVisualStyle = data.getVisual('legendLineStyle') || {};
            var legendIcon = data.getVisual('legendIcon');
            /**
             * `data.getVisual('style')` may be the color from the register
             * in series. For example, for line series,
             */

            var style = data.getVisual('style');

            var itemGroup = this._createItem(seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, lineVisualStyle, style, legendIcon, selectMode, api);

            itemGroup.on('click', curry$1(dispatchSelectAction, name, null, api, excludeSeriesId)).on('mouseover', curry$1(dispatchHighlightAction, seriesModel.name, null, api, excludeSeriesId)).on('mouseout', curry$1(dispatchDownplayAction, seriesModel.name, null, api, excludeSeriesId));
            legendDrawnMap.set(name, true);
          } else {
            // Legend to control data. In pie and funnel.
            ecModel.eachRawSeries(function (seriesModel) {
              // In case multiple series has same data name
              if (legendDrawnMap.get(name)) {
                return;
              }

              if (seriesModel.legendVisualProvider) {
                var provider = seriesModel.legendVisualProvider;

                if (!provider.containName(name)) {
                  return;
                }

                var idx = provider.indexOfName(name);
                var style = provider.getItemVisual(idx, 'style');
                var legendIcon = provider.getItemVisual(idx, 'legendIcon');
                var colorArr = parse(style.fill); // Color may be set to transparent in visualMap when data is out of range.
                // Do not show nothing.

                if (colorArr && colorArr[3] === 0) {
                  colorArr[3] = 0.2; // TODO color is set to 0, 0, 0, 0. Should show correct RGBA

                  style = extend(extend({}, style), {
                    fill: stringify(colorArr, 'rgba')
                  });
                }

                var itemGroup = this._createItem(seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, {}, style, legendIcon, selectMode, api); // FIXME: consider different series has items with the same name.


                itemGroup.on('click', curry$1(dispatchSelectAction, null, name, api, excludeSeriesId)) // Should not specify the series name, consider legend controls
                // more than one pie series.
                .on('mouseover', curry$1(dispatchHighlightAction, null, name, api, excludeSeriesId)).on('mouseout', curry$1(dispatchDownplayAction, null, name, api, excludeSeriesId));
                legendDrawnMap.set(name, true);
              }
            }, this);
          }

          if ("development" !== 'production') {
            if (!legendDrawnMap.get(name)) {
              console.warn(name + ' series not exists. Legend data should be same with series name or data name.');
            }
          }
        }, this);

        if (selector) {
          this._createSelector(selector, legendModel, api, orient, selectorPosition);
        }
      };

      LegendView.prototype._createSelector = function (selector, legendModel, api, orient, selectorPosition) {
        var selectorGroup = this.getSelectorGroup();
        each$7(selector, function createSelectorButton(selectorItem) {
          var type = selectorItem.type;
          var labelText = new ZRText({
            style: {
              x: 0,
              y: 0,
              align: 'center',
              verticalAlign: 'middle'
            },
            onclick: function () {
              api.dispatchAction({
                type: type === 'all' ? 'legendAllSelect' : 'legendInverseSelect'
              });
            }
          });
          selectorGroup.add(labelText);
          var labelModel = legendModel.getModel('selectorLabel');
          var emphasisLabelModel = legendModel.getModel(['emphasis', 'selectorLabel']);
          setLabelStyle(labelText, {
            normal: labelModel,
            emphasis: emphasisLabelModel
          }, {
            defaultText: selectorItem.title
          });
          enableHoverEmphasis(labelText);
        });
      };

      LegendView.prototype._createItem = function (seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, lineVisualStyle, itemVisualStyle, legendIcon, selectMode, api) {
        var drawType = seriesModel.visualDrawType;
        var itemWidth = legendModel.get('itemWidth');
        var itemHeight = legendModel.get('itemHeight');
        var isSelected = legendModel.isSelected(name);
        var iconRotate = legendItemModel.get('symbolRotate');
        var symbolKeepAspect = legendItemModel.get('symbolKeepAspect');
        var legendIconType = legendItemModel.get('icon');
        legendIcon = legendIconType || legendIcon || 'roundRect';
        var style = getLegendStyle(legendIcon, legendItemModel, lineVisualStyle, itemVisualStyle, drawType, isSelected, api);
        var itemGroup = new Group$1();
        var textStyleModel = legendItemModel.getModel('textStyle');

        if (isFunction(seriesModel.getLegendIcon) && (!legendIconType || legendIconType === 'inherit')) {
          // Series has specific way to define legend icon
          itemGroup.add(seriesModel.getLegendIcon({
            itemWidth: itemWidth,
            itemHeight: itemHeight,
            icon: legendIcon,
            iconRotate: iconRotate,
            itemStyle: style.itemStyle,
            lineStyle: style.lineStyle,
            symbolKeepAspect: symbolKeepAspect
          }));
        } else {
          // Use default legend icon policy for most series
          var rotate = legendIconType === 'inherit' && seriesModel.getData().getVisual('symbol') ? iconRotate === 'inherit' ? seriesModel.getData().getVisual('symbolRotate') : iconRotate : 0; // No rotation for no icon

          itemGroup.add(getDefaultLegendIcon({
            itemWidth: itemWidth,
            itemHeight: itemHeight,
            icon: legendIcon,
            iconRotate: rotate,
            itemStyle: style.itemStyle,
            lineStyle: style.lineStyle,
            symbolKeepAspect: symbolKeepAspect
          }));
        }

        var textX = itemAlign === 'left' ? itemWidth + 5 : -5;
        var textAlign = itemAlign;
        var formatter = legendModel.get('formatter');
        var content = name;

        if (isString(formatter) && formatter) {
          content = formatter.replace('{name}', name != null ? name : '');
        } else if (isFunction(formatter)) {
          content = formatter(name);
        }

        var inactiveColor = legendItemModel.get('inactiveColor');
        itemGroup.add(new ZRText({
          style: createTextStyle(textStyleModel, {
            text: content,
            x: textX,
            y: itemHeight / 2,
            fill: isSelected ? textStyleModel.getTextColor() : inactiveColor,
            align: textAlign,
            verticalAlign: 'middle'
          })
        })); // Add a invisible rect to increase the area of mouse hover

        var hitRect = new Rect({
          shape: itemGroup.getBoundingRect(),
          invisible: true
        });
        var tooltipModel = legendItemModel.getModel('tooltip');

        if (tooltipModel.get('show')) {
          setTooltipConfig({
            el: hitRect,
            componentModel: legendModel,
            itemName: name,
            itemTooltipOption: tooltipModel.option
          });
        }

        itemGroup.add(hitRect);
        itemGroup.eachChild(function (child) {
          child.silent = true;
        });
        hitRect.silent = !selectMode;
        this.getContentGroup().add(itemGroup);
        enableHoverEmphasis(itemGroup); // @ts-ignore

        itemGroup.__legendDataIndex = dataIndex;
        return itemGroup;
      };

      LegendView.prototype.layoutInner = function (legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition) {
        var contentGroup = this.getContentGroup();
        var selectorGroup = this.getSelectorGroup(); // Place items in contentGroup.

        box(legendModel.get('orient'), contentGroup, legendModel.get('itemGap'), maxSize.width, maxSize.height);
        var contentRect = contentGroup.getBoundingRect();
        var contentPos = [-contentRect.x, -contentRect.y];
        selectorGroup.markRedraw();
        contentGroup.markRedraw();

        if (selector) {
          // Place buttons in selectorGroup
          box( // Buttons in selectorGroup always layout horizontally
          'horizontal', selectorGroup, legendModel.get('selectorItemGap', true));
          var selectorRect = selectorGroup.getBoundingRect();
          var selectorPos = [-selectorRect.x, -selectorRect.y];
          var selectorButtonGap = legendModel.get('selectorButtonGap', true);
          var orientIdx = legendModel.getOrient().index;
          var wh = orientIdx === 0 ? 'width' : 'height';
          var hw = orientIdx === 0 ? 'height' : 'width';
          var yx = orientIdx === 0 ? 'y' : 'x';

          if (selectorPosition === 'end') {
            selectorPos[orientIdx] += contentRect[wh] + selectorButtonGap;
          } else {
            contentPos[orientIdx] += selectorRect[wh] + selectorButtonGap;
          } // Always align selector to content as 'middle'


          selectorPos[1 - orientIdx] += contentRect[hw] / 2 - selectorRect[hw] / 2;
          selectorGroup.x = selectorPos[0];
          selectorGroup.y = selectorPos[1];
          contentGroup.x = contentPos[0];
          contentGroup.y = contentPos[1];
          var mainRect = {
            x: 0,
            y: 0
          };
          mainRect[wh] = contentRect[wh] + selectorButtonGap + selectorRect[wh];
          mainRect[hw] = Math.max(contentRect[hw], selectorRect[hw]);
          mainRect[yx] = Math.min(0, selectorRect[yx] + selectorPos[1 - orientIdx]);
          return mainRect;
        } else {
          contentGroup.x = contentPos[0];
          contentGroup.y = contentPos[1];
          return this.group.getBoundingRect();
        }
      };
      /**
       * @protected
       */


      LegendView.prototype.remove = function () {
        this.getContentGroup().removeAll();
        this._isFirstRender = true;
      };

      LegendView.type = 'legend.plain';
      return LegendView;
    }(ComponentView);

    function getLegendStyle(iconType, legendItemModel, lineVisualStyle, itemVisualStyle, drawType, isSelected, api) {
      /**
       * Use series style if is inherit;
       * elsewise, use legend style
       */
      function handleCommonProps(style, visualStyle) {
        // If lineStyle.width is 'auto', it is set to be 2 if series has border
        if (style.lineWidth === 'auto') {
          style.lineWidth = visualStyle.lineWidth > 0 ? 2 : 0;
        }

        each$7(style, function (propVal, propName) {
          style[propName] === 'inherit' && (style[propName] = visualStyle[propName]);
        });
      } // itemStyle


      var itemStyleModel = legendItemModel.getModel('itemStyle');
      var itemStyle = itemStyleModel.getItemStyle();
      var iconBrushType = iconType.lastIndexOf('empty', 0) === 0 ? 'fill' : 'stroke';
      var decalStyle = itemStyleModel.getShallow('decal');
      itemStyle.decal = !decalStyle || decalStyle === 'inherit' ? itemVisualStyle.decal : createOrUpdatePatternFromDecal(decalStyle, api);

      if (itemStyle.fill === 'inherit') {
        /**
         * Series with visualDrawType as 'stroke' should have
         * series stroke as legend fill
         */
        itemStyle.fill = itemVisualStyle[drawType];
      }

      if (itemStyle.stroke === 'inherit') {
        /**
         * icon type with "emptyXXX" should use fill color
         * in visual style
         */
        itemStyle.stroke = itemVisualStyle[iconBrushType];
      }

      if (itemStyle.opacity === 'inherit') {
        /**
         * Use lineStyle.opacity if drawType is stroke
         */
        itemStyle.opacity = (drawType === 'fill' ? itemVisualStyle : lineVisualStyle).opacity;
      }

      handleCommonProps(itemStyle, itemVisualStyle); // lineStyle

      var legendLineModel = legendItemModel.getModel('lineStyle');
      var lineStyle = legendLineModel.getLineStyle();
      handleCommonProps(lineStyle, lineVisualStyle); // Fix auto color to real color

      itemStyle.fill === 'auto' && (itemStyle.fill = itemVisualStyle.fill);
      itemStyle.stroke === 'auto' && (itemStyle.stroke = itemVisualStyle.fill);
      lineStyle.stroke === 'auto' && (lineStyle.stroke = itemVisualStyle.fill);

      if (!isSelected) {
        var borderWidth = legendItemModel.get('inactiveBorderWidth');
        /**
         * Since stroke is set to be inactiveBorderColor, it may occur that
         * there is no border in series but border in legend, so we need to
         * use border only when series has border if is set to be auto
         */

        var visualHasBorder = itemStyle[iconBrushType];
        itemStyle.lineWidth = borderWidth === 'auto' ? itemVisualStyle.lineWidth > 0 && visualHasBorder ? 2 : 0 : itemStyle.lineWidth;
        itemStyle.fill = legendItemModel.get('inactiveColor');
        itemStyle.stroke = legendItemModel.get('inactiveBorderColor');
        lineStyle.stroke = legendLineModel.get('inactiveColor');
        lineStyle.lineWidth = legendLineModel.get('inactiveWidth');
      }

      return {
        itemStyle: itemStyle,
        lineStyle: lineStyle
      };
    }

    function getDefaultLegendIcon(opt) {
      var symboType = opt.icon || 'roundRect';
      var icon = createSymbol(symboType, 0, 0, opt.itemWidth, opt.itemHeight, opt.itemStyle.fill, opt.symbolKeepAspect);
      icon.setStyle(opt.itemStyle);
      icon.rotation = (opt.iconRotate || 0) * Math.PI / 180;
      icon.setOrigin([opt.itemWidth / 2, opt.itemHeight / 2]);

      if (symboType.indexOf('empty') > -1) {
        icon.style.stroke = icon.style.fill;
        icon.style.fill = '#fff';
        icon.style.lineWidth = 2;
      }

      return icon;
    }

    function dispatchSelectAction(seriesName, dataName, api, excludeSeriesId) {
      // downplay before unselect
      dispatchDownplayAction(seriesName, dataName, api, excludeSeriesId);
      api.dispatchAction({
        type: 'legendToggleSelect',
        name: seriesName != null ? seriesName : dataName
      }); // highlight after select
      // TODO highlight immediately may cause animation loss.

      dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId);
    }

    function isUseHoverLayer(api) {
      var list = api.getZr().storage.getDisplayList();
      var emphasisState;
      var i = 0;
      var len = list.length;

      while (i < len && !(emphasisState = list[i].states.emphasis)) {
        i++;
      }

      return emphasisState && emphasisState.hoverLayer;
    }

    function dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId) {
      // If element hover will move to a hoverLayer.
      if (!isUseHoverLayer(api)) {
        api.dispatchAction({
          type: 'highlight',
          seriesName: seriesName,
          name: dataName,
          excludeSeriesId: excludeSeriesId
        });
      }
    }

    function dispatchDownplayAction(seriesName, dataName, api, excludeSeriesId) {
      // If element hover will move to a hoverLayer.
      if (!isUseHoverLayer(api)) {
        api.dispatchAction({
          type: 'downplay',
          seriesName: seriesName,
          name: dataName,
          excludeSeriesId: excludeSeriesId
        });
      }
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    function legendFilter(ecModel) {
      var legendModels = ecModel.findComponents({
        mainType: 'legend'
      });

      if (legendModels && legendModels.length) {
        ecModel.filterSeries(function (series) {
          // If in any legend component the status is not selected.
          // Because in legend series is assumed selected when it is not in the legend data.
          for (var i = 0; i < legendModels.length; i++) {
            if (!legendModels[i].isSelected(series.name)) {
              return false;
            }
          }

          return true;
        });
      }
    }

    function legendSelectActionHandler(methodName, payload, ecModel) {
      var selectedMap = {};
      var isToggleSelect = methodName === 'toggleSelected';
      var isSelected; // Update all legend components

      ecModel.eachComponent('legend', function (legendModel) {
        if (isToggleSelect && isSelected != null) {
          // Force other legend has same selected status
          // Or the first is toggled to true and other are toggled to false
          // In the case one legend has some item unSelected in option. And if other legend
          // doesn't has the item, they will assume it is selected.
          legendModel[isSelected ? 'select' : 'unSelect'](payload.name);
        } else if (methodName === 'allSelect' || methodName === 'inverseSelect') {
          legendModel[methodName]();
        } else {
          legendModel[methodName](payload.name);
          isSelected = legendModel.isSelected(payload.name);
        }

        var legendData = legendModel.getData();
        each(legendData, function (model) {
          var name = model.get('name'); // Wrap element

          if (name === '\n' || name === '') {
            return;
          }

          var isItemSelected = legendModel.isSelected(name);

          if (selectedMap.hasOwnProperty(name)) {
            // Unselected if any legend is unselected
            selectedMap[name] = selectedMap[name] && isItemSelected;
          } else {
            selectedMap[name] = isItemSelected;
          }
        });
      }); // Return the event explicitly

      return methodName === 'allSelect' || methodName === 'inverseSelect' ? {
        selected: selectedMap
      } : {
        name: payload.name,
        selected: selectedMap
      };
    }

    function installLegendAction(registers) {
      /**
       * @event legendToggleSelect
       * @type {Object}
       * @property {string} type 'legendToggleSelect'
       * @property {string} [from]
       * @property {string} name Series name or data item name
       */
      registers.registerAction('legendToggleSelect', 'legendselectchanged', curry(legendSelectActionHandler, 'toggleSelected'));
      registers.registerAction('legendAllSelect', 'legendselectall', curry(legendSelectActionHandler, 'allSelect'));
      registers.registerAction('legendInverseSelect', 'legendinverseselect', curry(legendSelectActionHandler, 'inverseSelect'));
      /**
       * @event legendSelect
       * @type {Object}
       * @property {string} type 'legendSelect'
       * @property {string} name Series name or data item name
       */

      registers.registerAction('legendSelect', 'legendselected', curry(legendSelectActionHandler, 'select'));
      /**
       * @event legendUnSelect
       * @type {Object}
       * @property {string} type 'legendUnSelect'
       * @property {string} name Series name or data item name
       */

      registers.registerAction('legendUnSelect', 'legendunselected', curry(legendSelectActionHandler, 'unSelect'));
    }

    function install$h(registers) {
      registers.registerComponentModel(LegendModel);
      registers.registerComponentView(LegendView);
      registers.registerProcessor(registers.PRIORITY.PROCESSOR.SERIES_FILTER, legendFilter);
      registers.registerSubTypeDefaulter('legend', function () {
        return 'plain';
      });
      installLegendAction(registers);
    }

    var ScrollableLegendModel =
    /** @class */
    function (_super) {
      __extends(ScrollableLegendModel, _super);

      function ScrollableLegendModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ScrollableLegendModel.type;
        return _this;
      }
      /**
       * @param {number} scrollDataIndex
       */


      ScrollableLegendModel.prototype.setScrollDataIndex = function (scrollDataIndex) {
        this.option.scrollDataIndex = scrollDataIndex;
      };

      ScrollableLegendModel.prototype.init = function (option, parentModel, ecModel) {
        var inputPositionParams = getLayoutParams(option);

        _super.prototype.init.call(this, option, parentModel, ecModel);

        mergeAndNormalizeLayoutParams(this, option, inputPositionParams);
      };
      /**
       * @override
       */


      ScrollableLegendModel.prototype.mergeOption = function (option, ecModel) {
        _super.prototype.mergeOption.call(this, option, ecModel);

        mergeAndNormalizeLayoutParams(this, this.option, option);
      };

      ScrollableLegendModel.type = 'legend.scroll';
      ScrollableLegendModel.defaultOption = inheritDefaultOption(LegendModel.defaultOption, {
        scrollDataIndex: 0,
        pageButtonItemGap: 5,
        pageButtonGap: null,
        pageButtonPosition: 'end',
        pageFormatter: '{current}/{total}',
        pageIcons: {
          horizontal: ['M0,0L12,-10L12,10z', 'M0,0L-12,-10L-12,10z'],
          vertical: ['M0,0L20,0L10,-20z', 'M0,0L20,0L10,20z']
        },
        pageIconColor: '#2f4554',
        pageIconInactiveColor: '#aaa',
        pageIconSize: 15,
        pageTextStyle: {
          color: '#333'
        },
        animationDurationUpdate: 800
      });
      return ScrollableLegendModel;
    }(LegendModel);

    function mergeAndNormalizeLayoutParams(legendModel, target, raw) {
      var orient = legendModel.getOrient();
      var ignoreSize = [1, 1];
      ignoreSize[orient.index] = 0;
      mergeLayoutParam(target, raw, {
        type: 'box',
        ignoreSize: !!ignoreSize
      });
    }

    var Group$2 = Group;
    var WH = ['width', 'height'];
    var XY = ['x', 'y'];

    var ScrollableLegendView =
    /** @class */
    function (_super) {
      __extends(ScrollableLegendView, _super);

      function ScrollableLegendView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ScrollableLegendView.type;
        _this.newlineDisabled = true;
        _this._currentIndex = 0;
        return _this;
      }

      ScrollableLegendView.prototype.init = function () {
        _super.prototype.init.call(this);

        this.group.add(this._containerGroup = new Group$2());

        this._containerGroup.add(this.getContentGroup());

        this.group.add(this._controllerGroup = new Group$2());
      };
      /**
       * @override
       */


      ScrollableLegendView.prototype.resetInner = function () {
        _super.prototype.resetInner.call(this);

        this._controllerGroup.removeAll();

        this._containerGroup.removeClipPath();

        this._containerGroup.__rectSize = null;
      };
      /**
       * @override
       */


      ScrollableLegendView.prototype.renderInner = function (itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition) {
        var self = this; // Render content items.

        _super.prototype.renderInner.call(this, itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition);

        var controllerGroup = this._controllerGroup; // FIXME: support be 'auto' adapt to size number text length,
        // e.g., '3/12345' should not overlap with the control arrow button.

        var pageIconSize = legendModel.get('pageIconSize', true);
        var pageIconSizeArr = isArray(pageIconSize) ? pageIconSize : [pageIconSize, pageIconSize];
        createPageButton('pagePrev', 0);
        var pageTextStyleModel = legendModel.getModel('pageTextStyle');
        controllerGroup.add(new ZRText({
          name: 'pageText',
          style: {
            // Placeholder to calculate a proper layout.
            text: 'xx/xx',
            fill: pageTextStyleModel.getTextColor(),
            font: pageTextStyleModel.getFont(),
            verticalAlign: 'middle',
            align: 'center'
          },
          silent: true
        }));
        createPageButton('pageNext', 1);

        function createPageButton(name, iconIdx) {
          var pageDataIndexName = name + 'DataIndex';
          var icon = createIcon(legendModel.get('pageIcons', true)[legendModel.getOrient().name][iconIdx], {
            // Buttons will be created in each render, so we do not need
            // to worry about avoiding using legendModel kept in scope.
            onclick: bind(self._pageGo, self, pageDataIndexName, legendModel, api)
          }, {
            x: -pageIconSizeArr[0] / 2,
            y: -pageIconSizeArr[1] / 2,
            width: pageIconSizeArr[0],
            height: pageIconSizeArr[1]
          });
          icon.name = name;
          controllerGroup.add(icon);
        }
      };
      /**
       * @override
       */


      ScrollableLegendView.prototype.layoutInner = function (legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition) {
        var selectorGroup = this.getSelectorGroup();
        var orientIdx = legendModel.getOrient().index;
        var wh = WH[orientIdx];
        var xy = XY[orientIdx];
        var hw = WH[1 - orientIdx];
        var yx = XY[1 - orientIdx];
        selector && box( // Buttons in selectorGroup always layout horizontally
        'horizontal', selectorGroup, legendModel.get('selectorItemGap', true));
        var selectorButtonGap = legendModel.get('selectorButtonGap', true);
        var selectorRect = selectorGroup.getBoundingRect();
        var selectorPos = [-selectorRect.x, -selectorRect.y];
        var processMaxSize = clone(maxSize);
        selector && (processMaxSize[wh] = maxSize[wh] - selectorRect[wh] - selectorButtonGap);

        var mainRect = this._layoutContentAndController(legendModel, isFirstRender, processMaxSize, orientIdx, wh, hw, yx, xy);

        if (selector) {
          if (selectorPosition === 'end') {
            selectorPos[orientIdx] += mainRect[wh] + selectorButtonGap;
          } else {
            var offset = selectorRect[wh] + selectorButtonGap;
            selectorPos[orientIdx] -= offset;
            mainRect[xy] -= offset;
          }

          mainRect[wh] += selectorRect[wh] + selectorButtonGap;
          selectorPos[1 - orientIdx] += mainRect[yx] + mainRect[hw] / 2 - selectorRect[hw] / 2;
          mainRect[hw] = Math.max(mainRect[hw], selectorRect[hw]);
          mainRect[yx] = Math.min(mainRect[yx], selectorRect[yx] + selectorPos[1 - orientIdx]);
          selectorGroup.x = selectorPos[0];
          selectorGroup.y = selectorPos[1];
          selectorGroup.markRedraw();
        }

        return mainRect;
      };

      ScrollableLegendView.prototype._layoutContentAndController = function (legendModel, isFirstRender, maxSize, orientIdx, wh, hw, yx, xy) {
        var contentGroup = this.getContentGroup();
        var containerGroup = this._containerGroup;
        var controllerGroup = this._controllerGroup; // Place items in contentGroup.

        box(legendModel.get('orient'), contentGroup, legendModel.get('itemGap'), !orientIdx ? null : maxSize.width, orientIdx ? null : maxSize.height);
        box( // Buttons in controller are layout always horizontally.
        'horizontal', controllerGroup, legendModel.get('pageButtonItemGap', true));
        var contentRect = contentGroup.getBoundingRect();
        var controllerRect = controllerGroup.getBoundingRect();
        var showController = this._showController = contentRect[wh] > maxSize[wh]; // In case that the inner elements of contentGroup layout do not based on [0, 0]

        var contentPos = [-contentRect.x, -contentRect.y]; // Remain contentPos when scroll animation perfroming.
        // If first rendering, `contentGroup.position` is [0, 0], which
        // does not make sense and may cause unexepcted animation if adopted.

        if (!isFirstRender) {
          contentPos[orientIdx] = contentGroup[xy];
        } // Layout container group based on 0.


        var containerPos = [0, 0];
        var controllerPos = [-controllerRect.x, -controllerRect.y];
        var pageButtonGap = retrieve2(legendModel.get('pageButtonGap', true), legendModel.get('itemGap', true)); // Place containerGroup and controllerGroup and contentGroup.

        if (showController) {
          var pageButtonPosition = legendModel.get('pageButtonPosition', true); // controller is on the right / bottom.

          if (pageButtonPosition === 'end') {
            controllerPos[orientIdx] += maxSize[wh] - controllerRect[wh];
          } // controller is on the left / top.
          else {
              containerPos[orientIdx] += controllerRect[wh] + pageButtonGap;
            }
        } // Always align controller to content as 'middle'.


        controllerPos[1 - orientIdx] += contentRect[hw] / 2 - controllerRect[hw] / 2;
        contentGroup.setPosition(contentPos);
        containerGroup.setPosition(containerPos);
        controllerGroup.setPosition(controllerPos); // Calculate `mainRect` and set `clipPath`.
        // mainRect should not be calculated by `this.group.getBoundingRect()`
        // for sake of the overflow.

        var mainRect = {
          x: 0,
          y: 0
        }; // Consider content may be overflow (should be clipped).

        mainRect[wh] = showController ? maxSize[wh] : contentRect[wh];
        mainRect[hw] = Math.max(contentRect[hw], controllerRect[hw]); // `containerRect[yx] + containerPos[1 - orientIdx]` is 0.

        mainRect[yx] = Math.min(0, controllerRect[yx] + controllerPos[1 - orientIdx]);
        containerGroup.__rectSize = maxSize[wh];

        if (showController) {
          var clipShape = {
            x: 0,
            y: 0
          };
          clipShape[wh] = Math.max(maxSize[wh] - controllerRect[wh] - pageButtonGap, 0);
          clipShape[hw] = mainRect[hw];
          containerGroup.setClipPath(new Rect({
            shape: clipShape
          })); // Consider content may be larger than container, container rect
          // can not be obtained from `containerGroup.getBoundingRect()`.

          containerGroup.__rectSize = clipShape[wh];
        } else {
          // Do not remove or ignore controller. Keep them set as placeholders.
          controllerGroup.eachChild(function (child) {
            child.attr({
              invisible: true,
              silent: true
            });
          });
        } // Content translate animation.


        var pageInfo = this._getPageInfo(legendModel);

        pageInfo.pageIndex != null && updateProps(contentGroup, {
          x: pageInfo.contentPosition[0],
          y: pageInfo.contentPosition[1]
        }, // When switch from "show controller" to "not show controller", view should be
        // updated immediately without animation, otherwise causes weird effect.
        showController ? legendModel : null);

        this._updatePageInfoView(legendModel, pageInfo);

        return mainRect;
      };

      ScrollableLegendView.prototype._pageGo = function (to, legendModel, api) {
        var scrollDataIndex = this._getPageInfo(legendModel)[to];

        scrollDataIndex != null && api.dispatchAction({
          type: 'legendScroll',
          scrollDataIndex: scrollDataIndex,
          legendId: legendModel.id
        });
      };

      ScrollableLegendView.prototype._updatePageInfoView = function (legendModel, pageInfo) {
        var controllerGroup = this._controllerGroup;
        each(['pagePrev', 'pageNext'], function (name) {
          var key = name + 'DataIndex';
          var canJump = pageInfo[key] != null;
          var icon = controllerGroup.childOfName(name);

          if (icon) {
            icon.setStyle('fill', canJump ? legendModel.get('pageIconColor', true) : legendModel.get('pageIconInactiveColor', true));
            icon.cursor = canJump ? 'pointer' : 'default';
          }
        });
        var pageText = controllerGroup.childOfName('pageText');
        var pageFormatter = legendModel.get('pageFormatter');
        var pageIndex = pageInfo.pageIndex;
        var current = pageIndex != null ? pageIndex + 1 : 0;
        var total = pageInfo.pageCount;
        pageText && pageFormatter && pageText.setStyle('text', isString(pageFormatter) ? pageFormatter.replace('{current}', current == null ? '' : current + '').replace('{total}', total == null ? '' : total + '') : pageFormatter({
          current: current,
          total: total
        }));
      };
      /**
       *  contentPosition: Array.<number>, null when data item not found.
       *  pageIndex: number, null when data item not found.
       *  pageCount: number, always be a number, can be 0.
       *  pagePrevDataIndex: number, null when no previous page.
       *  pageNextDataIndex: number, null when no next page.
       * }
       */


      ScrollableLegendView.prototype._getPageInfo = function (legendModel) {
        var scrollDataIndex = legendModel.get('scrollDataIndex', true);
        var contentGroup = this.getContentGroup();
        var containerRectSize = this._containerGroup.__rectSize;
        var orientIdx = legendModel.getOrient().index;
        var wh = WH[orientIdx];
        var xy = XY[orientIdx];

        var targetItemIndex = this._findTargetItemIndex(scrollDataIndex);

        var children = contentGroup.children();
        var targetItem = children[targetItemIndex];
        var itemCount = children.length;
        var pCount = !itemCount ? 0 : 1;
        var result = {
          contentPosition: [contentGroup.x, contentGroup.y],
          pageCount: pCount,
          pageIndex: pCount - 1,
          pagePrevDataIndex: null,
          pageNextDataIndex: null
        };

        if (!targetItem) {
          return result;
        }

        var targetItemInfo = getItemInfo(targetItem);
        result.contentPosition[orientIdx] = -targetItemInfo.s; // Strategy:
        // (1) Always align based on the left/top most item.
        // (2) It is user-friendly that the last item shown in the
        // current window is shown at the begining of next window.
        // Otherwise if half of the last item is cut by the window,
        // it will have no chance to display entirely.
        // (3) Consider that item size probably be different, we
        // have calculate pageIndex by size rather than item index,
        // and we can not get page index directly by division.
        // (4) The window is to narrow to contain more than
        // one item, we should make sure that the page can be fliped.

        for (var i = targetItemIndex + 1, winStartItemInfo = targetItemInfo, winEndItemInfo = targetItemInfo, currItemInfo = null; i <= itemCount; ++i) {
          currItemInfo = getItemInfo(children[i]);

          if ( // Half of the last item is out of the window.
          !currItemInfo && winEndItemInfo.e > winStartItemInfo.s + containerRectSize || // If the current item does not intersect with the window, the new page
          // can be started at the current item or the last item.
          currItemInfo && !intersect(currItemInfo, winStartItemInfo.s)) {
            if (winEndItemInfo.i > winStartItemInfo.i) {
              winStartItemInfo = winEndItemInfo;
            } else {
              // e.g., when page size is smaller than item size.
              winStartItemInfo = currItemInfo;
            }

            if (winStartItemInfo) {
              if (result.pageNextDataIndex == null) {
                result.pageNextDataIndex = winStartItemInfo.i;
              }

              ++result.pageCount;
            }
          }

          winEndItemInfo = currItemInfo;
        }

        for (var i = targetItemIndex - 1, winStartItemInfo = targetItemInfo, winEndItemInfo = targetItemInfo, currItemInfo = null; i >= -1; --i) {
          currItemInfo = getItemInfo(children[i]);

          if ( // If the the end item does not intersect with the window started
          // from the current item, a page can be settled.
          (!currItemInfo || !intersect(winEndItemInfo, currItemInfo.s)) && // e.g., when page size is smaller than item size.
          winStartItemInfo.i < winEndItemInfo.i) {
            winEndItemInfo = winStartItemInfo;

            if (result.pagePrevDataIndex == null) {
              result.pagePrevDataIndex = winStartItemInfo.i;
            }

            ++result.pageCount;
            ++result.pageIndex;
          }

          winStartItemInfo = currItemInfo;
        }

        return result;

        function getItemInfo(el) {
          if (el) {
            var itemRect = el.getBoundingRect();
            var start = itemRect[xy] + el[xy];
            return {
              s: start,
              e: start + itemRect[wh],
              i: el.__legendDataIndex
            };
          }
        }

        function intersect(itemInfo, winStart) {
          return itemInfo.e >= winStart && itemInfo.s <= winStart + containerRectSize;
        }
      };

      ScrollableLegendView.prototype._findTargetItemIndex = function (targetDataIndex) {
        if (!this._showController) {
          return 0;
        }

        var index;
        var contentGroup = this.getContentGroup();
        var defaultIndex;
        contentGroup.eachChild(function (child, idx) {
          var legendDataIdx = child.__legendDataIndex; // FIXME
          // If the given targetDataIndex (from model) is illegal,
          // we use defaultIndex. But the index on the legend model and
          // action payload is still illegal. That case will not be
          // changed until some scenario requires.

          if (defaultIndex == null && legendDataIdx != null) {
            defaultIndex = idx;
          }

          if (legendDataIdx === targetDataIndex) {
            index = idx;
          }
        });
        return index != null ? index : defaultIndex;
      };

      ScrollableLegendView.type = 'legend.scroll';
      return ScrollableLegendView;
    }(LegendView);

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    function installScrollableLegendAction(registers) {
      /**
       * @event legendScroll
       * @type {Object}
       * @property {string} type 'legendScroll'
       * @property {string} scrollDataIndex
       */
      registers.registerAction('legendScroll', 'legendscroll', function (payload, ecModel) {
        var scrollDataIndex = payload.scrollDataIndex;
        scrollDataIndex != null && ecModel.eachComponent({
          mainType: 'legend',
          subType: 'scroll',
          query: payload
        }, function (legendModel) {
          legendModel.setScrollDataIndex(scrollDataIndex);
        });
      });
    }

    function install$i(registers) {
      use(install$h);
      registers.registerComponentModel(ScrollableLegendModel);
      registers.registerComponentView(ScrollableLegendView);
      installScrollableLegendAction(registers);
    }

    function install$j(registers) {
      use(install$h);
      use(install$i);
    }

    var InsideZoomModel =
    /** @class */
    function (_super) {
      __extends(InsideZoomModel, _super);

      function InsideZoomModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = InsideZoomModel.type;
        return _this;
      }

      InsideZoomModel.type = 'dataZoom.inside';
      InsideZoomModel.defaultOption = inheritDefaultOption(DataZoomModel.defaultOption, {
        disabled: false,
        zoomLock: false,
        zoomOnMouseWheel: true,
        moveOnMouseMove: true,
        moveOnMouseWheel: false,
        preventDefaultMouseMove: true
      });
      return InsideZoomModel;
    }(DataZoomModel);

    var RoamController =
    /** @class */
    function (_super) {
      __extends(RoamController, _super);

      function RoamController(zr) {
        var _this = _super.call(this) || this;

        _this._zr = zr; // Avoid two roamController bind the same handler

        var mousedownHandler = bind(_this._mousedownHandler, _this);
        var mousemoveHandler = bind(_this._mousemoveHandler, _this);
        var mouseupHandler = bind(_this._mouseupHandler, _this);
        var mousewheelHandler = bind(_this._mousewheelHandler, _this);
        var pinchHandler = bind(_this._pinchHandler, _this);
        /**
         * Notice: only enable needed types. For example, if 'zoom'
         * is not needed, 'zoom' should not be enabled, otherwise
         * default mousewheel behaviour (scroll page) will be disabled.
         */

        _this.enable = function (controlType, opt) {
          // Disable previous first
          this.disable();
          this._opt = defaults(clone(opt) || {}, {
            zoomOnMouseWheel: true,
            moveOnMouseMove: true,
            // By default, wheel do not trigger move.
            moveOnMouseWheel: false,
            preventDefaultMouseMove: true
          });

          if (controlType == null) {
            controlType = true;
          }

          if (controlType === true || controlType === 'move' || controlType === 'pan') {
            zr.on('mousedown', mousedownHandler);
            zr.on('mousemove', mousemoveHandler);
            zr.on('mouseup', mouseupHandler);
          }

          if (controlType === true || controlType === 'scale' || controlType === 'zoom') {
            zr.on('mousewheel', mousewheelHandler);
            zr.on('pinch', pinchHandler);
          }
        };

        _this.disable = function () {
          zr.off('mousedown', mousedownHandler);
          zr.off('mousemove', mousemoveHandler);
          zr.off('mouseup', mouseupHandler);
          zr.off('mousewheel', mousewheelHandler);
          zr.off('pinch', pinchHandler);
        };

        return _this;
      }

      RoamController.prototype.isDragging = function () {
        return this._dragging;
      };

      RoamController.prototype.isPinching = function () {
        return this._pinching;
      };

      RoamController.prototype.setPointerChecker = function (pointerChecker) {
        this.pointerChecker = pointerChecker;
      };

      RoamController.prototype.dispose = function () {
        this.disable();
      };

      RoamController.prototype._mousedownHandler = function (e) {
        if (isMiddleOrRightButtonOnMouseUpDown(e)) {
          return;
        }

        var el = e.target;

        while (el) {
          if (el.draggable) {
            return;
          } // check if host is draggable


          el = el.__hostTarget || el.parent;
        }

        var x = e.offsetX;
        var y = e.offsetY; // Only check on mosedown, but not mousemove.
        // Mouse can be out of target when mouse moving.

        if (this.pointerChecker && this.pointerChecker(e, x, y)) {
          this._x = x;
          this._y = y;
          this._dragging = true;
        }
      };

      RoamController.prototype._mousemoveHandler = function (e) {
        if (!this._dragging || !isAvailableBehavior('moveOnMouseMove', e, this._opt) || e.gestureEvent === 'pinch' || isTaken(this._zr, 'globalPan')) {
          return;
        }

        var x = e.offsetX;
        var y = e.offsetY;
        var oldX = this._x;
        var oldY = this._y;
        var dx = x - oldX;
        var dy = y - oldY;
        this._x = x;
        this._y = y;
        this._opt.preventDefaultMouseMove && stop(e.event);
        trigger$1(this, 'pan', 'moveOnMouseMove', e, {
          dx: dx,
          dy: dy,
          oldX: oldX,
          oldY: oldY,
          newX: x,
          newY: y,
          isAvailableBehavior: null
        });
      };

      RoamController.prototype._mouseupHandler = function (e) {
        if (!isMiddleOrRightButtonOnMouseUpDown(e)) {
          this._dragging = false;
        }
      };

      RoamController.prototype._mousewheelHandler = function (e) {
        var shouldZoom = isAvailableBehavior('zoomOnMouseWheel', e, this._opt);
        var shouldMove = isAvailableBehavior('moveOnMouseWheel', e, this._opt);
        var wheelDelta = e.wheelDelta;
        var absWheelDeltaDelta = Math.abs(wheelDelta);
        var originX = e.offsetX;
        var originY = e.offsetY; // wheelDelta maybe -0 in chrome mac.

        if (wheelDelta === 0 || !shouldZoom && !shouldMove) {
          return;
        } // If both `shouldZoom` and `shouldMove` is true, trigger
        // their event both, and the final behavior is determined
        // by event listener themselves.


        if (shouldZoom) {
          // Convenience:
          // Mac and VM Windows on Mac: scroll up: zoom out.
          // Windows: scroll up: zoom in.
          // FIXME: Should do more test in different environment.
          // wheelDelta is too complicated in difference nvironment
          // (https://developer.mozilla.org/en-US/docs/Web/Events/mousewheel),
          // although it has been normallized by zrender.
          // wheelDelta of mouse wheel is bigger than touch pad.
          var factor = absWheelDeltaDelta > 3 ? 1.4 : absWheelDeltaDelta > 1 ? 1.2 : 1.1;
          var scale = wheelDelta > 0 ? factor : 1 / factor;
          checkPointerAndTrigger(this, 'zoom', 'zoomOnMouseWheel', e, {
            scale: scale,
            originX: originX,
            originY: originY,
            isAvailableBehavior: null
          });
        }

        if (shouldMove) {
          // FIXME: Should do more test in different environment.
          var absDelta = Math.abs(wheelDelta); // wheelDelta of mouse wheel is bigger than touch pad.

          var scrollDelta = (wheelDelta > 0 ? 1 : -1) * (absDelta > 3 ? 0.4 : absDelta > 1 ? 0.15 : 0.05);
          checkPointerAndTrigger(this, 'scrollMove', 'moveOnMouseWheel', e, {
            scrollDelta: scrollDelta,
            originX: originX,
            originY: originY,
            isAvailableBehavior: null
          });
        }
      };

      RoamController.prototype._pinchHandler = function (e) {
        if (isTaken(this._zr, 'globalPan')) {
          return;
        }

        var scale = e.pinchScale > 1 ? 1.1 : 1 / 1.1;
        checkPointerAndTrigger(this, 'zoom', null, e, {
          scale: scale,
          originX: e.pinchX,
          originY: e.pinchY,
          isAvailableBehavior: null
        });
      };

      return RoamController;
    }(Eventful);

    function checkPointerAndTrigger(controller, eventName, behaviorToCheck, e, contollerEvent) {
      if (controller.pointerChecker && controller.pointerChecker(e, contollerEvent.originX, contollerEvent.originY)) {
        // When mouse is out of roamController rect,
        // default befavoius should not be be disabled, otherwise
        // page sliding is disabled, contrary to expectation.
        stop(e.event);
        trigger$1(controller, eventName, behaviorToCheck, e, contollerEvent);
      }
    }

    function trigger$1(controller, eventName, behaviorToCheck, e, contollerEvent) {
      // Also provide behavior checker for event listener, for some case that
      // multiple components share one listener.
      contollerEvent.isAvailableBehavior = bind(isAvailableBehavior, null, behaviorToCheck, e); // TODO should not have type issue.

      controller.trigger(eventName, contollerEvent);
    } // settings: {
    //     zoomOnMouseWheel
    //     moveOnMouseMove
    //     moveOnMouseWheel
    // }
    // The value can be: true / false / 'shift' / 'ctrl' / 'alt'.


    function isAvailableBehavior(behaviorToCheck, e, settings) {
      var setting = settings[behaviorToCheck];
      return !behaviorToCheck || setting && (!isString(setting) || e.event[setting + 'Key']);
    }

    var inner$g = makeInner();
    function setViewInfoToCoordSysRecord(api, dataZoomModel, getRange) {
      inner$g(api).coordSysRecordMap.each(function (coordSysRecord) {
        var dzInfo = coordSysRecord.dataZoomInfoMap.get(dataZoomModel.uid);

        if (dzInfo) {
          dzInfo.getRange = getRange;
        }
      });
    }
    function disposeCoordSysRecordIfNeeded(api, dataZoomModel) {
      var coordSysRecordMap = inner$g(api).coordSysRecordMap;
      var coordSysKeyArr = coordSysRecordMap.keys();

      for (var i = 0; i < coordSysKeyArr.length; i++) {
        var coordSysKey = coordSysKeyArr[i];
        var coordSysRecord = coordSysRecordMap.get(coordSysKey);
        var dataZoomInfoMap = coordSysRecord.dataZoomInfoMap;

        if (dataZoomInfoMap) {
          var dzUid = dataZoomModel.uid;
          var dzInfo = dataZoomInfoMap.get(dzUid);

          if (dzInfo) {
            dataZoomInfoMap.removeKey(dzUid);

            if (!dataZoomInfoMap.keys().length) {
              disposeCoordSysRecord(coordSysRecordMap, coordSysRecord);
            }
          }
        }
      }
    }

    function disposeCoordSysRecord(coordSysRecordMap, coordSysRecord) {
      if (coordSysRecord) {
        coordSysRecordMap.removeKey(coordSysRecord.model.uid);
        var controller = coordSysRecord.controller;
        controller && controller.dispose();
      }
    }

    function createCoordSysRecord(api, coordSysModel) {
      // These init props will never change after record created.
      var coordSysRecord = {
        model: coordSysModel,
        containsPoint: curry(containsPoint, coordSysModel),
        dispatchAction: curry(dispatchAction, api),
        dataZoomInfoMap: null,
        controller: null
      }; // Must not do anything depends on coordSysRecord outside the event handler here,
      // because coordSysRecord not completed yet.

      var controller = coordSysRecord.controller = new RoamController(api.getZr());
      each(['pan', 'zoom', 'scrollMove'], function (eventName) {
        controller.on(eventName, function (event) {
          var batch = [];
          coordSysRecord.dataZoomInfoMap.each(function (dzInfo) {
            // Check whether the behaviors (zoomOnMouseWheel, moveOnMouseMove,
            // moveOnMouseWheel, ...) enabled.
            if (!event.isAvailableBehavior(dzInfo.model.option)) {
              return;
            }

            var method = (dzInfo.getRange || {})[eventName];
            var range = method && method(dzInfo.dzReferCoordSysInfo, coordSysRecord.model.mainType, coordSysRecord.controller, event);
            !dzInfo.model.get('disabled', true) && range && batch.push({
              dataZoomId: dzInfo.model.id,
              start: range[0],
              end: range[1]
            });
          });
          batch.length && coordSysRecord.dispatchAction(batch);
        });
      });
      return coordSysRecord;
    }
    /**
     * This action will be throttled.
     */


    function dispatchAction(api, batch) {
      if (!api.isDisposed()) {
        api.dispatchAction({
          type: 'dataZoom',
          animation: {
            easing: 'cubicOut',
            duration: 100
          },
          batch: batch
        });
      }
    }

    function containsPoint(coordSysModel, e, x, y) {
      return coordSysModel.coordinateSystem.containPoint([x, y]);
    }
    /**
     * Merge roamController settings when multiple dataZooms share one roamController.
     */


    function mergeControllerParams(dataZoomInfoMap) {
      var controlType; // DO NOT use reserved word (true, false, undefined) as key literally. Even if encapsulated
      // as string, it is probably revert to reserved word by compress tool. See #7411.

      var prefix = 'type_';
      var typePriority = {
        'type_true': 2,
        'type_move': 1,
        'type_false': 0,
        'type_undefined': -1
      };
      var preventDefaultMouseMove = true;
      dataZoomInfoMap.each(function (dataZoomInfo) {
        var dataZoomModel = dataZoomInfo.model;
        var oneType = dataZoomModel.get('disabled', true) ? false : dataZoomModel.get('zoomLock', true) ? 'move' : true;

        if (typePriority[prefix + oneType] > typePriority[prefix + controlType]) {
          controlType = oneType;
        } // Prevent default move event by default. If one false, do not prevent. Otherwise
        // users may be confused why it does not work when multiple insideZooms exist.


        preventDefaultMouseMove = preventDefaultMouseMove && dataZoomModel.get('preventDefaultMouseMove', true);
      });
      return {
        controlType: controlType,
        opt: {
          // RoamController will enable all of these functionalities,
          // and the final behavior is determined by its event listener
          // provided by each inside zoom.
          zoomOnMouseWheel: true,
          moveOnMouseMove: true,
          moveOnMouseWheel: true,
          preventDefaultMouseMove: !!preventDefaultMouseMove
        }
      };
    }

    function installDataZoomRoamProcessor(registers) {
      registers.registerProcessor(registers.PRIORITY.PROCESSOR.FILTER, function (ecModel, api) {
        var apiInner = inner$g(api);
        var coordSysRecordMap = apiInner.coordSysRecordMap || (apiInner.coordSysRecordMap = createHashMap());
        coordSysRecordMap.each(function (coordSysRecord) {
          // `coordSysRecordMap` always exists (because it holds the `roam controller`, which should
          // better not re-create each time), but clear `dataZoomInfoMap` each round of the workflow.
          coordSysRecord.dataZoomInfoMap = null;
        });
        ecModel.eachComponent({
          mainType: 'dataZoom',
          subType: 'inside'
        }, function (dataZoomModel) {
          var dzReferCoordSysWrap = collectReferCoordSysModelInfo(dataZoomModel);
          each(dzReferCoordSysWrap.infoList, function (dzCoordSysInfo) {
            var coordSysUid = dzCoordSysInfo.model.uid;
            var coordSysRecord = coordSysRecordMap.get(coordSysUid) || coordSysRecordMap.set(coordSysUid, createCoordSysRecord(api, dzCoordSysInfo.model));
            var dataZoomInfoMap = coordSysRecord.dataZoomInfoMap || (coordSysRecord.dataZoomInfoMap = createHashMap()); // Notice these props might be changed each time for a single dataZoomModel.

            dataZoomInfoMap.set(dataZoomModel.uid, {
              dzReferCoordSysInfo: dzCoordSysInfo,
              model: dataZoomModel,
              getRange: null
            });
          });
        }); // (1) Merge dataZoom settings for each coord sys and set to the roam controller.
        // (2) Clear coord sys if not refered by any dataZoom.

        coordSysRecordMap.each(function (coordSysRecord) {
          var controller = coordSysRecord.controller;
          var firstDzInfo;
          var dataZoomInfoMap = coordSysRecord.dataZoomInfoMap;

          if (dataZoomInfoMap) {
            var firstDzKey = dataZoomInfoMap.keys()[0];

            if (firstDzKey != null) {
              firstDzInfo = dataZoomInfoMap.get(firstDzKey);
            }
          }

          if (!firstDzInfo) {
            disposeCoordSysRecord(coordSysRecordMap, coordSysRecord);
            return;
          }

          var controllerParams = mergeControllerParams(dataZoomInfoMap);
          controller.enable(controllerParams.controlType, controllerParams.opt);
          controller.setPointerChecker(coordSysRecord.containsPoint);
          createOrUpdate(coordSysRecord, 'dispatchAction', firstDzInfo.model.get('throttle', true), 'fixRate');
        });
      });
    }

    var InsideZoomView =
    /** @class */
    function (_super) {
      __extends(InsideZoomView, _super);

      function InsideZoomView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'dataZoom.inside';
        return _this;
      }

      InsideZoomView.prototype.render = function (dataZoomModel, ecModel, api) {
        _super.prototype.render.apply(this, arguments);

        if (dataZoomModel.noTarget()) {
          this._clear();

          return;
        } // Hence the `throttle` util ensures to preserve command order,
        // here simply updating range all the time will not cause missing
        // any of the the roam change.


        this.range = dataZoomModel.getPercentRange(); // Reset controllers.

        setViewInfoToCoordSysRecord(api, dataZoomModel, {
          pan: bind(getRangeHandlers.pan, this),
          zoom: bind(getRangeHandlers.zoom, this),
          scrollMove: bind(getRangeHandlers.scrollMove, this)
        });
      };

      InsideZoomView.prototype.dispose = function () {
        this._clear();

        _super.prototype.dispose.apply(this, arguments);
      };

      InsideZoomView.prototype._clear = function () {
        disposeCoordSysRecordIfNeeded(this.api, this.dataZoomModel);
        this.range = null;
      };

      InsideZoomView.type = 'dataZoom.inside';
      return InsideZoomView;
    }(DataZoomView);

    var getRangeHandlers = {
      zoom: function (coordSysInfo, coordSysMainType, controller, e) {
        var lastRange = this.range;
        var range = lastRange.slice(); // Calculate transform by the first axis.

        var axisModel = coordSysInfo.axisModels[0];

        if (!axisModel) {
          return;
        }

        var directionInfo = getDirectionInfo[coordSysMainType](null, [e.originX, e.originY], axisModel, controller, coordSysInfo);
        var percentPoint = (directionInfo.signal > 0 ? directionInfo.pixelStart + directionInfo.pixelLength - directionInfo.pixel : directionInfo.pixel - directionInfo.pixelStart) / directionInfo.pixelLength * (range[1] - range[0]) + range[0];
        var scale = Math.max(1 / e.scale, 0);
        range[0] = (range[0] - percentPoint) * scale + percentPoint;
        range[1] = (range[1] - percentPoint) * scale + percentPoint; // Restrict range.

        var minMaxSpan = this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();
        sliderMove(0, range, [0, 100], 0, minMaxSpan.minSpan, minMaxSpan.maxSpan);
        this.range = range;

        if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) {
          return range;
        }
      },
      pan: makeMover(function (range, axisModel, coordSysInfo, coordSysMainType, controller, e) {
        var directionInfo = getDirectionInfo[coordSysMainType]([e.oldX, e.oldY], [e.newX, e.newY], axisModel, controller, coordSysInfo);
        return directionInfo.signal * (range[1] - range[0]) * directionInfo.pixel / directionInfo.pixelLength;
      }),
      scrollMove: makeMover(function (range, axisModel, coordSysInfo, coordSysMainType, controller, e) {
        var directionInfo = getDirectionInfo[coordSysMainType]([0, 0], [e.scrollDelta, e.scrollDelta], axisModel, controller, coordSysInfo);
        return directionInfo.signal * (range[1] - range[0]) * e.scrollDelta;
      })
    };

    function makeMover(getPercentDelta) {
      return function (coordSysInfo, coordSysMainType, controller, e) {
        var lastRange = this.range;
        var range = lastRange.slice(); // Calculate transform by the first axis.

        var axisModel = coordSysInfo.axisModels[0];

        if (!axisModel) {
          return;
        }

        var percentDelta = getPercentDelta(range, axisModel, coordSysInfo, coordSysMainType, controller, e);
        sliderMove(percentDelta, range, [0, 100], 'all');
        this.range = range;

        if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) {
          return range;
        }
      };
    }

    var getDirectionInfo = {
      grid: function (oldPoint, newPoint, axisModel, controller, coordSysInfo) {
        var axis = axisModel.axis;
        var ret = {};
        var rect = coordSysInfo.model.coordinateSystem.getRect();
        oldPoint = oldPoint || [0, 0];

        if (axis.dim === 'x') {
          ret.pixel = newPoint[0] - oldPoint[0];
          ret.pixelLength = rect.width;
          ret.pixelStart = rect.x;
          ret.signal = axis.inverse ? 1 : -1;
        } else {
          // axis.dim === 'y'
          ret.pixel = newPoint[1] - oldPoint[1];
          ret.pixelLength = rect.height;
          ret.pixelStart = rect.y;
          ret.signal = axis.inverse ? -1 : 1;
        }

        return ret;
      },
      polar: function (oldPoint, newPoint, axisModel, controller, coordSysInfo) {
        var axis = axisModel.axis;
        var ret = {};
        var polar = coordSysInfo.model.coordinateSystem;
        var radiusExtent = polar.getRadiusAxis().getExtent();
        var angleExtent = polar.getAngleAxis().getExtent();
        oldPoint = oldPoint ? polar.pointToCoord(oldPoint) : [0, 0];
        newPoint = polar.pointToCoord(newPoint);

        if (axisModel.mainType === 'radiusAxis') {
          ret.pixel = newPoint[0] - oldPoint[0]; // ret.pixelLength = Math.abs(radiusExtent[1] - radiusExtent[0]);
          // ret.pixelStart = Math.min(radiusExtent[0], radiusExtent[1]);

          ret.pixelLength = radiusExtent[1] - radiusExtent[0];
          ret.pixelStart = radiusExtent[0];
          ret.signal = axis.inverse ? 1 : -1;
        } else {
          // 'angleAxis'
          ret.pixel = newPoint[1] - oldPoint[1]; // ret.pixelLength = Math.abs(angleExtent[1] - angleExtent[0]);
          // ret.pixelStart = Math.min(angleExtent[0], angleExtent[1]);

          ret.pixelLength = angleExtent[1] - angleExtent[0];
          ret.pixelStart = angleExtent[0];
          ret.signal = axis.inverse ? -1 : 1;
        }

        return ret;
      },
      singleAxis: function (oldPoint, newPoint, axisModel, controller, coordSysInfo) {
        var axis = axisModel.axis;
        var rect = coordSysInfo.model.coordinateSystem.getRect();
        var ret = {};
        oldPoint = oldPoint || [0, 0];

        if (axis.orient === 'horizontal') {
          ret.pixel = newPoint[0] - oldPoint[0];
          ret.pixelLength = rect.width;
          ret.pixelStart = rect.x;
          ret.signal = axis.inverse ? 1 : -1;
        } else {
          // 'vertical'
          ret.pixel = newPoint[1] - oldPoint[1];
          ret.pixelLength = rect.height;
          ret.pixelStart = rect.y;
          ret.signal = axis.inverse ? -1 : 1;
        }

        return ret;
      }
    };

    function install$k(registers) {
      installCommon(registers);
      registers.registerComponentModel(InsideZoomModel);
      registers.registerComponentView(InsideZoomView);
      installDataZoomRoamProcessor(registers);
    }

    var SliderZoomModel =
    /** @class */
    function (_super) {
      __extends(SliderZoomModel, _super);

      function SliderZoomModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SliderZoomModel.type;
        return _this;
      }

      SliderZoomModel.type = 'dataZoom.slider';
      SliderZoomModel.layoutMode = 'box';
      SliderZoomModel.defaultOption = inheritDefaultOption(DataZoomModel.defaultOption, {
        show: true,
        // deault value can only be drived in view stage.
        right: 'ph',
        top: 'ph',
        width: 'ph',
        height: 'ph',
        left: null,
        bottom: null,
        borderColor: '#d2dbee',
        borderRadius: 3,
        backgroundColor: 'rgba(47,69,84,0)',
        // dataBackgroundColor: '#ddd',
        dataBackground: {
          lineStyle: {
            color: '#d2dbee',
            width: 0.5
          },
          areaStyle: {
            color: '#d2dbee',
            opacity: 0.2
          }
        },
        selectedDataBackground: {
          lineStyle: {
            color: '#8fb0f7',
            width: 0.5
          },
          areaStyle: {
            color: '#8fb0f7',
            opacity: 0.2
          }
        },
        // Color of selected window.
        fillerColor: 'rgba(135,175,274,0.2)',
        handleIcon: 'path://M-9.35,34.56V42m0-40V9.5m-2,0h4a2,2,0,0,1,2,2v21a2,2,0,0,1-2,2h-4a2,2,0,0,1-2-2v-21A2,2,0,0,1-11.35,9.5Z',
        // Percent of the slider height
        handleSize: '100%',
        handleStyle: {
          color: '#fff',
          borderColor: '#ACB8D1'
        },
        moveHandleSize: 7,
        moveHandleIcon: 'path://M-320.9-50L-320.9-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-348-41-339-50-320.9-50z M-212.3-50L-212.3-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-239.4-41-230.4-50-212.3-50z M-103.7-50L-103.7-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-130.9-41-121.8-50-103.7-50z',
        moveHandleStyle: {
          color: '#D2DBEE',
          opacity: 0.7
        },
        showDetail: true,
        showDataShadow: 'auto',
        realtime: true,
        zoomLock: false,
        textStyle: {
          color: '#6E7079'
        },
        brushSelect: true,
        brushStyle: {
          color: 'rgba(135,175,274,0.15)'
        },
        emphasis: {
          handleStyle: {
            borderColor: '#8FB0F7'
          },
          moveHandleStyle: {
            color: '#8FB0F7'
          }
        }
      });
      return SliderZoomModel;
    }(DataZoomModel);

    var Rect$1 = Rect; // Constants

    var DEFAULT_LOCATION_EDGE_GAP = 7;
    var DEFAULT_FRAME_BORDER_WIDTH = 1;
    var DEFAULT_FILLER_SIZE = 30;
    var DEFAULT_MOVE_HANDLE_SIZE = 7;
    var HORIZONTAL = 'horizontal';
    var VERTICAL = 'vertical';
    var LABEL_GAP = 5;
    var SHOW_DATA_SHADOW_SERIES_TYPE = ['line', 'bar', 'candlestick', 'scatter'];
    var REALTIME_ANIMATION_CONFIG = {
      easing: 'cubicOut',
      duration: 100,
      delay: 0
    };

    var SliderZoomView =
    /** @class */
    function (_super) {
      __extends(SliderZoomView, _super);

      function SliderZoomView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SliderZoomView.type;
        _this._displayables = {};
        return _this;
      }

      SliderZoomView.prototype.init = function (ecModel, api) {
        this.api = api; // A unique handler for each dataZoom component

        this._onBrush = bind(this._onBrush, this);
        this._onBrushEnd = bind(this._onBrushEnd, this);
      };

      SliderZoomView.prototype.render = function (dataZoomModel, ecModel, api, payload) {
        _super.prototype.render.apply(this, arguments);

        createOrUpdate(this, '_dispatchZoomAction', dataZoomModel.get('throttle'), 'fixRate');
        this._orient = dataZoomModel.getOrient();

        if (dataZoomModel.get('show') === false) {
          this.group.removeAll();
          return;
        }

        if (dataZoomModel.noTarget()) {
          this._clear();

          this.group.removeAll();
          return;
        } // Notice: this._resetInterval() should not be executed when payload.type
        // is 'dataZoom', origin this._range should be maintained, otherwise 'pan'
        // or 'zoom' info will be missed because of 'throttle' of this.dispatchAction,


        if (!payload || payload.type !== 'dataZoom' || payload.from !== this.uid) {
          this._buildView();
        }

        this._updateView();
      };

      SliderZoomView.prototype.dispose = function () {
        this._clear();

        _super.prototype.dispose.apply(this, arguments);
      };

      SliderZoomView.prototype._clear = function () {
        clear(this, '_dispatchZoomAction');
        var zr = this.api.getZr();
        zr.off('mousemove', this._onBrush);
        zr.off('mouseup', this._onBrushEnd);
      };

      SliderZoomView.prototype._buildView = function () {
        var thisGroup = this.group;
        thisGroup.removeAll();
        this._brushing = false;
        this._displayables.brushRect = null;

        this._resetLocation();

        this._resetInterval();

        var barGroup = this._displayables.sliderGroup = new Group();

        this._renderBackground();

        this._renderHandle();

        this._renderDataShadow();

        thisGroup.add(barGroup);

        this._positionGroup();
      };

      SliderZoomView.prototype._resetLocation = function () {
        var dataZoomModel = this.dataZoomModel;
        var api = this.api;
        var showMoveHandle = dataZoomModel.get('brushSelect');
        var moveHandleSize = showMoveHandle ? DEFAULT_MOVE_HANDLE_SIZE : 0; // If some of x/y/width/height are not specified,
        // auto-adapt according to target grid.

        var coordRect = this._findCoordRect();

        var ecSize = {
          width: api.getWidth(),
          height: api.getHeight()
        }; // Default align by coordinate system rect.

        var positionInfo = this._orient === HORIZONTAL ? {
          // Why using 'right', because right should be used in vertical,
          // and it is better to be consistent for dealing with position param merge.
          right: ecSize.width - coordRect.x - coordRect.width,
          top: ecSize.height - DEFAULT_FILLER_SIZE - DEFAULT_LOCATION_EDGE_GAP - moveHandleSize,
          width: coordRect.width,
          height: DEFAULT_FILLER_SIZE
        } : {
          right: DEFAULT_LOCATION_EDGE_GAP,
          top: coordRect.y,
          width: DEFAULT_FILLER_SIZE,
          height: coordRect.height
        }; // Do not write back to option and replace value 'ph', because
        // the 'ph' value should be recalculated when resize.

        var layoutParams = getLayoutParams(dataZoomModel.option); // Replace the placeholder value.

        each(['right', 'top', 'width', 'height'], function (name) {
          if (layoutParams[name] === 'ph') {
            layoutParams[name] = positionInfo[name];
          }
        });
        var layoutRect = getLayoutRect(layoutParams, ecSize);
        this._location = {
          x: layoutRect.x,
          y: layoutRect.y
        };
        this._size = [layoutRect.width, layoutRect.height];
        this._orient === VERTICAL && this._size.reverse();
      };

      SliderZoomView.prototype._positionGroup = function () {
        var thisGroup = this.group;
        var location = this._location;
        var orient = this._orient; // Just use the first axis to determine mapping.

        var targetAxisModel = this.dataZoomModel.getFirstTargetAxisModel();
        var inverse = targetAxisModel && targetAxisModel.get('inverse');
        var sliderGroup = this._displayables.sliderGroup;
        var otherAxisInverse = (this._dataShadowInfo || {}).otherAxisInverse; // Transform barGroup.

        sliderGroup.attr(orient === HORIZONTAL && !inverse ? {
          scaleY: otherAxisInverse ? 1 : -1,
          scaleX: 1
        } : orient === HORIZONTAL && inverse ? {
          scaleY: otherAxisInverse ? 1 : -1,
          scaleX: -1
        } : orient === VERTICAL && !inverse ? {
          scaleY: otherAxisInverse ? -1 : 1,
          scaleX: 1,
          rotation: Math.PI / 2
        } // Dont use Math.PI, considering shadow direction.
        : {
          scaleY: otherAxisInverse ? -1 : 1,
          scaleX: -1,
          rotation: Math.PI / 2
        }); // Position barGroup

        var rect = thisGroup.getBoundingRect([sliderGroup]);
        thisGroup.x = location.x - rect.x;
        thisGroup.y = location.y - rect.y;
        thisGroup.markRedraw();
      };

      SliderZoomView.prototype._getViewExtent = function () {
        return [0, this._size[0]];
      };

      SliderZoomView.prototype._renderBackground = function () {
        var dataZoomModel = this.dataZoomModel;
        var size = this._size;
        var barGroup = this._displayables.sliderGroup;
        var brushSelect = dataZoomModel.get('brushSelect');
        barGroup.add(new Rect$1({
          silent: true,
          shape: {
            x: 0,
            y: 0,
            width: size[0],
            height: size[1]
          },
          style: {
            fill: dataZoomModel.get('backgroundColor')
          },
          z2: -40
        })); // Click panel, over shadow, below handles.

        var clickPanel = new Rect$1({
          shape: {
            x: 0,
            y: 0,
            width: size[0],
            height: size[1]
          },
          style: {
            fill: 'transparent'
          },
          z2: 0,
          onclick: bind(this._onClickPanel, this)
        });
        var zr = this.api.getZr();

        if (brushSelect) {
          clickPanel.on('mousedown', this._onBrushStart, this);
          clickPanel.cursor = 'crosshair';
          zr.on('mousemove', this._onBrush);
          zr.on('mouseup', this._onBrushEnd);
        } else {
          zr.off('mousemove', this._onBrush);
          zr.off('mouseup', this._onBrushEnd);
        }

        barGroup.add(clickPanel);
      };

      SliderZoomView.prototype._renderDataShadow = function () {
        var info = this._dataShadowInfo = this._prepareDataShadowInfo();

        this._displayables.dataShadowSegs = [];

        if (!info) {
          return;
        }

        var size = this._size;
        var oldSize = this._shadowSize || [];
        var seriesModel = info.series;
        var data = seriesModel.getRawData();
        var candlestickDim = seriesModel.getShadowDim && seriesModel.getShadowDim();
        var otherDim = candlestickDim && data.getDimensionInfo(candlestickDim) ? seriesModel.getShadowDim() // @see candlestick
        : info.otherDim;

        if (otherDim == null) {
          return;
        }

        var polygonPts = this._shadowPolygonPts;
        var polylinePts = this._shadowPolylinePts; // Not re-render if data doesn't change.

        if (data !== this._shadowData || otherDim !== this._shadowDim || size[0] !== oldSize[0] || size[1] !== oldSize[1]) {
          var otherDataExtent_1 = data.getDataExtent(otherDim); // Nice extent.

          var otherOffset = (otherDataExtent_1[1] - otherDataExtent_1[0]) * 0.3;
          otherDataExtent_1 = [otherDataExtent_1[0] - otherOffset, otherDataExtent_1[1] + otherOffset];
          var otherShadowExtent_1 = [0, size[1]];
          var thisShadowExtent = [0, size[0]];
          var areaPoints_1 = [[size[0], 0], [0, 0]];
          var linePoints_1 = [];
          var step_1 = thisShadowExtent[1] / (data.count() - 1);
          var thisCoord_1 = 0; // Optimize for large data shadow

          var stride_1 = Math.round(data.count() / size[0]);
          var lastIsEmpty_1;
          data.each([otherDim], function (value, index) {
            if (stride_1 > 0 && index % stride_1) {
              thisCoord_1 += step_1;
              return;
            } // FIXME
            // Should consider axis.min/axis.max when drawing dataShadow.
            // FIXME
            // 应该使用统一的空判断？还是在list里进行空判断？


            var isEmpty = value == null || isNaN(value) || value === ''; // See #4235.

            var otherCoord = isEmpty ? 0 : linearMap(value, otherDataExtent_1, otherShadowExtent_1, true); // Attempt to draw data shadow precisely when there are empty value.

            if (isEmpty && !lastIsEmpty_1 && index) {
              areaPoints_1.push([areaPoints_1[areaPoints_1.length - 1][0], 0]);
              linePoints_1.push([linePoints_1[linePoints_1.length - 1][0], 0]);
            } else if (!isEmpty && lastIsEmpty_1) {
              areaPoints_1.push([thisCoord_1, 0]);
              linePoints_1.push([thisCoord_1, 0]);
            }

            areaPoints_1.push([thisCoord_1, otherCoord]);
            linePoints_1.push([thisCoord_1, otherCoord]);
            thisCoord_1 += step_1;
            lastIsEmpty_1 = isEmpty;
          });
          polygonPts = this._shadowPolygonPts = areaPoints_1;
          polylinePts = this._shadowPolylinePts = linePoints_1;
        }

        this._shadowData = data;
        this._shadowDim = otherDim;
        this._shadowSize = [size[0], size[1]];
        var dataZoomModel = this.dataZoomModel;

        function createDataShadowGroup(isSelectedArea) {
          var model = dataZoomModel.getModel(isSelectedArea ? 'selectedDataBackground' : 'dataBackground');
          var group = new Group();
          var polygon = new Polygon({
            shape: {
              points: polygonPts
            },
            segmentIgnoreThreshold: 1,
            style: model.getModel('areaStyle').getAreaStyle(),
            silent: true,
            z2: -20
          });
          var polyline = new Polyline({
            shape: {
              points: polylinePts
            },
            segmentIgnoreThreshold: 1,
            style: model.getModel('lineStyle').getLineStyle(),
            silent: true,
            z2: -19
          });
          group.add(polygon);
          group.add(polyline);
          return group;
        } // let dataBackgroundModel = dataZoomModel.getModel('dataBackground');


        for (var i = 0; i < 3; i++) {
          var group = createDataShadowGroup(i === 1);

          this._displayables.sliderGroup.add(group);

          this._displayables.dataShadowSegs.push(group);
        }
      };

      SliderZoomView.prototype._prepareDataShadowInfo = function () {
        var dataZoomModel = this.dataZoomModel;
        var showDataShadow = dataZoomModel.get('showDataShadow');

        if (showDataShadow === false) {
          return;
        } // Find a representative series.


        var result;
        var ecModel = this.ecModel;
        dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
          var seriesModels = dataZoomModel.getAxisProxy(axisDim, axisIndex).getTargetSeriesModels();
          each(seriesModels, function (seriesModel) {
            if (result) {
              return;
            }

            if (showDataShadow !== true && indexOf(SHOW_DATA_SHADOW_SERIES_TYPE, seriesModel.get('type')) < 0) {
              return;
            }

            var thisAxis = ecModel.getComponent(getAxisMainType(axisDim), axisIndex).axis;
            var otherDim = getOtherDim(axisDim);
            var otherAxisInverse;
            var coordSys = seriesModel.coordinateSystem;

            if (otherDim != null && coordSys.getOtherAxis) {
              otherAxisInverse = coordSys.getOtherAxis(thisAxis).inverse;
            }

            otherDim = seriesModel.getData().mapDimension(otherDim);
            result = {
              thisAxis: thisAxis,
              series: seriesModel,
              thisDim: axisDim,
              otherDim: otherDim,
              otherAxisInverse: otherAxisInverse
            };
          }, this);
        }, this);
        return result;
      };

      SliderZoomView.prototype._renderHandle = function () {
        var thisGroup = this.group;
        var displayables = this._displayables;
        var handles = displayables.handles = [null, null];
        var handleLabels = displayables.handleLabels = [null, null];
        var sliderGroup = this._displayables.sliderGroup;
        var size = this._size;
        var dataZoomModel = this.dataZoomModel;
        var api = this.api;
        var borderRadius = dataZoomModel.get('borderRadius') || 0;
        var brushSelect = dataZoomModel.get('brushSelect');
        var filler = displayables.filler = new Rect$1({
          silent: brushSelect,
          style: {
            fill: dataZoomModel.get('fillerColor')
          },
          textConfig: {
            position: 'inside'
          }
        });
        sliderGroup.add(filler); // Frame border.

        sliderGroup.add(new Rect$1({
          silent: true,
          subPixelOptimize: true,
          shape: {
            x: 0,
            y: 0,
            width: size[0],
            height: size[1],
            r: borderRadius
          },
          style: {
            // deprecated option
            stroke: dataZoomModel.get('dataBackgroundColor') || dataZoomModel.get('borderColor'),
            lineWidth: DEFAULT_FRAME_BORDER_WIDTH,
            fill: 'rgba(0,0,0,0)'
          }
        })); // Left and right handle to resize

        each([0, 1], function (handleIndex) {
          var iconStr = dataZoomModel.get('handleIcon');

          if (!symbolBuildProxies[iconStr] && iconStr.indexOf('path://') < 0 && iconStr.indexOf('image://') < 0) {
            // Compatitable with the old icon parsers. Which can use a path string without path://
            iconStr = 'path://' + iconStr;

            if ("development" !== 'production') {
              deprecateLog('handleIcon now needs \'path://\' prefix when using a path string');
            }
          }

          var path = createSymbol(iconStr, -1, 0, 2, 2, null, true);
          path.attr({
            cursor: getCursor(this._orient),
            draggable: true,
            drift: bind(this._onDragMove, this, handleIndex),
            ondragend: bind(this._onDragEnd, this),
            onmouseover: bind(this._showDataInfo, this, true),
            onmouseout: bind(this._showDataInfo, this, false),
            z2: 5
          });
          var bRect = path.getBoundingRect();
          var handleSize = dataZoomModel.get('handleSize');
          this._handleHeight = parsePercent$1(handleSize, this._size[1]);
          this._handleWidth = bRect.width / bRect.height * this._handleHeight;
          path.setStyle(dataZoomModel.getModel('handleStyle').getItemStyle());
          path.style.strokeNoScale = true;
          path.rectHover = true;
          path.ensureState('emphasis').style = dataZoomModel.getModel(['emphasis', 'handleStyle']).getItemStyle();
          enableHoverEmphasis(path);
          var handleColor = dataZoomModel.get('handleColor'); // deprecated option
          // Compatitable with previous version

          if (handleColor != null) {
            path.style.fill = handleColor;
          }

          sliderGroup.add(handles[handleIndex] = path);
          var textStyleModel = dataZoomModel.getModel('textStyle');
          thisGroup.add(handleLabels[handleIndex] = new ZRText({
            silent: true,
            invisible: true,
            style: createTextStyle(textStyleModel, {
              x: 0,
              y: 0,
              text: '',
              verticalAlign: 'middle',
              align: 'center',
              fill: textStyleModel.getTextColor(),
              font: textStyleModel.getFont()
            }),
            z2: 10
          }));
        }, this); // Handle to move. Only visible when brushSelect is set true.

        var actualMoveZone = filler;

        if (brushSelect) {
          var moveHandleHeight = parsePercent$1(dataZoomModel.get('moveHandleSize'), size[1]);
          var moveHandle_1 = displayables.moveHandle = new Rect({
            style: dataZoomModel.getModel('moveHandleStyle').getItemStyle(),
            silent: true,
            shape: {
              r: [0, 0, 2, 2],
              y: size[1] - 0.5,
              height: moveHandleHeight
            }
          });
          var iconSize = moveHandleHeight * 0.8;
          var moveHandleIcon = displayables.moveHandleIcon = createSymbol(dataZoomModel.get('moveHandleIcon'), -iconSize / 2, -iconSize / 2, iconSize, iconSize, '#fff', true);
          moveHandleIcon.silent = true;
          moveHandleIcon.y = size[1] + moveHandleHeight / 2 - 0.5;
          moveHandle_1.ensureState('emphasis').style = dataZoomModel.getModel(['emphasis', 'moveHandleStyle']).getItemStyle();
          var moveZoneExpandSize = Math.min(size[1] / 2, Math.max(moveHandleHeight, 10));
          actualMoveZone = displayables.moveZone = new Rect({
            invisible: true,
            shape: {
              y: size[1] - moveZoneExpandSize,
              height: moveHandleHeight + moveZoneExpandSize
            }
          });
          actualMoveZone.on('mouseover', function () {
            api.enterEmphasis(moveHandle_1);
          }).on('mouseout', function () {
            api.leaveEmphasis(moveHandle_1);
          });
          sliderGroup.add(moveHandle_1);
          sliderGroup.add(moveHandleIcon);
          sliderGroup.add(actualMoveZone);
        }

        actualMoveZone.attr({
          draggable: true,
          cursor: getCursor(this._orient),
          drift: bind(this._onDragMove, this, 'all'),
          ondragstart: bind(this._showDataInfo, this, true),
          ondragend: bind(this._onDragEnd, this),
          onmouseover: bind(this._showDataInfo, this, true),
          onmouseout: bind(this._showDataInfo, this, false)
        });
      };

      SliderZoomView.prototype._resetInterval = function () {
        var range = this._range = this.dataZoomModel.getPercentRange();

        var viewExtent = this._getViewExtent();

        this._handleEnds = [linearMap(range[0], [0, 100], viewExtent, true), linearMap(range[1], [0, 100], viewExtent, true)];
      };

      SliderZoomView.prototype._updateInterval = function (handleIndex, delta) {
        var dataZoomModel = this.dataZoomModel;
        var handleEnds = this._handleEnds;

        var viewExtend = this._getViewExtent();

        var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();
        var percentExtent = [0, 100];
        sliderMove(delta, handleEnds, viewExtend, dataZoomModel.get('zoomLock') ? 'all' : handleIndex, minMaxSpan.minSpan != null ? linearMap(minMaxSpan.minSpan, percentExtent, viewExtend, true) : null, minMaxSpan.maxSpan != null ? linearMap(minMaxSpan.maxSpan, percentExtent, viewExtend, true) : null);
        var lastRange = this._range;
        var range = this._range = asc([linearMap(handleEnds[0], viewExtend, percentExtent, true), linearMap(handleEnds[1], viewExtend, percentExtent, true)]);
        return !lastRange || lastRange[0] !== range[0] || lastRange[1] !== range[1];
      };

      SliderZoomView.prototype._updateView = function (nonRealtime) {
        var displaybles = this._displayables;
        var handleEnds = this._handleEnds;
        var handleInterval = asc(handleEnds.slice());
        var size = this._size;
        each([0, 1], function (handleIndex) {
          // Handles
          var handle = displaybles.handles[handleIndex];
          var handleHeight = this._handleHeight;
          handle.attr({
            scaleX: handleHeight / 2,
            scaleY: handleHeight / 2,
            // This is a trick, by adding an extra tiny offset to let the default handle's end point align to the drag window.
            // NOTE: It may affect some custom shapes a bit. But we prefer to have better result by default.
            x: handleEnds[handleIndex] + (handleIndex ? -1 : 1),
            y: size[1] / 2 - handleHeight / 2
          });
        }, this); // Filler

        displaybles.filler.setShape({
          x: handleInterval[0],
          y: 0,
          width: handleInterval[1] - handleInterval[0],
          height: size[1]
        });
        var viewExtent = {
          x: handleInterval[0],
          width: handleInterval[1] - handleInterval[0]
        }; // Move handle

        if (displaybles.moveHandle) {
          displaybles.moveHandle.setShape(viewExtent);
          displaybles.moveZone.setShape(viewExtent); // Force update path on the invisible object

          displaybles.moveZone.getBoundingRect();
          displaybles.moveHandleIcon && displaybles.moveHandleIcon.attr('x', viewExtent.x + viewExtent.width / 2);
        } // update clip path of shadow.


        var dataShadowSegs = displaybles.dataShadowSegs;
        var segIntervals = [0, handleInterval[0], handleInterval[1], size[0]];

        for (var i = 0; i < dataShadowSegs.length; i++) {
          var segGroup = dataShadowSegs[i];
          var clipPath = segGroup.getClipPath();

          if (!clipPath) {
            clipPath = new Rect();
            segGroup.setClipPath(clipPath);
          }

          clipPath.setShape({
            x: segIntervals[i],
            y: 0,
            width: segIntervals[i + 1] - segIntervals[i],
            height: size[1]
          });
        }

        this._updateDataInfo(nonRealtime);
      };

      SliderZoomView.prototype._updateDataInfo = function (nonRealtime) {
        var dataZoomModel = this.dataZoomModel;
        var displaybles = this._displayables;
        var handleLabels = displaybles.handleLabels;
        var orient = this._orient;
        var labelTexts = ['', '']; // FIXME
        // date型，支持formatter，autoformatter（ec2 date.getAutoFormatter）

        if (dataZoomModel.get('showDetail')) {
          var axisProxy = dataZoomModel.findRepresentativeAxisProxy();

          if (axisProxy) {
            var axis = axisProxy.getAxisModel().axis;
            var range = this._range;
            var dataInterval = nonRealtime // See #4434, data and axis are not processed and reset yet in non-realtime mode.
            ? axisProxy.calculateDataWindow({
              start: range[0],
              end: range[1]
            }).valueWindow : axisProxy.getDataValueWindow();
            labelTexts = [this._formatLabel(dataInterval[0], axis), this._formatLabel(dataInterval[1], axis)];
          }
        }

        var orderedHandleEnds = asc(this._handleEnds.slice());
        setLabel.call(this, 0);
        setLabel.call(this, 1);

        function setLabel(handleIndex) {
          // Label
          // Text should not transform by barGroup.
          // Ignore handlers transform
          var barTransform = getTransform(displaybles.handles[handleIndex].parent, this.group);
          var direction = transformDirection(handleIndex === 0 ? 'right' : 'left', barTransform);
          var offset = this._handleWidth / 2 + LABEL_GAP;
          var textPoint = applyTransform$1([orderedHandleEnds[handleIndex] + (handleIndex === 0 ? -offset : offset), this._size[1] / 2], barTransform);
          handleLabels[handleIndex].setStyle({
            x: textPoint[0],
            y: textPoint[1],
            verticalAlign: orient === HORIZONTAL ? 'middle' : direction,
            align: orient === HORIZONTAL ? direction : 'center',
            text: labelTexts[handleIndex]
          });
        }
      };

      SliderZoomView.prototype._formatLabel = function (value, axis) {
        var dataZoomModel = this.dataZoomModel;
        var labelFormatter = dataZoomModel.get('labelFormatter');
        var labelPrecision = dataZoomModel.get('labelPrecision');

        if (labelPrecision == null || labelPrecision === 'auto') {
          labelPrecision = axis.getPixelPrecision();
        }

        var valueStr = value == null || isNaN(value) ? '' // FIXME Glue code
        : axis.type === 'category' || axis.type === 'time' ? axis.scale.getLabel({
          value: Math.round(value)
        }) // param of toFixed should less then 20.
        : value.toFixed(Math.min(labelPrecision, 20));
        return isFunction(labelFormatter) ? labelFormatter(value, valueStr) : isString(labelFormatter) ? labelFormatter.replace('{value}', valueStr) : valueStr;
      };
      /**
       * @param showOrHide true: show, false: hide
       */


      SliderZoomView.prototype._showDataInfo = function (showOrHide) {
        // Always show when drgging.
        showOrHide = this._dragging || showOrHide;
        var displayables = this._displayables;
        var handleLabels = displayables.handleLabels;
        handleLabels[0].attr('invisible', !showOrHide);
        handleLabels[1].attr('invisible', !showOrHide); // Highlight move handle

        displayables.moveHandle && this.api[showOrHide ? 'enterEmphasis' : 'leaveEmphasis'](displayables.moveHandle, 1);
      };

      SliderZoomView.prototype._onDragMove = function (handleIndex, dx, dy, event) {
        this._dragging = true; // For mobile device, prevent screen slider on the button.

        stop(event.event); // Transform dx, dy to bar coordination.

        var barTransform = this._displayables.sliderGroup.getLocalTransform();

        var vertex = applyTransform$1([dx, dy], barTransform, true);

        var changed = this._updateInterval(handleIndex, vertex[0]);

        var realtime = this.dataZoomModel.get('realtime');

        this._updateView(!realtime); // Avoid dispatch dataZoom repeatly but range not changed,
        // which cause bad visual effect when progressive enabled.


        changed && realtime && this._dispatchZoomAction(true);
      };

      SliderZoomView.prototype._onDragEnd = function () {
        this._dragging = false;

        this._showDataInfo(false); // While in realtime mode and stream mode, dispatch action when
        // drag end will cause the whole view rerender, which is unnecessary.


        var realtime = this.dataZoomModel.get('realtime');
        !realtime && this._dispatchZoomAction(false);
      };

      SliderZoomView.prototype._onClickPanel = function (e) {
        var size = this._size;

        var localPoint = this._displayables.sliderGroup.transformCoordToLocal(e.offsetX, e.offsetY);

        if (localPoint[0] < 0 || localPoint[0] > size[0] || localPoint[1] < 0 || localPoint[1] > size[1]) {
          return;
        }

        var handleEnds = this._handleEnds;
        var center = (handleEnds[0] + handleEnds[1]) / 2;

        var changed = this._updateInterval('all', localPoint[0] - center);

        this._updateView();

        changed && this._dispatchZoomAction(false);
      };

      SliderZoomView.prototype._onBrushStart = function (e) {
        var x = e.offsetX;
        var y = e.offsetY;
        this._brushStart = new Point(x, y);
        this._brushing = true;
        this._brushStartTime = +new Date(); // this._updateBrushRect(x, y);
      };

      SliderZoomView.prototype._onBrushEnd = function (e) {
        if (!this._brushing) {
          return;
        }

        var brushRect = this._displayables.brushRect;
        this._brushing = false;

        if (!brushRect) {
          return;
        }

        brushRect.attr('ignore', true);
        var brushShape = brushRect.shape;
        var brushEndTime = +new Date(); // console.log(brushEndTime - this._brushStartTime);

        if (brushEndTime - this._brushStartTime < 200 && Math.abs(brushShape.width) < 5) {
          // Will treat it as a click
          return;
        }

        var viewExtend = this._getViewExtent();

        var percentExtent = [0, 100];
        this._range = asc([linearMap(brushShape.x, viewExtend, percentExtent, true), linearMap(brushShape.x + brushShape.width, viewExtend, percentExtent, true)]);
        this._handleEnds = [brushShape.x, brushShape.x + brushShape.width];

        this._updateView();

        this._dispatchZoomAction(false);
      };

      SliderZoomView.prototype._onBrush = function (e) {
        if (this._brushing) {
          // For mobile device, prevent screen slider on the button.
          stop(e.event);

          this._updateBrushRect(e.offsetX, e.offsetY);
        }
      };

      SliderZoomView.prototype._updateBrushRect = function (mouseX, mouseY) {
        var displayables = this._displayables;
        var dataZoomModel = this.dataZoomModel;
        var brushRect = displayables.brushRect;

        if (!brushRect) {
          brushRect = displayables.brushRect = new Rect$1({
            silent: true,
            style: dataZoomModel.getModel('brushStyle').getItemStyle()
          });
          displayables.sliderGroup.add(brushRect);
        }

        brushRect.attr('ignore', false);
        var brushStart = this._brushStart;
        var sliderGroup = this._displayables.sliderGroup;
        var endPoint = sliderGroup.transformCoordToLocal(mouseX, mouseY);
        var startPoint = sliderGroup.transformCoordToLocal(brushStart.x, brushStart.y);
        var size = this._size;
        endPoint[0] = Math.max(Math.min(size[0], endPoint[0]), 0);
        brushRect.setShape({
          x: startPoint[0],
          y: 0,
          width: endPoint[0] - startPoint[0],
          height: size[1]
        });
      };
      /**
       * This action will be throttled.
       */


      SliderZoomView.prototype._dispatchZoomAction = function (realtime) {
        var range = this._range;
        this.api.dispatchAction({
          type: 'dataZoom',
          from: this.uid,
          dataZoomId: this.dataZoomModel.id,
          animation: realtime ? REALTIME_ANIMATION_CONFIG : null,
          start: range[0],
          end: range[1]
        });
      };

      SliderZoomView.prototype._findCoordRect = function () {
        // Find the grid coresponding to the first axis referred by dataZoom.
        var rect;
        var coordSysInfoList = collectReferCoordSysModelInfo(this.dataZoomModel).infoList;

        if (!rect && coordSysInfoList.length) {
          var coordSys = coordSysInfoList[0].model.coordinateSystem;
          rect = coordSys.getRect && coordSys.getRect();
        }

        if (!rect) {
          var width = this.api.getWidth();
          var height = this.api.getHeight();
          rect = {
            x: width * 0.2,
            y: height * 0.2,
            width: width * 0.6,
            height: height * 0.6
          };
        }

        return rect;
      };

      SliderZoomView.type = 'dataZoom.slider';
      return SliderZoomView;
    }(DataZoomView);

    function getOtherDim(thisDim) {
      // FIXME
      // 这个逻辑和getOtherAxis里一致，但是写在这里是否不好
      var map = {
        x: 'y',
        y: 'x',
        radius: 'angle',
        angle: 'radius'
      };
      return map[thisDim];
    }

    function getCursor(orient) {
      return orient === 'vertical' ? 'ns-resize' : 'ew-resize';
    }

    function install$l(registers) {
      registers.registerComponentModel(SliderZoomModel);
      registers.registerComponentView(SliderZoomView);
      installCommon(registers);
    }

    function install$m(registers) {
      use(install$k);
      use(install$l); // Do not install './dataZoomSelect',
      // since it only work for toolbox dataZoom.
    }

    var DEFAULT_OPTION = {
      label: {
        enabled: true
      },
      decal: {
        show: false
      }
    };
    var inner$h = makeInner();
    var decalPaletteScope = {};
    function ariaVisual(ecModel, api) {
      var ariaModel = ecModel.getModel('aria'); // See "area enabled" detection code in `GlobalModel.ts`.

      if (!ariaModel.get('enabled')) {
        return;
      }

      var defaultOption = clone(DEFAULT_OPTION);
      merge(defaultOption.label, ecModel.getLocaleModel().get('aria'), false);
      merge(ariaModel.option, defaultOption, false);
      setDecal();
      setLabel();

      function setDecal() {
        var decalModel = ariaModel.getModel('decal');
        var useDecal = decalModel.get('show');

        if (useDecal) {
          // Each type of series use one scope.
          // Pie and funnel are using different scopes.
          var paletteScopeGroupByType_1 = createHashMap();
          ecModel.eachSeries(function (seriesModel) {
            if (seriesModel.isColorBySeries()) {
              return;
            }

            var decalScope = paletteScopeGroupByType_1.get(seriesModel.type);

            if (!decalScope) {
              decalScope = {};
              paletteScopeGroupByType_1.set(seriesModel.type, decalScope);
            }

            inner$h(seriesModel).scope = decalScope;
          });
          ecModel.eachRawSeries(function (seriesModel) {
            if (ecModel.isSeriesFiltered(seriesModel)) {
              return;
            }

            if (isFunction(seriesModel.enableAriaDecal)) {
              // Let series define how to use decal palette on data
              seriesModel.enableAriaDecal();
              return;
            }

            var data = seriesModel.getData();

            if (!seriesModel.isColorBySeries()) {
              var dataAll_1 = seriesModel.getRawData();
              var idxMap_1 = {};
              var decalScope_1 = inner$h(seriesModel).scope;
              data.each(function (idx) {
                var rawIdx = data.getRawIndex(idx);
                idxMap_1[rawIdx] = idx;
              });
              var dataCount_1 = dataAll_1.count();
              dataAll_1.each(function (rawIdx) {
                var idx = idxMap_1[rawIdx];
                var name = dataAll_1.getName(rawIdx) || rawIdx + '';
                var paletteDecal = getDecalFromPalette(seriesModel.ecModel, name, decalScope_1, dataCount_1);
                var specifiedDecal = data.getItemVisual(idx, 'decal');
                data.setItemVisual(idx, 'decal', mergeDecal(specifiedDecal, paletteDecal));
              });
            } else {
              var paletteDecal = getDecalFromPalette(seriesModel.ecModel, seriesModel.name, decalPaletteScope, ecModel.getSeriesCount());
              var specifiedDecal = data.getVisual('decal');
              data.setVisual('decal', mergeDecal(specifiedDecal, paletteDecal));
            }

            function mergeDecal(specifiedDecal, paletteDecal) {
              // Merge decal from palette to decal from itemStyle.
              // User do not need to specify all of the decal props.
              var resultDecal = specifiedDecal ? extend(extend({}, paletteDecal), specifiedDecal) : paletteDecal;
              resultDecal.dirty = true;
              return resultDecal;
            }
          });
        }
      }

      function setLabel() {
        var labelLocale = ecModel.getLocaleModel().get('aria');
        var labelModel = ariaModel.getModel('label');
        labelModel.option = defaults(labelModel.option, labelLocale);

        if (!labelModel.get('enabled')) {
          return;
        }

        var dom = api.getZr().dom;

        if (labelModel.get('description')) {
          dom.setAttribute('aria-label', labelModel.get('description'));
          return;
        }

        var seriesCnt = ecModel.getSeriesCount();
        var maxDataCnt = labelModel.get(['data', 'maxCount']) || 10;
        var maxSeriesCnt = labelModel.get(['series', 'maxCount']) || 10;
        var displaySeriesCnt = Math.min(seriesCnt, maxSeriesCnt);
        var ariaLabel;

        if (seriesCnt < 1) {
          // No series, no aria label
          return;
        } else {
          var title = getTitle();

          if (title) {
            var withTitle = labelModel.get(['general', 'withTitle']);
            ariaLabel = replace(withTitle, {
              title: title
            });
          } else {
            ariaLabel = labelModel.get(['general', 'withoutTitle']);
          }

          var seriesLabels_1 = [];
          var prefix = seriesCnt > 1 ? labelModel.get(['series', 'multiple', 'prefix']) : labelModel.get(['series', 'single', 'prefix']);
          ariaLabel += replace(prefix, {
            seriesCount: seriesCnt
          });
          ecModel.eachSeries(function (seriesModel, idx) {
            if (idx < displaySeriesCnt) {
              var seriesLabel = void 0;
              var seriesName = seriesModel.get('name');
              var withName = seriesName ? 'withName' : 'withoutName';
              seriesLabel = seriesCnt > 1 ? labelModel.get(['series', 'multiple', withName]) : labelModel.get(['series', 'single', withName]);
              seriesLabel = replace(seriesLabel, {
                seriesId: seriesModel.seriesIndex,
                seriesName: seriesModel.get('name'),
                seriesType: getSeriesTypeName(seriesModel.subType)
              });
              var data = seriesModel.getData();

              if (data.count() > maxDataCnt) {
                // Show part of data
                var partialLabel = labelModel.get(['data', 'partialData']);
                seriesLabel += replace(partialLabel, {
                  displayCnt: maxDataCnt
                });
              } else {
                seriesLabel += labelModel.get(['data', 'allData']);
              }

              var middleSeparator_1 = labelModel.get(['data', 'separator', 'middle']);
              var endSeparator_1 = labelModel.get(['data', 'separator', 'end']);
              var dataLabels = [];

              for (var i = 0; i < data.count(); i++) {
                if (i < maxDataCnt) {
                  var name_1 = data.getName(i);
                  var value = data.getValues(i);
                  var dataLabel = labelModel.get(['data', name_1 ? 'withName' : 'withoutName']);
                  dataLabels.push(replace(dataLabel, {
                    name: name_1,
                    value: value.join(middleSeparator_1)
                  }));
                }
              }

              seriesLabel += dataLabels.join(middleSeparator_1) + endSeparator_1;
              seriesLabels_1.push(seriesLabel);
            }
          });
          var separatorModel = labelModel.getModel(['series', 'multiple', 'separator']);
          var middleSeparator = separatorModel.get('middle');
          var endSeparator = separatorModel.get('end');
          ariaLabel += seriesLabels_1.join(middleSeparator) + endSeparator;
          dom.setAttribute('aria-label', ariaLabel);
        }
      }

      function replace(str, keyValues) {
        if (!isString(str)) {
          return str;
        }

        var result = str;
        each(keyValues, function (value, key) {
          result = result.replace(new RegExp('\\{\\s*' + key + '\\s*\\}', 'g'), value);
        });
        return result;
      }

      function getTitle() {
        var title = ecModel.get('title');

        if (title && title.length) {
          title = title[0];
        }

        return title && title.text;
      }

      function getSeriesTypeName(type) {
        return ecModel.getLocaleModel().get(['series', 'typeNames'])[type] || '自定义图';
      }
    }

    function ariaPreprocessor(option) {
      if (!option || !option.aria) {
        return;
      }

      var aria = option.aria; // aria.show is deprecated and should use aria.enabled instead

      if (aria.show != null) {
        aria.enabled = aria.show;
      }

      aria.label = aria.label || {}; // move description, general, series, data to be under aria.label

      each(['description', 'general', 'series', 'data'], function (name) {
        if (aria[name] != null) {
          aria.label[name] = aria[name];
        }
      });
    }

    function install$n(registers) {
      registers.registerPreprocessor(ariaPreprocessor);
      registers.registerVisual(registers.PRIORITY.VISUAL.ARIA, ariaVisual);
    }

    var DatasetModel =
    /** @class */
    function (_super) {
      __extends(DatasetModel, _super);

      function DatasetModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'dataset';
        return _this;
      }

      DatasetModel.prototype.init = function (option, parentModel, ecModel) {
        _super.prototype.init.call(this, option, parentModel, ecModel);

        this._sourceManager = new SourceManager(this);
        disableTransformOptionMerge(this);
      };

      DatasetModel.prototype.mergeOption = function (newOption, ecModel) {
        _super.prototype.mergeOption.call(this, newOption, ecModel);

        disableTransformOptionMerge(this);
      };

      DatasetModel.prototype.optionUpdated = function () {
        this._sourceManager.dirty();
      };

      DatasetModel.prototype.getSourceManager = function () {
        return this._sourceManager;
      };

      DatasetModel.type = 'dataset';
      DatasetModel.defaultOption = {
        seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN
      };
      return DatasetModel;
    }(ComponentModel);

    var DatasetView =
    /** @class */
    function (_super) {
      __extends(DatasetView, _super);

      function DatasetView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'dataset';
        return _this;
      }

      DatasetView.type = 'dataset';
      return DatasetView;
    }(ComponentView);

    function install$o(registers) {
      registers.registerComponentModel(DatasetModel);
      registers.registerComponentView(DatasetView);
    }

    use([install$1]);
    use([install]);
    use([install$2, install$3, install$4, install$6]);
    use([install$9, install$c, install$7, install$j, install$8, install$d, install$e, install$f, install$g, install$m, install$b, install$n, install$o]);

    exports.Axis = Axis;
    exports.ChartView = ChartView;
    exports.ComponentModel = ComponentModel;
    exports.ComponentView = ComponentView;
    exports.List = SeriesData;
    exports.Model = Model;
    exports.PRIORITY = PRIORITY;
    exports.SeriesModel = SeriesModel;
    exports.color = color;
    exports.connect = connect;
    exports.dataTool = dataTool;
    exports.dependencies = dependencies;
    exports.disConnect = disConnect;
    exports.disconnect = disconnect;
    exports.dispose = dispose$1;
    exports.env = env;
    exports.extendChartView = extendChartView;
    exports.extendComponentModel = extendComponentModel;
    exports.extendComponentView = extendComponentView;
    exports.extendSeriesModel = extendSeriesModel;
    exports.format = format$1;
    exports.getCoordinateSystemDimensions = getCoordinateSystemDimensions;
    exports.getInstanceByDom = getInstanceByDom;
    exports.getInstanceById = getInstanceById;
    exports.getMap = getMap;
    exports.graphic = graphic$1;
    exports.helper = helper;
    exports.init = init$1;
    exports.innerDrawElementOnCanvas = brushSingle;
    exports.matrix = matrix;
    exports.number = number;
    exports.parseGeoJSON = parseGeoJSON;
    exports.parseGeoJson = parseGeoJSON;
    exports.registerAction = registerAction;
    exports.registerCoordinateSystem = registerCoordinateSystem;
    exports.registerLayout = registerLayout;
    exports.registerLoading = registerLoading;
    exports.registerLocale = registerLocale;
    exports.registerMap = registerMap;
    exports.registerPostInit = registerPostInit;
    exports.registerPostUpdate = registerPostUpdate;
    exports.registerPreprocessor = registerPreprocessor;
    exports.registerProcessor = registerProcessor;
    exports.registerTheme = registerTheme;
    exports.registerTransform = registerTransform;
    exports.registerUpdateLifecycle = registerUpdateLifecycle;
    exports.registerVisual = registerVisual;
    exports.setCanvasCreator = setCanvasCreator;
    exports.setPlatformAPI = setPlatformAPI;
    exports.throttle = throttle;
    exports.time = time;
    exports.use = use;
    exports.util = util$1;
    exports.vector = vector;
    exports.version = version$1;
    exports.zrUtil = util;
    exports.zrender = zrender;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=echarts.common.js.map
