/*!
 * @pixi/graphics - v6.3.0
 * Compiled Wed, 23 Mar 2022 18:58:56 UTC
 *
 * @pixi/graphics is licensed under the MIT License.
 * http://www.opensource.org/licenses/mit-license
 */
this.PIXI = this.PIXI || {};
var _pixi_graphics = (function (exports, core, math, utils, constants, display) {
    'use strict';

    /**
     * Supported line joints in `PIXI.LineStyle` for graphics.
     *
     * @see PIXI.Graphics#lineStyle
     * @see https://graphicdesign.stackexchange.com/questions/59018/what-is-a-bevel-join-of-two-lines-exactly-illustrator
     *
     * @name LINE_JOIN
     * @memberof PIXI
     * @static
     * @enum {string}
     * @property {string} MITER - 'miter': make a sharp corner where outer part of lines meet
     * @property {string} BEVEL - 'bevel': add a square butt at each end of line segment and fill the triangle at turn
     * @property {string} ROUND - 'round': add an arc at the joint
     */
    (function (LINE_JOIN) {
        LINE_JOIN["MITER"] = "miter";
        LINE_JOIN["BEVEL"] = "bevel";
        LINE_JOIN["ROUND"] = "round";
    })(exports.LINE_JOIN || (exports.LINE_JOIN = {}));
    (function (LINE_CAP) {
        LINE_CAP["BUTT"] = "butt";
        LINE_CAP["ROUND"] = "round";
        LINE_CAP["SQUARE"] = "square";
    })(exports.LINE_CAP || (exports.LINE_CAP = {}));
    /**
     * Graphics curves resolution settings. If `adaptive` flag is set to `true`,
     * the resolution is calculated based on the curve's length to ensure better visual quality.
     * Adaptive draw works with `bezierCurveTo` and `quadraticCurveTo`.
     *
     * @static
     * @constant
     * @memberof PIXI
     * @name GRAPHICS_CURVES
     * @type {object}
     * @property {boolean} adaptive=true - flag indicating if the resolution should be adaptive
     * @property {number} maxLength=10 - maximal length of a single segment of the curve (if adaptive = false, ignored)
     * @property {number} minSegments=8 - minimal number of segments in the curve (if adaptive = false, ignored)
     * @property {number} maxSegments=2048 - maximal number of segments in the curve (if adaptive = false, ignored)
     */
    var GRAPHICS_CURVES = {
        adaptive: true,
        maxLength: 10,
        minSegments: 8,
        maxSegments: 2048,
        epsilon: 0.0001,
        _segmentsCount: function (length, defaultSegments) {
            if (defaultSegments === void 0) { defaultSegments = 20; }
            if (!this.adaptive || !length || isNaN(length)) {
                return defaultSegments;
            }
            var result = Math.ceil(length / this.maxLength);
            if (result < this.minSegments) {
                result = this.minSegments;
            }
            else if (result > this.maxSegments) {
                result = this.maxSegments;
            }
            return result;
        },
    };

    /**
     * Fill style object for Graphics.
     *
     * @memberof PIXI
     */
    var FillStyle = /** @class */ (function () {
        function FillStyle() {
            /**
             * The hex color value used when coloring the Graphics object.
             *
             * @default 0xFFFFFF
             */
            this.color = 0xFFFFFF;
            /** The alpha value used when filling the Graphics object. */
            this.alpha = 1.0;
            /**
             * The texture to be used for the fill.
             *
             * @default 0
             */
            this.texture = core.Texture.WHITE;
            /**
             * The transform applied to the texture.
             *
             * @default null
             */
            this.matrix = null;
            /** If the current fill is visible. */
            this.visible = false;
            this.reset();
        }
        /** Clones the object */
        FillStyle.prototype.clone = function () {
            var obj = new FillStyle();
            obj.color = this.color;
            obj.alpha = this.alpha;
            obj.texture = this.texture;
            obj.matrix = this.matrix;
            obj.visible = this.visible;
            return obj;
        };
        /** Reset */
        FillStyle.prototype.reset = function () {
            this.color = 0xFFFFFF;
            this.alpha = 1;
            this.texture = core.Texture.WHITE;
            this.matrix = null;
            this.visible = false;
        };
        /** Destroy and don't use after this. */
        FillStyle.prototype.destroy = function () {
            this.texture = null;
            this.matrix = null;
        };
        return FillStyle;
    }());

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    Licensed 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

    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    MERCHANTABLITY OR NON-INFRINGEMENT.

    See the Apache Version 2.0 License for specific language governing permissions
    and limitations under the License.
    ***************************************************************************** */
    /* 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 (b.hasOwnProperty(p)) { d[p] = b[p]; } } };
        return extendStatics(d, b);
    };

    function __extends(d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }

    var __assign = function() {
        __assign = Object.assign || function __assign(t) {
            var arguments$1 = arguments;

            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments$1[i];
                for (var p in s) { if (Object.prototype.hasOwnProperty.call(s, p)) { t[p] = s[p]; } }
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };

    function __rest(s, e) {
        var t = {};
        for (var p in s) { if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
            { t[p] = s[p]; } }
        if (s != null && typeof Object.getOwnPropertySymbols === "function")
            { for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0)
                { t[p[i]] = s[p[i]]; } } }
        return t;
    }

    function __decorate(decorators, target, key, desc) {
        var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
        if (typeof Reflect === "object" && typeof Reflect.decorate === "function") { r = Reflect.decorate(decorators, target, key, desc); }
        else { for (var i = decorators.length - 1; i >= 0; i--) { if (d = decorators[i]) { r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; } } }
        return c > 3 && r && Object.defineProperty(target, key, r), r;
    }

    function __param(paramIndex, decorator) {
        return function (target, key) { decorator(target, key, paramIndex); }
    }

    function __metadata(metadataKey, metadataValue) {
        if (typeof Reflect === "object" && typeof Reflect.metadata === "function") { return Reflect.metadata(metadataKey, metadataValue); }
    }

    function __awaiter(thisArg, _arguments, P, generator) {
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    }

    function __generator(thisArg, body) {
        var _ = { label: 0, sent: function() { if (t[0] & 1) { throw t[1]; } return t[1]; }, trys: [], ops: [] }, f, y, t, g;
        return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
        function verb(n) { return function (v) { return step([n, v]); }; }
        function step(op) {
            if (f) { throw new TypeError("Generator is already executing."); }
            while (_) { try {
                if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) { return t; }
                if (y = 0, t) { op = [op[0] & 2, t.value]; }
                switch (op[0]) {
                    case 0: case 1: t = op; break;
                    case 4: _.label++; return { value: op[1], done: false };
                    case 5: _.label++; y = op[1]; op = [0]; continue;
                    case 7: op = _.ops.pop(); _.trys.pop(); continue;
                    default:
                        if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                        if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                        if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                        if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                        if (t[2]) { _.ops.pop(); }
                        _.trys.pop(); continue;
                }
                op = body.call(thisArg, _);
            } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } }
            if (op[0] & 5) { throw op[1]; } return { value: op[0] ? op[1] : void 0, done: true };
        }
    }

    function __exportStar(m, exports) {
        for (var p in m) { if (!exports.hasOwnProperty(p)) { exports[p] = m[p]; } }
    }

    function __values(o) {
        var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
        if (m) { return m.call(o); }
        return {
            next: function () {
                if (o && i >= o.length) { o = void 0; }
                return { value: o && o[i++], done: !o };
            }
        };
    }

    function __read(o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m) { return o; }
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done) { ar.push(r.value); }
        }
        catch (error) { e = { error: error }; }
        finally {
            try {
                if (r && !r.done && (m = i["return"])) { m.call(i); }
            }
            finally { if (e) { throw e.error; } }
        }
        return ar;
    }

    function __spread() {
        var arguments$1 = arguments;

        for (var ar = [], i = 0; i < arguments.length; i++)
            { ar = ar.concat(__read(arguments$1[i])); }
        return ar;
    }

    function __await(v) {
        return this instanceof __await ? (this.v = v, this) : new __await(v);
    }

    function __asyncGenerator(thisArg, _arguments, generator) {
        if (!Symbol.asyncIterator) { throw new TypeError("Symbol.asyncIterator is not defined."); }
        var g = generator.apply(thisArg, _arguments || []), i, q = [];
        return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
        function verb(n) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } }
        function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
        function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
        function fulfill(value) { resume("next", value); }
        function reject(value) { resume("throw", value); }
        function settle(f, v) { if (f(v), q.shift(), q.length) { resume(q[0][0], q[0][1]); } }
    }

    function __asyncDelegator(o) {
        var i, p;
        return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
        function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
    }

    function __asyncValues(o) {
        if (!Symbol.asyncIterator) { throw new TypeError("Symbol.asyncIterator is not defined."); }
        var m = o[Symbol.asyncIterator], i;
        return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
        function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
        function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
    }

    function __makeTemplateObject(cooked, raw) {
        if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
        return cooked;
    };

    function __importStar(mod) {
        if (mod && mod.__esModule) { return mod; }
        var result = {};
        if (mod != null) { for (var k in mod) { if (Object.hasOwnProperty.call(mod, k)) { result[k] = mod[k]; } } }
        result.default = mod;
        return result;
    }

    function __importDefault(mod) {
        return (mod && mod.__esModule) ? mod : { default: mod };
    }

    function fixOrientation(points, hole) {
        var _a, _b;
        if (hole === void 0) { hole = false; }
        var m = points.length;
        if (m < 6) {
            return;
        }
        var area = 0;
        for (var i = 0, x1 = points[m - 2], y1 = points[m - 1]; i < m; i += 2) {
            var x2 = points[i];
            var y2 = points[i + 1];
            area += (x2 - x1) * (y2 + y1);
            x1 = x2;
            y1 = y2;
        }
        if ((!hole && area > 0) || (hole && area <= 0)) {
            var n = m / 2;
            for (var i = n + (n % 2); i < m; i += 2) {
                var i1 = m - i - 2;
                var i2 = m - i - 1;
                var i3 = i;
                var i4 = i + 1;
                _a = [points[i3], points[i1]], points[i1] = _a[0], points[i3] = _a[1];
                _b = [points[i4], points[i2]], points[i2] = _b[0], points[i4] = _b[1];
            }
        }
    }
    /**
     * Builds a polygon to draw
     *
     * Ignored from docs since it is not directly exposed.
     *
     * @ignore
     * @private
     * @param {PIXI.WebGLGraphicsData} graphicsData - The graphics object containing all the necessary properties
     * @param {object} webGLData - an object containing all the WebGL-specific information to create this shape
     * @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines
     */
    var buildPoly = {
        build: function (graphicsData) {
            graphicsData.points = graphicsData.shape.points.slice();
        },
        triangulate: function (graphicsData, graphicsGeometry) {
            var points = graphicsData.points;
            var holes = graphicsData.holes;
            var verts = graphicsGeometry.points;
            var indices = graphicsGeometry.indices;
            if (points.length >= 6) {
                fixOrientation(points, false);
                var holeArray = [];
                // Process holes..
                for (var i = 0; i < holes.length; i++) {
                    var hole = holes[i];
                    fixOrientation(hole.points, true);
                    holeArray.push(points.length / 2);
                    points = points.concat(hole.points);
                }
                // sort color
                var triangles = utils.earcut(points, holeArray, 2);
                if (!triangles) {
                    return;
                }
                var vertPos = verts.length / 2;
                for (var i = 0; i < triangles.length; i += 3) {
                    indices.push(triangles[i] + vertPos);
                    indices.push(triangles[i + 1] + vertPos);
                    indices.push(triangles[i + 2] + vertPos);
                }
                for (var i = 0; i < points.length; i++) {
                    verts.push(points[i]);
                }
            }
        },
    };

    // for type only
    /**
     * Builds a circle to draw
     *
     * Ignored from docs since it is not directly exposed.
     *
     * @ignore
     * @private
     * @param {PIXI.WebGLGraphicsData} graphicsData - The graphics object to draw
     * @param {object} webGLData - an object containing all the WebGL-specific information to create this shape
     * @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines
     */
    var buildCircle = {
        build: function (graphicsData) {
            // need to convert points to a nice regular data
            var points = graphicsData.points;
            var x;
            var y;
            var dx;
            var dy;
            var rx;
            var ry;
            if (graphicsData.type === math.SHAPES.CIRC) {
                var circle = graphicsData.shape;
                x = circle.x;
                y = circle.y;
                rx = ry = circle.radius;
                dx = dy = 0;
            }
            else if (graphicsData.type === math.SHAPES.ELIP) {
                var ellipse = graphicsData.shape;
                x = ellipse.x;
                y = ellipse.y;
                rx = ellipse.width;
                ry = ellipse.height;
                dx = dy = 0;
            }
            else {
                var roundedRect = graphicsData.shape;
                var halfWidth = roundedRect.width / 2;
                var halfHeight = roundedRect.height / 2;
                x = roundedRect.x + halfWidth;
                y = roundedRect.y + halfHeight;
                rx = ry = Math.max(0, Math.min(roundedRect.radius, Math.min(halfWidth, halfHeight)));
                dx = halfWidth - rx;
                dy = halfHeight - ry;
            }
            // Choose a number of segments such that the maximum absolute deviation from the circle is approximately 0.029
            var n = Math.ceil(2.3 * Math.sqrt(rx + ry));
            var m = (n * 8) + (dx ? 4 : 0) + (dy ? 4 : 0);
            points.length = m;
            if (m === 0) {
                return;
            }
            if (n === 0) {
                points.length = 8;
                points[0] = points[6] = x + dx;
                points[1] = points[3] = y + dy;
                points[2] = points[4] = x - dx;
                points[5] = points[7] = y - dy;
                return;
            }
            var j1 = 0;
            var j2 = (n * 4) + (dx ? 2 : 0) + 2;
            var j3 = j2;
            var j4 = m;
            {
                var x0 = dx + rx;
                var y0 = dy;
                var x1 = x + x0;
                var x2 = x - x0;
                var y1 = y + y0;
                points[j1++] = x1;
                points[j1++] = y1;
                points[--j2] = y1;
                points[--j2] = x2;
                if (dy) {
                    var y2 = y - y0;
                    points[j3++] = x2;
                    points[j3++] = y2;
                    points[--j4] = y2;
                    points[--j4] = x1;
                }
            }
            for (var i = 1; i < n; i++) {
                var a = Math.PI / 2 * (i / n);
                var x0 = dx + (Math.cos(a) * rx);
                var y0 = dy + (Math.sin(a) * ry);
                var x1 = x + x0;
                var x2 = x - x0;
                var y1 = y + y0;
                var y2 = y - y0;
                points[j1++] = x1;
                points[j1++] = y1;
                points[--j2] = y1;
                points[--j2] = x2;
                points[j3++] = x2;
                points[j3++] = y2;
                points[--j4] = y2;
                points[--j4] = x1;
            }
            {
                var x0 = dx;
                var y0 = dy + ry;
                var x1 = x + x0;
                var x2 = x - x0;
                var y1 = y + y0;
                var y2 = y - y0;
                points[j1++] = x1;
                points[j1++] = y1;
                points[--j4] = y2;
                points[--j4] = x1;
                if (dx) {
                    points[j1++] = x2;
                    points[j1++] = y1;
                    points[--j4] = y2;
                    points[--j4] = x2;
                }
            }
        },
        triangulate: function (graphicsData, graphicsGeometry) {
            var points = graphicsData.points;
            var verts = graphicsGeometry.points;
            var indices = graphicsGeometry.indices;
            var vertPos = verts.length / 2;
            var center = vertPos;
            var x;
            var y;
            if (graphicsData.type !== math.SHAPES.RREC) {
                var circle = graphicsData.shape;
                x = circle.x;
                y = circle.y;
            }
            else {
                var roundedRect = graphicsData.shape;
                x = roundedRect.x + (roundedRect.width / 2);
                y = roundedRect.y + (roundedRect.height / 2);
            }
            var matrix = graphicsData.matrix;
            // Push center (special point)
            verts.push(graphicsData.matrix ? (matrix.a * x) + (matrix.c * y) + matrix.tx : x, graphicsData.matrix ? (matrix.b * x) + (matrix.d * y) + matrix.ty : y);
            vertPos++;
            verts.push(points[0], points[1]);
            for (var i = 2; i < points.length; i += 2) {
                verts.push(points[i], points[i + 1]);
                // add some uvs
                indices.push(vertPos++, center, vertPos);
            }
            indices.push(center + 1, center, vertPos);
        },
    };

    /**
     * Builds a rectangle to draw
     *
     * Ignored from docs since it is not directly exposed.
     *
     * @ignore
     * @private
     * @param {PIXI.WebGLGraphicsData} graphicsData - The graphics object containing all the necessary properties
     * @param {object} webGLData - an object containing all the WebGL-specific information to create this shape
     * @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines
     */
    var buildRectangle = {
        build: function (graphicsData) {
            // --- //
            // need to convert points to a nice regular data
            //
            var rectData = graphicsData.shape;
            var x = rectData.x;
            var y = rectData.y;
            var width = rectData.width;
            var height = rectData.height;
            var points = graphicsData.points;
            points.length = 0;
            points.push(x, y, x + width, y, x + width, y + height, x, y + height);
        },
        triangulate: function (graphicsData, graphicsGeometry) {
            var points = graphicsData.points;
            var verts = graphicsGeometry.points;
            var vertPos = verts.length / 2;
            verts.push(points[0], points[1], points[2], points[3], points[6], points[7], points[4], points[5]);
            graphicsGeometry.indices.push(vertPos, vertPos + 1, vertPos + 2, vertPos + 1, vertPos + 2, vertPos + 3);
        },
    };

    /**
     * Calculate a single point for a quadratic bezier curve.
     * Utility function used by quadraticBezierCurve.
     * Ignored from docs since it is not directly exposed.
     *
     * @ignore
     * @private
     * @param {number} n1 - first number
     * @param {number} n2 - second number
     * @param {number} perc - percentage
     * @return {number} the result
     *
     */
    function getPt(n1, n2, perc) {
        var diff = n2 - n1;
        return n1 + (diff * perc);
    }
    /**
     * Calculate the points for a quadratic bezier curve. (helper function..)
     * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c
     *
     * Ignored from docs since it is not directly exposed.
     *
     * @ignore
     * @private
     * @param {number} fromX - Origin point x
     * @param {number} fromY - Origin point x
     * @param {number} cpX - Control point x
     * @param {number} cpY - Control point y
     * @param {number} toX - Destination point x
     * @param {number} toY - Destination point y
     * @param {number[]} [out=[]] - The output array to add points into. If not passed, a new array is created.
     * @return {number[]} an array of points
     */
    function quadraticBezierCurve(fromX, fromY, cpX, cpY, toX, toY, out) {
        if (out === void 0) { out = []; }
        var n = 20;
        var points = out;
        var xa = 0;
        var ya = 0;
        var xb = 0;
        var yb = 0;
        var x = 0;
        var y = 0;
        for (var i = 0, j = 0; i <= n; ++i) {
            j = i / n;
            // The Green Line
            xa = getPt(fromX, cpX, j);
            ya = getPt(fromY, cpY, j);
            xb = getPt(cpX, toX, j);
            yb = getPt(cpY, toY, j);
            // The Black Dot
            x = getPt(xa, xb, j);
            y = getPt(ya, yb, j);
            // Handle case when first curve points overlaps and earcut fails to triangulate
            if (i === 0 && points[points.length - 2] === x && points[points.length - 1] === y) {
                continue;
            }
            points.push(x, y);
        }
        return points;
    }
    /**
     * Builds a rounded rectangle to draw
     *
     * Ignored from docs since it is not directly exposed.
     *
     * @ignore
     * @private
     * @param {PIXI.WebGLGraphicsData} graphicsData - The graphics object containing all the necessary properties
     * @param {object} webGLData - an object containing all the WebGL-specific information to create this shape
     * @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines
     */
    var buildRoundedRectangle = {
        build: function (graphicsData) {
            if (Graphics.nextRoundedRectBehavior) {
                buildCircle.build(graphicsData);
                return;
            }
            var rrectData = graphicsData.shape;
            var points = graphicsData.points;
            var x = rrectData.x;
            var y = rrectData.y;
            var width = rrectData.width;
            var height = rrectData.height;
            // Don't allow negative radius or greater than half the smallest width
            var radius = Math.max(0, Math.min(rrectData.radius, Math.min(width, height) / 2));
            points.length = 0;
            // No radius, do a simple rectangle
            if (!radius) {
                points.push(x, y, x + width, y, x + width, y + height, x, y + height);
            }
            else {
                quadraticBezierCurve(x, y + radius, x, y, x + radius, y, points);
                quadraticBezierCurve(x + width - radius, y, x + width, y, x + width, y + radius, points);
                quadraticBezierCurve(x + width, y + height - radius, x + width, y + height, x + width - radius, y + height, points);
                quadraticBezierCurve(x + radius, y + height, x, y + height, x, y + height - radius, points);
            }
        },
        triangulate: function (graphicsData, graphicsGeometry) {
            if (Graphics.nextRoundedRectBehavior) {
                buildCircle.triangulate(graphicsData, graphicsGeometry);
                return;
            }
            var points = graphicsData.points;
            var verts = graphicsGeometry.points;
            var indices = graphicsGeometry.indices;
            var vecPos = verts.length / 2;
            var triangles = utils.earcut(points, null, 2);
            for (var i = 0, j = triangles.length; i < j; i += 3) {
                indices.push(triangles[i] + vecPos);
                //     indices.push(triangles[i] + vecPos);
                indices.push(triangles[i + 1] + vecPos);
                //   indices.push(triangles[i + 2] + vecPos);
                indices.push(triangles[i + 2] + vecPos);
            }
            for (var i = 0, j = points.length; i < j; i++) {
                verts.push(points[i], points[++i]);
            }
        },
    };

    /**
     * Buffers vertices to draw a square cap.
     *
     * Ignored from docs since it is not directly exposed.
     *
     * @ignore
     * @private
     * @param {number} x - X-coord of end point
     * @param {number} y - Y-coord of end point
     * @param {number} nx - X-coord of line normal pointing inside
     * @param {number} ny - Y-coord of line normal pointing inside
     * @param {Array<number>} verts - vertex buffer
     * @returns {}
     */
    function square(x, y, nx, ny, innerWeight, outerWeight, clockwise, /* rotation for square (true at left end, false at right end) */ verts) {
        var ix = x - (nx * innerWeight);
        var iy = y - (ny * innerWeight);
        var ox = x + (nx * outerWeight);
        var oy = y + (ny * outerWeight);
        /* Rotate nx,ny for extension vector */
        var exx;
        var eyy;
        if (clockwise) {
            exx = ny;
            eyy = -nx;
        }
        else {
            exx = -ny;
            eyy = nx;
        }
        /* [i|0]x,y extended at cap */
        var eix = ix + exx;
        var eiy = iy + eyy;
        var eox = ox + exx;
        var eoy = oy + eyy;
        /* Square itself must be inserted clockwise*/
        verts.push(eix, eiy);
        verts.push(eox, eoy);
        return 2;
    }
    /**
     * Buffers vertices to draw an arc at the line joint or cap.
     *
     * Ignored from docs since it is not directly exposed.
     *
     * @ignore
     * @private
     * @param {number} cx - X-coord of center
     * @param {number} cy - Y-coord of center
     * @param {number} sx - X-coord of arc start
     * @param {number} sy - Y-coord of arc start
     * @param {number} ex - X-coord of arc end
     * @param {number} ey - Y-coord of arc end
     * @param {Array<number>} verts - buffer of vertices
     * @param {boolean} clockwise - orientation of vertices
     * @returns {number} - no. of vertices pushed
     */
    function round(cx, cy, sx, sy, ex, ey, verts, clockwise) {
        var cx2p0x = sx - cx;
        var cy2p0y = sy - cy;
        var angle0 = Math.atan2(cx2p0x, cy2p0y);
        var angle1 = Math.atan2(ex - cx, ey - cy);
        if (clockwise && angle0 < angle1) {
            angle0 += Math.PI * 2;
        }
        else if (!clockwise && angle0 > angle1) {
            angle1 += Math.PI * 2;
        }
        var startAngle = angle0;
        var angleDiff = angle1 - angle0;
        var absAngleDiff = Math.abs(angleDiff);
        /* if (absAngleDiff >= PI_LBOUND && absAngleDiff <= PI_UBOUND)
        {
            const r1x = cx - nxtPx;
            const r1y = cy - nxtPy;

            if (r1x === 0)
            {
                if (r1y > 0)
                {
                    angleDiff = -angleDiff;
                }
            }
            else if (r1x >= -GRAPHICS_CURVES.epsilon)
            {
                angleDiff = -angleDiff;
            }
        }*/
        var radius = Math.sqrt((cx2p0x * cx2p0x) + (cy2p0y * cy2p0y));
        var segCount = ((15 * absAngleDiff * Math.sqrt(radius) / Math.PI) >> 0) + 1;
        var angleInc = angleDiff / segCount;
        startAngle += angleInc;
        if (clockwise) {
            verts.push(cx, cy);
            verts.push(sx, sy);
            for (var i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) {
                verts.push(cx, cy);
                verts.push(cx + ((Math.sin(angle) * radius)), cy + ((Math.cos(angle) * radius)));
            }
            verts.push(cx, cy);
            verts.push(ex, ey);
        }
        else {
            verts.push(sx, sy);
            verts.push(cx, cy);
            for (var i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) {
                verts.push(cx + ((Math.sin(angle) * radius)), cy + ((Math.cos(angle) * radius)));
                verts.push(cx, cy);
            }
            verts.push(ex, ey);
            verts.push(cx, cy);
        }
        return segCount * 2;
    }
    /**
     * Builds a line to draw using the polygon method.
     *
     * Ignored from docs since it is not directly exposed.
     *
     * @ignore
     * @private
     * @param {PIXI.GraphicsData} graphicsData - The graphics object containing all the necessary properties
     * @param {PIXI.GraphicsGeometry} graphicsGeometry - Geometry where to append output
     */
    function buildNonNativeLine(graphicsData, graphicsGeometry) {
        var shape = graphicsData.shape;
        var points = graphicsData.points || shape.points.slice();
        var eps = graphicsGeometry.closePointEps;
        if (points.length === 0) {
            return;
        }
        // if the line width is an odd number add 0.5 to align to a whole pixel
        // commenting this out fixes #711 and #1620
        // if (graphicsData.lineWidth%2)
        // {
        //     for (i = 0; i < points.length; i++)
        //     {
        //         points[i] += 0.5;
        //     }
        // }
        var style = graphicsData.lineStyle;
        // get first and last point.. figure out the middle!
        var firstPoint = new math.Point(points[0], points[1]);
        var lastPoint = new math.Point(points[points.length - 2], points[points.length - 1]);
        var closedShape = shape.type !== math.SHAPES.POLY || shape.closeStroke;
        var closedPath = Math.abs(firstPoint.x - lastPoint.x) < eps
            && Math.abs(firstPoint.y - lastPoint.y) < eps;
        // if the first point is the last point - gonna have issues :)
        if (closedShape) {
            // need to clone as we are going to slightly modify the shape..
            points = points.slice();
            if (closedPath) {
                points.pop();
                points.pop();
                lastPoint.set(points[points.length - 2], points[points.length - 1]);
            }
            var midPointX = (firstPoint.x + lastPoint.x) * 0.5;
            var midPointY = (lastPoint.y + firstPoint.y) * 0.5;
            points.unshift(midPointX, midPointY);
            points.push(midPointX, midPointY);
        }
        var verts = graphicsGeometry.points;
        var length = points.length / 2;
        var indexCount = points.length;
        var indexStart = verts.length / 2;
        // Max. inner and outer width
        var width = style.width / 2;
        var widthSquared = width * width;
        var miterLimitSquared = style.miterLimit * style.miterLimit;
        /* Line segments of interest where (x1,y1) forms the corner. */
        var x0 = points[0];
        var y0 = points[1];
        var x1 = points[2];
        var y1 = points[3];
        var x2 = 0;
        var y2 = 0;
        /* perp[?](x|y) = the line normal with magnitude lineWidth. */
        var perpx = -(y0 - y1);
        var perpy = x0 - x1;
        var perp1x = 0;
        var perp1y = 0;
        var dist = Math.sqrt((perpx * perpx) + (perpy * perpy));
        perpx /= dist;
        perpy /= dist;
        perpx *= width;
        perpy *= width;
        var ratio = style.alignment; // 0.5;
        var innerWeight = (1 - ratio) * 2;
        var outerWeight = ratio * 2;
        if (!closedShape) {
            if (style.cap === exports.LINE_CAP.ROUND) {
                indexCount += round(x0 - (perpx * (innerWeight - outerWeight) * 0.5), y0 - (perpy * (innerWeight - outerWeight) * 0.5), x0 - (perpx * innerWeight), y0 - (perpy * innerWeight), x0 + (perpx * outerWeight), y0 + (perpy * outerWeight), verts, true) + 2;
            }
            else if (style.cap === exports.LINE_CAP.SQUARE) {
                indexCount += square(x0, y0, perpx, perpy, innerWeight, outerWeight, true, verts);
            }
        }
        // Push first point (below & above vertices)
        verts.push(x0 - (perpx * innerWeight), y0 - (perpy * innerWeight));
        verts.push(x0 + (perpx * outerWeight), y0 + (perpy * outerWeight));
        for (var i = 1; i < length - 1; ++i) {
            x0 = points[(i - 1) * 2];
            y0 = points[((i - 1) * 2) + 1];
            x1 = points[i * 2];
            y1 = points[(i * 2) + 1];
            x2 = points[(i + 1) * 2];
            y2 = points[((i + 1) * 2) + 1];
            perpx = -(y0 - y1);
            perpy = x0 - x1;
            dist = Math.sqrt((perpx * perpx) + (perpy * perpy));
            perpx /= dist;
            perpy /= dist;
            perpx *= width;
            perpy *= width;
            perp1x = -(y1 - y2);
            perp1y = x1 - x2;
            dist = Math.sqrt((perp1x * perp1x) + (perp1y * perp1y));
            perp1x /= dist;
            perp1y /= dist;
            perp1x *= width;
            perp1y *= width;
            /* d[x|y](0|1) = the component displacement between points p(0,1|1,2) */
            var dx0 = x1 - x0;
            var dy0 = y0 - y1;
            var dx1 = x1 - x2;
            var dy1 = y2 - y1;
            /* +ve if internal angle counterclockwise, -ve if internal angle clockwise. */
            var cross = (dy0 * dx1) - (dy1 * dx0);
            var clockwise = (cross < 0);
            /* Going nearly straight? */
            if (Math.abs(cross) < 0.1) {
                verts.push(x1 - (perpx * innerWeight), y1 - (perpy * innerWeight));
                verts.push(x1 + (perpx * outerWeight), y1 + (perpy * outerWeight));
                continue;
            }
            /* p[x|y] is the miter point. pdist is the distance between miter point and p1. */
            var c1 = ((-perpx + x0) * (-perpy + y1)) - ((-perpx + x1) * (-perpy + y0));
            var c2 = ((-perp1x + x2) * (-perp1y + y1)) - ((-perp1x + x1) * (-perp1y + y2));
            var px = ((dx0 * c2) - (dx1 * c1)) / cross;
            var py = ((dy1 * c1) - (dy0 * c2)) / cross;
            var pdist = ((px - x1) * (px - x1)) + ((py - y1) * (py - y1));
            /* Inner miter point */
            var imx = x1 + ((px - x1) * innerWeight);
            var imy = y1 + ((py - y1) * innerWeight);
            /* Outer miter point */
            var omx = x1 - ((px - x1) * outerWeight);
            var omy = y1 - ((py - y1) * outerWeight);
            /* Is the inside miter point too far away, creating a spike? */
            var smallerInsideSegmentSq = Math.min((dx0 * dx0) + (dy0 * dy0), (dx1 * dx1) + (dy1 * dy1));
            var insideWeight = clockwise ? innerWeight : outerWeight;
            var smallerInsideDiagonalSq = smallerInsideSegmentSq + (insideWeight * insideWeight * widthSquared);
            var insideMiterOk = pdist <= smallerInsideDiagonalSq;
            if (insideMiterOk) {
                if (style.join === exports.LINE_JOIN.BEVEL || pdist / widthSquared > miterLimitSquared) {
                    if (clockwise) /* rotating at inner angle */ {
                        verts.push(imx, imy); // inner miter point
                        verts.push(x1 + (perpx * outerWeight), y1 + (perpy * outerWeight)); // first segment's outer vertex
                        verts.push(imx, imy); // inner miter point
                        verts.push(x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight)); // second segment's outer vertex
                    }
                    else /* rotating at outer angle */ {
                        verts.push(x1 - (perpx * innerWeight), y1 - (perpy * innerWeight)); // first segment's inner vertex
                        verts.push(omx, omy); // outer miter point
                        verts.push(x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight)); // second segment's outer vertex
                        verts.push(omx, omy); // outer miter point
                    }
                    indexCount += 2;
                }
                else if (style.join === exports.LINE_JOIN.ROUND) {
                    if (clockwise) /* arc is outside */ {
                        verts.push(imx, imy);
                        verts.push(x1 + (perpx * outerWeight), y1 + (perpy * outerWeight));
                        indexCount += round(x1, y1, x1 + (perpx * outerWeight), y1 + (perpy * outerWeight), x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight), verts, true) + 4;
                        verts.push(imx, imy);
                        verts.push(x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight));
                    }
                    else /* arc is inside */ {
                        verts.push(x1 - (perpx * innerWeight), y1 - (perpy * innerWeight));
                        verts.push(omx, omy);
                        indexCount += round(x1, y1, x1 - (perpx * innerWeight), y1 - (perpy * innerWeight), x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight), verts, false) + 4;
                        verts.push(x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight));
                        verts.push(omx, omy);
                    }
                }
                else {
                    verts.push(imx, imy);
                    verts.push(omx, omy);
                }
            }
            else // inside miter is NOT ok
             {
                verts.push(x1 - (perpx * innerWeight), y1 - (perpy * innerWeight)); // first segment's inner vertex
                verts.push(x1 + (perpx * outerWeight), y1 + (perpy * outerWeight)); // first segment's outer vertex
                if (style.join === exports.LINE_JOIN.BEVEL || pdist / widthSquared > miterLimitSquared) {
                    // Nothing needed
                }
                else if (style.join === exports.LINE_JOIN.ROUND) {
                    if (clockwise) /* arc is outside */ {
                        indexCount += round(x1, y1, x1 + (perpx * outerWeight), y1 + (perpy * outerWeight), x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight), verts, true) + 2;
                    }
                    else /* arc is inside */ {
                        indexCount += round(x1, y1, x1 - (perpx * innerWeight), y1 - (perpy * innerWeight), x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight), verts, false) + 2;
                    }
                }
                else {
                    if (clockwise) {
                        verts.push(omx, omy); // inner miter point
                        verts.push(omx, omy); // inner miter point
                    }
                    else {
                        verts.push(imx, imy); // outer miter point
                        verts.push(imx, imy); // outer miter point
                    }
                    indexCount += 2;
                }
                verts.push(x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight)); // second segment's inner vertex
                verts.push(x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight)); // second segment's outer vertex
                indexCount += 2;
            }
        }
        x0 = points[(length - 2) * 2];
        y0 = points[((length - 2) * 2) + 1];
        x1 = points[(length - 1) * 2];
        y1 = points[((length - 1) * 2) + 1];
        perpx = -(y0 - y1);
        perpy = x0 - x1;
        dist = Math.sqrt((perpx * perpx) + (perpy * perpy));
        perpx /= dist;
        perpy /= dist;
        perpx *= width;
        perpy *= width;
        verts.push(x1 - (perpx * innerWeight), y1 - (perpy * innerWeight));
        verts.push(x1 + (perpx * outerWeight), y1 + (perpy * outerWeight));
        if (!closedShape) {
            if (style.cap === exports.LINE_CAP.ROUND) {
                indexCount += round(x1 - (perpx * (innerWeight - outerWeight) * 0.5), y1 - (perpy * (innerWeight - outerWeight) * 0.5), x1 - (perpx * innerWeight), y1 - (perpy * innerWeight), x1 + (perpx * outerWeight), y1 + (perpy * outerWeight), verts, false) + 2;
            }
            else if (style.cap === exports.LINE_CAP.SQUARE) {
                indexCount += square(x1, y1, perpx, perpy, innerWeight, outerWeight, false, verts);
            }
        }
        var indices = graphicsGeometry.indices;
        var eps2 = GRAPHICS_CURVES.epsilon * GRAPHICS_CURVES.epsilon;
        // indices.push(indexStart);
        for (var i = indexStart; i < indexCount + indexStart - 2; ++i) {
            x0 = verts[(i * 2)];
            y0 = verts[(i * 2) + 1];
            x1 = verts[(i + 1) * 2];
            y1 = verts[((i + 1) * 2) + 1];
            x2 = verts[(i + 2) * 2];
            y2 = verts[((i + 2) * 2) + 1];
            /* Skip zero area triangles */
            if (Math.abs((x0 * (y1 - y2)) + (x1 * (y2 - y0)) + (x2 * (y0 - y1))) < eps2) {
                continue;
            }
            indices.push(i, i + 1, i + 2);
        }
    }
    /**
     * Builds a line to draw using the gl.drawArrays(gl.LINES) method
     *
     * Ignored from docs since it is not directly exposed.
     *
     * @ignore
     * @private
     * @param {PIXI.GraphicsData} graphicsData - The graphics object containing all the necessary properties
     * @param {PIXI.GraphicsGeometry} graphicsGeometry - Geometry where to append output
     */
    function buildNativeLine(graphicsData, graphicsGeometry) {
        var i = 0;
        var shape = graphicsData.shape;
        var points = graphicsData.points || shape.points;
        var closedShape = shape.type !== math.SHAPES.POLY || shape.closeStroke;
        if (points.length === 0)
            { return; }
        var verts = graphicsGeometry.points;
        var indices = graphicsGeometry.indices;
        var length = points.length / 2;
        var startIndex = verts.length / 2;
        var currentIndex = startIndex;
        verts.push(points[0], points[1]);
        for (i = 1; i < length; i++) {
            verts.push(points[i * 2], points[(i * 2) + 1]);
            indices.push(currentIndex, currentIndex + 1);
            currentIndex++;
        }
        if (closedShape) {
            indices.push(currentIndex, startIndex);
        }
    }
    /**
     * Builds a line to draw
     *
     * Ignored from docs since it is not directly exposed.
     *
     * @ignore
     * @private
     * @param {PIXI.GraphicsData} graphicsData - The graphics object containing all the necessary properties
     * @param {PIXI.GraphicsGeometry} graphicsGeometry - Geometry where to append output
     */
    function buildLine(graphicsData, graphicsGeometry) {
        if (graphicsData.lineStyle.native) {
            buildNativeLine(graphicsData, graphicsGeometry);
        }
        else {
            buildNonNativeLine(graphicsData, graphicsGeometry);
        }
    }

    /**
     * Utilities for arc curves.
     *
     * @private
     */
    var ArcUtils = /** @class */ (function () {
        function ArcUtils() {
        }
        /**
         * The arcTo() method creates an arc/curve between two tangents on the canvas.
         *
         * "borrowed" from https://code.google.com/p/fxcanvas/ - thanks google!
         *
         * @private
         * @param x1 - The x-coordinate of the beginning of the arc
         * @param y1 - The y-coordinate of the beginning of the arc
         * @param x2 - The x-coordinate of the end of the arc
         * @param y2 - The y-coordinate of the end of the arc
         * @param radius - The radius of the arc
         * @return - If the arc length is valid, return center of circle, radius and other info otherwise `null`.
         */
        ArcUtils.curveTo = function (x1, y1, x2, y2, radius, points) {
            var fromX = points[points.length - 2];
            var fromY = points[points.length - 1];
            var a1 = fromY - y1;
            var b1 = fromX - x1;
            var a2 = y2 - y1;
            var b2 = x2 - x1;
            var mm = Math.abs((a1 * b2) - (b1 * a2));
            if (mm < 1.0e-8 || radius === 0) {
                if (points[points.length - 2] !== x1 || points[points.length - 1] !== y1) {
                    points.push(x1, y1);
                }
                return null;
            }
            var dd = (a1 * a1) + (b1 * b1);
            var cc = (a2 * a2) + (b2 * b2);
            var tt = (a1 * a2) + (b1 * b2);
            var k1 = radius * Math.sqrt(dd) / mm;
            var k2 = radius * Math.sqrt(cc) / mm;
            var j1 = k1 * tt / dd;
            var j2 = k2 * tt / cc;
            var cx = (k1 * b2) + (k2 * b1);
            var cy = (k1 * a2) + (k2 * a1);
            var px = b1 * (k2 + j1);
            var py = a1 * (k2 + j1);
            var qx = b2 * (k1 + j2);
            var qy = a2 * (k1 + j2);
            var startAngle = Math.atan2(py - cy, px - cx);
            var endAngle = Math.atan2(qy - cy, qx - cx);
            return {
                cx: (cx + x1),
                cy: (cy + y1),
                radius: radius,
                startAngle: startAngle,
                endAngle: endAngle,
                anticlockwise: (b1 * a2 > b2 * a1),
            };
        };
        /* eslint-disable max-len */
        /**
         * The arc method creates an arc/curve (used to create circles, or parts of circles).
         *
         * @private
         * @param startX - Start x location of arc
         * @param startY - Start y location of arc
         * @param cx - The x-coordinate of the center of the circle
         * @param cy - The y-coordinate of the center of the circle
         * @param radius - The radius of the circle
         * @param startAngle - The starting angle, in radians (0 is at the 3 o'clock position
         *  of the arc's circle)
         * @param endAngle - The ending angle, in radians
         * @param anticlockwise - Specifies whether the drawing should be
         *  counter-clockwise or clockwise. False is default, and indicates clockwise, while true
         *  indicates counter-clockwise.
         * @param points - Collection of points to add to
         */
        ArcUtils.arc = function (_startX, _startY, cx, cy, radius, startAngle, endAngle, _anticlockwise, points) {
            var sweep = endAngle - startAngle;
            var n = GRAPHICS_CURVES._segmentsCount(Math.abs(sweep) * radius, Math.ceil(Math.abs(sweep) / math.PI_2) * 40);
            var theta = (sweep) / (n * 2);
            var theta2 = theta * 2;
            var cTheta = Math.cos(theta);
            var sTheta = Math.sin(theta);
            var segMinus = n - 1;
            var remainder = (segMinus % 1) / segMinus;
            for (var i = 0; i <= segMinus; ++i) {
                var real = i + (remainder * i);
                var angle = ((theta) + startAngle + (theta2 * real));
                var c = Math.cos(angle);
                var s = -Math.sin(angle);
                points.push((((cTheta * c) + (sTheta * s)) * radius) + cx, (((cTheta * -s) + (sTheta * c)) * radius) + cy);
            }
        };
        return ArcUtils;
    }());

    /**
     * Utilities for bezier curves
     *
     * @private
     */
    var BezierUtils = /** @class */ (function () {
        function BezierUtils() {
        }
        /**
         * Calculate length of bezier curve.
         * Analytical solution is impossible, since it involves an integral that does not integrate in general.
         * Therefore numerical solution is used.
         *
         * @private
         * @param fromX - Starting point x
         * @param fromY - Starting point y
         * @param cpX - Control point x
         * @param cpY - Control point y
         * @param cpX2 - Second Control point x
         * @param cpY2 - Second Control point y
         * @param toX - Destination point x
         * @param toY - Destination point y
         * @return - Length of bezier curve
         */
        BezierUtils.curveLength = function (fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY) {
            var n = 10;
            var result = 0.0;
            var t = 0.0;
            var t2 = 0.0;
            var t3 = 0.0;
            var nt = 0.0;
            var nt2 = 0.0;
            var nt3 = 0.0;
            var x = 0.0;
            var y = 0.0;
            var dx = 0.0;
            var dy = 0.0;
            var prevX = fromX;
            var prevY = fromY;
            for (var i = 1; i <= n; ++i) {
                t = i / n;
                t2 = t * t;
                t3 = t2 * t;
                nt = (1.0 - t);
                nt2 = nt * nt;
                nt3 = nt2 * nt;
                x = (nt3 * fromX) + (3.0 * nt2 * t * cpX) + (3.0 * nt * t2 * cpX2) + (t3 * toX);
                y = (nt3 * fromY) + (3.0 * nt2 * t * cpY) + (3 * nt * t2 * cpY2) + (t3 * toY);
                dx = prevX - x;
                dy = prevY - y;
                prevX = x;
                prevY = y;
                result += Math.sqrt((dx * dx) + (dy * dy));
            }
            return result;
        };
        /**
         * Calculate the points for a bezier curve and then draws it.
         *
         * Ignored from docs since it is not directly exposed.
         *
         * @ignore
         * @param cpX - Control point x
         * @param cpY - Control point y
         * @param cpX2 - Second Control point x
         * @param cpY2 - Second Control point y
         * @param toX - Destination point x
         * @param toY - Destination point y
         * @param points - Path array to push points into
         */
        BezierUtils.curveTo = function (cpX, cpY, cpX2, cpY2, toX, toY, points) {
            var fromX = points[points.length - 2];
            var fromY = points[points.length - 1];
            points.length -= 2;
            var n = GRAPHICS_CURVES._segmentsCount(BezierUtils.curveLength(fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY));
            var dt = 0;
            var dt2 = 0;
            var dt3 = 0;
            var t2 = 0;
            var t3 = 0;
            points.push(fromX, fromY);
            for (var i = 1, j = 0; i <= n; ++i) {
                j = i / n;
                dt = (1 - j);
                dt2 = dt * dt;
                dt3 = dt2 * dt;
                t2 = j * j;
                t3 = t2 * j;
                points.push((dt3 * fromX) + (3 * dt2 * j * cpX) + (3 * dt * t2 * cpX2) + (t3 * toX), (dt3 * fromY) + (3 * dt2 * j * cpY) + (3 * dt * t2 * cpY2) + (t3 * toY));
            }
        };
        return BezierUtils;
    }());

    /**
     * Utilities for quadratic curves.
     *
     * @private
     */
    var QuadraticUtils = /** @class */ (function () {
        function QuadraticUtils() {
        }
        /**
         * Calculate length of quadratic curve
         * @see {@link http://www.malczak.linuxpl.com/blog/quadratic-bezier-curve-length/}
         * for the detailed explanation of math behind this.
         *
         * @private
         * @param fromX - x-coordinate of curve start point
         * @param fromY - y-coordinate of curve start point
         * @param cpX - x-coordinate of curve control point
         * @param cpY - y-coordinate of curve control point
         * @param toX - x-coordinate of curve end point
         * @param toY - y-coordinate of curve end point
         * @return - Length of quadratic curve
         */
        QuadraticUtils.curveLength = function (fromX, fromY, cpX, cpY, toX, toY) {
            var ax = fromX - (2.0 * cpX) + toX;
            var ay = fromY - (2.0 * cpY) + toY;
            var bx = (2.0 * cpX) - (2.0 * fromX);
            var by = (2.0 * cpY) - (2.0 * fromY);
            var a = 4.0 * ((ax * ax) + (ay * ay));
            var b = 4.0 * ((ax * bx) + (ay * by));
            var c = (bx * bx) + (by * by);
            var s = 2.0 * Math.sqrt(a + b + c);
            var a2 = Math.sqrt(a);
            var a32 = 2.0 * a * a2;
            var c2 = 2.0 * Math.sqrt(c);
            var ba = b / a2;
            return ((a32 * s)
                + (a2 * b * (s - c2))
                + (((4.0 * c * a) - (b * b))
                    * Math.log(((2.0 * a2) + ba + s) / (ba + c2)))) / (4.0 * a32);
        };
        /**
         * Calculate the points for a quadratic bezier curve and then draws it.
         * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c
         *
         * @private
         * @param cpX - Control point x
         * @param cpY - Control point y
         * @param toX - Destination point x
         * @param toY - Destination point y
         * @param points - Points to add segments to.
         */
        QuadraticUtils.curveTo = function (cpX, cpY, toX, toY, points) {
            var fromX = points[points.length - 2];
            var fromY = points[points.length - 1];
            var n = GRAPHICS_CURVES._segmentsCount(QuadraticUtils.curveLength(fromX, fromY, cpX, cpY, toX, toY));
            var xa = 0;
            var ya = 0;
            for (var i = 1; i <= n; ++i) {
                var j = i / n;
                xa = fromX + ((cpX - fromX) * j);
                ya = fromY + ((cpY - fromY) * j);
                points.push(xa + (((cpX + ((toX - cpX) * j)) - xa) * j), ya + (((cpY + ((toY - cpY) * j)) - ya) * j));
            }
        };
        return QuadraticUtils;
    }());

    /**
     * A structure to hold interim batch objects for Graphics.
     *
     * @memberof PIXI.graphicsUtils
     */
    var BatchPart = /** @class */ (function () {
        function BatchPart() {
            this.reset();
        }
        /** Begin batch part. */
        BatchPart.prototype.begin = function (style, startIndex, attribStart) {
            this.reset();
            this.style = style;
            this.start = startIndex;
            this.attribStart = attribStart;
        };
        /** End batch part. */
        BatchPart.prototype.end = function (endIndex, endAttrib) {
            this.attribSize = endAttrib - this.attribStart;
            this.size = endIndex - this.start;
        };
        BatchPart.prototype.reset = function () {
            this.style = null;
            this.size = 0;
            this.start = 0;
            this.attribStart = 0;
            this.attribSize = 0;
        };
        return BatchPart;
    }());

    /**
     * Generalized convenience utilities for Graphics.
     *
     * @namespace graphicsUtils
     * @memberof PIXI
     */
    var _a;
    /**
     * Map of fill commands for each shape type.
     *
     * @memberof PIXI.graphicsUtils
     * @member {Object} FILL_COMMANDS
     */
    var FILL_COMMANDS = (_a = {},
        _a[math.SHAPES.POLY] = buildPoly,
        _a[math.SHAPES.CIRC] = buildCircle,
        _a[math.SHAPES.ELIP] = buildCircle,
        _a[math.SHAPES.RECT] = buildRectangle,
        _a[math.SHAPES.RREC] = buildRoundedRectangle,
        _a);
    /**
     * Batch pool, stores unused batches for preventing allocations.
     *
     * @memberof PIXI.graphicsUtils
     * @member {Array<PIXI.graphicsUtils.BatchPart>} BATCH_POOL
     */
    var BATCH_POOL = [];
    /**
     * Draw call pool, stores unused draw calls for preventing allocations.
     *
     * @memberof PIXI.graphicsUtils
     * @member {Array<PIXI.BatchDrawCall>} DRAW_CALL_POOL
     */
    var DRAW_CALL_POOL = [];

    /**
     * A class to contain data useful for Graphics objects
     *
     * @memberof PIXI
     */
    var GraphicsData = /** @class */ (function () {
        /**
         * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - The shape object to draw.
         * @param fillStyle - the width of the line to draw
         * @param lineStyle - the color of the line to draw
         * @param matrix - Transform matrix
         */
        function GraphicsData(shape, fillStyle, lineStyle, matrix) {
            if (fillStyle === void 0) { fillStyle = null; }
            if (lineStyle === void 0) { lineStyle = null; }
            if (matrix === void 0) { matrix = null; }
            /** The collection of points. */
            this.points = [];
            /** The collection of holes. */
            this.holes = [];
            this.shape = shape;
            this.lineStyle = lineStyle;
            this.fillStyle = fillStyle;
            this.matrix = matrix;
            this.type = shape.type;
        }
        /**
         * Creates a new GraphicsData object with the same values as this one.
         *
         * @return - Cloned GraphicsData object
         */
        GraphicsData.prototype.clone = function () {
            return new GraphicsData(this.shape, this.fillStyle, this.lineStyle, this.matrix);
        };
        /** Destroys the Graphics data. */
        GraphicsData.prototype.destroy = function () {
            this.shape = null;
            this.holes.length = 0;
            this.holes = null;
            this.points.length = 0;
            this.points = null;
            this.lineStyle = null;
            this.fillStyle = null;
        };
        return GraphicsData;
    }());

    var tmpPoint = new math.Point();
    var tmpBounds = new display.Bounds();
    /**
     * The Graphics class contains methods used to draw primitive shapes such as lines, circles and
     * rectangles to the display, and to color and fill them.
     *
     * GraphicsGeometry is designed to not be continually updating the geometry since it's expensive
     * to re-tesselate using **earcut**. Consider using {@link PIXI.Mesh} for this use-case, it's much faster.
     *
     * @memberof PIXI
     */
    var GraphicsGeometry = /** @class */ (function (_super) {
        __extends(GraphicsGeometry, _super);
        // eslint-disable-next-line @typescript-eslint/no-useless-constructor
        function GraphicsGeometry() {
            var _this = _super.call(this) || this;
            /**
             * Minimal distance between points that are considered different.
             * Affects line tesselation.
             */
            _this.closePointEps = 1e-4;
            /** Padding to add to the bounds. */
            _this.boundsPadding = 0;
            _this.uvsFloat32 = null;
            _this.indicesUint16 = null;
            _this.batchable = false;
            /** An array of points to draw, 2 numbers per point */
            _this.points = [];
            /** The collection of colors */
            _this.colors = [];
            /** The UVs collection */
            _this.uvs = [];
            /** The indices of the vertices */
            _this.indices = [];
            /** Reference to the texture IDs. */
            _this.textureIds = [];
            /**
             * The collection of drawn shapes.
             *
             * @member {PIXI.GraphicsData[]}
             */
            _this.graphicsData = [];
            /**
             * List of current draw calls drived from the batches.
             *
             * @member {PIXI.BatchDrawCall[]}
             */
            _this.drawCalls = [];
            /** Batches need to regenerated if the geometry is updated. */
            _this.batchDirty = -1;
            /**
             * Intermediate abstract format sent to batch system.
             * Can be converted to drawCalls or to batchable objects.
             *
             * @member {PIXI.graphicsUtils.BatchPart[]}
             */
            _this.batches = [];
            /** Used to detect if the graphics object has changed. */
            _this.dirty = 0;
            /** Used to check if the cache is dirty. */
            _this.cacheDirty = -1;
            /** Used to detect if we cleared the graphicsData. */
            _this.clearDirty = 0;
            /** Index of the last batched shape in the stack of calls. */
            _this.shapeIndex = 0;
            /** Cached bounds. */
            _this._bounds = new display.Bounds();
            /** The bounds dirty flag. */
            _this.boundsDirty = -1;
            return _this;
        }
        Object.defineProperty(GraphicsGeometry.prototype, "bounds", {
            /**
             * Get the current bounds of the graphic geometry.
             *
             * @readonly
             */
            get: function () {
                if (this.boundsDirty !== this.dirty) {
                    this.boundsDirty = this.dirty;
                    this.calculateBounds();
                }
                return this._bounds;
            },
            enumerable: false,
            configurable: true
        });
        /**
         * Call if you changed graphicsData manually.
         * Empties all batch buffers.
         */
        GraphicsGeometry.prototype.invalidate = function () {
            this.boundsDirty = -1;
            this.dirty++;
            this.batchDirty++;
            this.shapeIndex = 0;
            this.points.length = 0;
            this.colors.length = 0;
            this.uvs.length = 0;
            this.indices.length = 0;
            this.textureIds.length = 0;
            for (var i = 0; i < this.drawCalls.length; i++) {
                this.drawCalls[i].texArray.clear();
                DRAW_CALL_POOL.push(this.drawCalls[i]);
            }
            this.drawCalls.length = 0;
            for (var i = 0; i < this.batches.length; i++) {
                var batchPart = this.batches[i];
                batchPart.reset();
                BATCH_POOL.push(batchPart);
            }
            this.batches.length = 0;
        };
        /**
         * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
         *
         * @return - This GraphicsGeometry object. Good for chaining method calls
         */
        GraphicsGeometry.prototype.clear = function () {
            if (this.graphicsData.length > 0) {
                this.invalidate();
                this.clearDirty++;
                this.graphicsData.length = 0;
            }
            return this;
        };
        /**
         * Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon.
         *
         * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - The shape object to draw.
         * @param fillStyle - Defines style of the fill.
         * @param lineStyle - Defines style of the lines.
         * @param matrix - Transform applied to the points of the shape.
         * @return - Returns geometry for chaining.
         */
        GraphicsGeometry.prototype.drawShape = function (shape, fillStyle, lineStyle, matrix) {
            if (fillStyle === void 0) { fillStyle = null; }
            if (lineStyle === void 0) { lineStyle = null; }
            if (matrix === void 0) { matrix = null; }
            var data = new GraphicsData(shape, fillStyle, lineStyle, matrix);
            this.graphicsData.push(data);
            this.dirty++;
            return this;
        };
        /**
         * Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon.
         *
         * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - The shape object to draw.
         * @param matrix - Transform applied to the points of the shape.
         * @return - Returns geometry for chaining.
         */
        GraphicsGeometry.prototype.drawHole = function (shape, matrix) {
            if (matrix === void 0) { matrix = null; }
            if (!this.graphicsData.length) {
                return null;
            }
            var data = new GraphicsData(shape, null, null, matrix);
            var lastShape = this.graphicsData[this.graphicsData.length - 1];
            data.lineStyle = lastShape.lineStyle;
            lastShape.holes.push(data);
            this.dirty++;
            return this;
        };
        /** Destroys the GraphicsGeometry object. */
        GraphicsGeometry.prototype.destroy = function () {
            _super.prototype.destroy.call(this);
            // destroy each of the GraphicsData objects
            for (var i = 0; i < this.graphicsData.length; ++i) {
                this.graphicsData[i].destroy();
            }
            this.points.length = 0;
            this.points = null;
            this.colors.length = 0;
            this.colors = null;
            this.uvs.length = 0;
            this.uvs = null;
            this.indices.length = 0;
            this.indices = null;
            this.indexBuffer.destroy();
            this.indexBuffer = null;
            this.graphicsData.length = 0;
            this.graphicsData = null;
            this.drawCalls.length = 0;
            this.drawCalls = null;
            this.batches.length = 0;
            this.batches = null;
            this._bounds = null;
        };
        /**
         * Check to see if a point is contained within this geometry.
         *
         * @param point - Point to check if it's contained.
         * @return {Boolean} `true` if the point is contained within geometry.
         */
        GraphicsGeometry.prototype.containsPoint = function (point) {
            var graphicsData = this.graphicsData;
            for (var i = 0; i < graphicsData.length; ++i) {
                var data = graphicsData[i];
                if (!data.fillStyle.visible) {
                    continue;
                }
                // only deal with fills..
                if (data.shape) {
                    if (data.matrix) {
                        data.matrix.applyInverse(point, tmpPoint);
                    }
                    else {
                        tmpPoint.copyFrom(point);
                    }
                    if (data.shape.contains(tmpPoint.x, tmpPoint.y)) {
                        var hitHole = false;
                        if (data.holes) {
                            for (var i_1 = 0; i_1 < data.holes.length; i_1++) {
                                var hole = data.holes[i_1];
                                if (hole.shape.contains(tmpPoint.x, tmpPoint.y)) {
                                    hitHole = true;
                                    break;
                                }
                            }
                        }
                        if (!hitHole) {
                            return true;
                        }
                    }
                }
            }
            return false;
        };
        /**
         * Generates intermediate batch data. Either gets converted to drawCalls
         * or used to convert to batch objects directly by the Graphics object.
         *
         * @param allow32Indices - Allow using 32-bit indices for preventing artifacts when more that 65535 vertices
         */
        GraphicsGeometry.prototype.updateBatches = function (allow32Indices) {
            if (!this.graphicsData.length) {
                this.batchable = true;
                return;
            }
            if (!this.validateBatching()) {
                return;
            }
            this.cacheDirty = this.dirty;
            var uvs = this.uvs;
            var graphicsData = this.graphicsData;
            var batchPart = null;
            var currentStyle = null;
            if (this.batches.length > 0) {
                batchPart = this.batches[this.batches.length - 1];
                currentStyle = batchPart.style;
            }
            for (var i = this.shapeIndex; i < graphicsData.length; i++) {
                this.shapeIndex++;
                var data = graphicsData[i];
                var fillStyle = data.fillStyle;
                var lineStyle = data.lineStyle;
                var command = FILL_COMMANDS[data.type];
                // build out the shapes points..
                command.build(data);
                if (data.matrix) {
                    this.transformPoints(data.points, data.matrix);
                }
                if (fillStyle.visible || lineStyle.visible) {
                    this.processHoles(data.holes);
                }
                for (var j = 0; j < 2; j++) {
                    var style = (j === 0) ? fillStyle : lineStyle;
                    if (!style.visible)
                        { continue; }
                    var nextTexture = style.texture.baseTexture;
                    var index_1 = this.indices.length;
                    var attribIndex = this.points.length / 2;
                    nextTexture.wrapMode = constants.WRAP_MODES.REPEAT;
                    if (j === 0) {
                        this.processFill(data);
                    }
                    else {
                        this.processLine(data);
                    }
                    var size = (this.points.length / 2) - attribIndex;
                    if (size === 0)
                        { continue; }
                    // close batch if style is different
                    if (batchPart && !this._compareStyles(currentStyle, style)) {
                        batchPart.end(index_1, attribIndex);
                        batchPart = null;
                    }
                    // spawn new batch if its first batch or previous was closed
                    if (!batchPart) {
                        batchPart = BATCH_POOL.pop() || new BatchPart();
                        batchPart.begin(style, index_1, attribIndex);
                        this.batches.push(batchPart);
                        currentStyle = style;
                    }
                    this.addUvs(this.points, uvs, style.texture, attribIndex, size, style.matrix);
                }
            }
            var index = this.indices.length;
            var attrib = this.points.length / 2;
            if (batchPart) {
                batchPart.end(index, attrib);
            }
            if (this.batches.length === 0) {
                // there are no visible styles in GraphicsData
                // its possible that someone wants Graphics just for the bounds
                this.batchable = true;
                return;
            }
            // prevent allocation when length is same as buffer
            if (this.indicesUint16 && this.indices.length === this.indicesUint16.length) {
                this.indicesUint16.set(this.indices);
            }
            else {
                var need32 = attrib > 0xffff && allow32Indices;
                this.indicesUint16 = need32 ? new Uint32Array(this.indices) : new Uint16Array(this.indices);
            }
            // TODO make this a const..
            this.batchable = this.isBatchable();
            if (this.batchable) {
                this.packBatches();
            }
            else {
                this.buildDrawCalls();
            }
        };
        /**
         * Affinity check
         *
         * @param styleA
         * @param styleB
         */
        GraphicsGeometry.prototype._compareStyles = function (styleA, styleB) {
            if (!styleA || !styleB) {
                return false;
            }
            if (styleA.texture.baseTexture !== styleB.texture.baseTexture) {
                return false;
            }
            if (styleA.color + styleA.alpha !== styleB.color + styleB.alpha) {
                return false;
            }
            if (!!styleA.native !== !!styleB.native) {
                return false;
            }
            return true;
        };
        /** Test geometry for batching process. */
        GraphicsGeometry.prototype.validateBatching = function () {
            if (this.dirty === this.cacheDirty || !this.graphicsData.length) {
                return false;
            }
            for (var i = 0, l = this.graphicsData.length; i < l; i++) {
                var data = this.graphicsData[i];
                var fill = data.fillStyle;
                var line = data.lineStyle;
                if (fill && !fill.texture.baseTexture.valid)
                    { return false; }
                if (line && !line.texture.baseTexture.valid)
                    { return false; }
            }
            return true;
        };
        /** Offset the indices so that it works with the batcher. */
        GraphicsGeometry.prototype.packBatches = function () {
            this.batchDirty++;
            this.uvsFloat32 = new Float32Array(this.uvs);
            var batches = this.batches;
            for (var i = 0, l = batches.length; i < l; i++) {
                var batch = batches[i];
                for (var j = 0; j < batch.size; j++) {
                    var index = batch.start + j;
                    this.indicesUint16[index] = this.indicesUint16[index] - batch.attribStart;
                }
            }
        };
        /**
         * Checks to see if this graphics geometry can be batched.
         * Currently it needs to be small enough and not contain any native lines.
         */
        GraphicsGeometry.prototype.isBatchable = function () {
            // prevent heavy mesh batching
            if (this.points.length > 0xffff * 2) {
                return false;
            }
            var batches = this.batches;
            for (var i = 0; i < batches.length; i++) {
                if (batches[i].style.native) {
                    return false;
                }
            }
            return (this.points.length < GraphicsGeometry.BATCHABLE_SIZE * 2);
        };
        /** Converts intermediate batches data to drawCalls. */
        GraphicsGeometry.prototype.buildDrawCalls = function () {
            var TICK = ++core.BaseTexture._globalBatch;
            for (var i = 0; i < this.drawCalls.length; i++) {
                this.drawCalls[i].texArray.clear();
                DRAW_CALL_POOL.push(this.drawCalls[i]);
            }
            this.drawCalls.length = 0;
            var colors = this.colors;
            var textureIds = this.textureIds;
            var currentGroup = DRAW_CALL_POOL.pop();
            if (!currentGroup) {
                currentGroup = new core.BatchDrawCall();
                currentGroup.texArray = new core.BatchTextureArray();
            }
            currentGroup.texArray.count = 0;
            currentGroup.start = 0;
            currentGroup.size = 0;
            currentGroup.type = constants.DRAW_MODES.TRIANGLES;
            var textureCount = 0;
            var currentTexture = null;
            var textureId = 0;
            var native = false;
            var drawMode = constants.DRAW_MODES.TRIANGLES;
            var index = 0;
            this.drawCalls.push(currentGroup);
            // TODO - this can be simplified
            for (var i = 0; i < this.batches.length; i++) {
                var data = this.batches[i];
                // TODO add some full on MAX_TEXTURE CODE..
                var MAX_TEXTURES = 8;
                // Forced cast for checking `native` without errors
                var style = data.style;
                var nextTexture = style.texture.baseTexture;
                if (native !== !!style.native) {
                    native = !!style.native;
                    drawMode = native ? constants.DRAW_MODES.LINES : constants.DRAW_MODES.TRIANGLES;
                    // force the batch to break!
                    currentTexture = null;
                    textureCount = MAX_TEXTURES;
                    TICK++;
                }
                if (currentTexture !== nextTexture) {
                    currentTexture = nextTexture;
                    if (nextTexture._batchEnabled !== TICK) {
                        if (textureCount === MAX_TEXTURES) {
                            TICK++;
                            textureCount = 0;
                            if (currentGroup.size > 0) {
                                currentGroup = DRAW_CALL_POOL.pop();
                                if (!currentGroup) {
                                    currentGroup = new core.BatchDrawCall();
                                    currentGroup.texArray = new core.BatchTextureArray();
                                }
                                this.drawCalls.push(currentGroup);
                            }
                            currentGroup.start = index;
                            currentGroup.size = 0;
                            currentGroup.texArray.count = 0;
                            currentGroup.type = drawMode;
                        }
                        // TODO add this to the render part..
                        // Hack! Because texture has protected `touched`
                        nextTexture.touched = 1; // touch;
                        nextTexture._batchEnabled = TICK;
                        nextTexture._batchLocation = textureCount;
                        nextTexture.wrapMode = constants.WRAP_MODES.REPEAT;
                        currentGroup.texArray.elements[currentGroup.texArray.count++] = nextTexture;
                        textureCount++;
                    }
                }
                currentGroup.size += data.size;
                index += data.size;
                textureId = nextTexture._batchLocation;
                this.addColors(colors, style.color, style.alpha, data.attribSize, data.attribStart);
                this.addTextureIds(textureIds, textureId, data.attribSize, data.attribStart);
            }
            core.BaseTexture._globalBatch = TICK;
            // upload..
            // merge for now!
            this.packAttributes();
        };
        /** Packs attributes to single buffer. */
        GraphicsGeometry.prototype.packAttributes = function () {
            var verts = this.points;
            var uvs = this.uvs;
            var colors = this.colors;
            var textureIds = this.textureIds;
            // verts are 2 positions.. so we * by 3 as there are 6 properties.. then 4 cos its bytes
            var glPoints = new ArrayBuffer(verts.length * 3 * 4);
            var f32 = new Float32Array(glPoints);
            var u32 = new Uint32Array(glPoints);
            var p = 0;
            for (var i = 0; i < verts.length / 2; i++) {
                f32[p++] = verts[i * 2];
                f32[p++] = verts[(i * 2) + 1];
                f32[p++] = uvs[i * 2];
                f32[p++] = uvs[(i * 2) + 1];
                u32[p++] = colors[i];
                f32[p++] = textureIds[i];
            }
            this._buffer.update(glPoints);
            this._indexBuffer.update(this.indicesUint16);
        };
        /** Process fill part of Graphics. */
        GraphicsGeometry.prototype.processFill = function (data) {
            if (data.holes.length) {
                buildPoly.triangulate(data, this);
            }
            else {
                var command = FILL_COMMANDS[data.type];
                command.triangulate(data, this);
            }
        };
        /** Process line part of Graphics. */
        GraphicsGeometry.prototype.processLine = function (data) {
            buildLine(data, this);
            for (var i = 0; i < data.holes.length; i++) {
                buildLine(data.holes[i], this);
            }
        };
        /** Process the holes data. */
        GraphicsGeometry.prototype.processHoles = function (holes) {
            for (var i = 0; i < holes.length; i++) {
                var hole = holes[i];
                var command = FILL_COMMANDS[hole.type];
                command.build(hole);
                if (hole.matrix) {
                    this.transformPoints(hole.points, hole.matrix);
                }
            }
        };
        /** Update the local bounds of the object. Expensive to use performance-wise. */
        GraphicsGeometry.prototype.calculateBounds = function () {
            var bounds = this._bounds;
            var sequenceBounds = tmpBounds;
            var curMatrix = math.Matrix.IDENTITY;
            this._bounds.clear();
            sequenceBounds.clear();
            for (var i = 0; i < this.graphicsData.length; i++) {
                var data = this.graphicsData[i];
                var shape = data.shape;
                var type = data.type;
                var lineStyle = data.lineStyle;
                var nextMatrix = data.matrix || math.Matrix.IDENTITY;
                var lineWidth = 0.0;
                if (lineStyle && lineStyle.visible) {
                    lineWidth = lineStyle.width * Math.max(0, lineStyle.alignment);
                }
                if (curMatrix !== nextMatrix) {
                    if (!sequenceBounds.isEmpty()) {
                        bounds.addBoundsMatrix(sequenceBounds, curMatrix);
                        sequenceBounds.clear();
                    }
                    curMatrix = nextMatrix;
                }
                if (type === math.SHAPES.RECT || type === math.SHAPES.RREC) {
                    var rect = shape;
                    sequenceBounds.addFramePad(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, lineWidth, lineWidth);
                }
                else if (type === math.SHAPES.CIRC) {
                    var circle = shape;
                    sequenceBounds.addFramePad(circle.x, circle.y, circle.x, circle.y, circle.radius + lineWidth, circle.radius + lineWidth);
                }
                else if (type === math.SHAPES.ELIP) {
                    var ellipse = shape;
                    sequenceBounds.addFramePad(ellipse.x, ellipse.y, ellipse.x, ellipse.y, ellipse.width + lineWidth, ellipse.height + lineWidth);
                }
                else {
                    var poly = shape;
                    // adding directly to the bounds
                    bounds.addVerticesMatrix(curMatrix, poly.points, 0, poly.points.length, lineWidth, lineWidth);
                }
            }
            if (!sequenceBounds.isEmpty()) {
                bounds.addBoundsMatrix(sequenceBounds, curMatrix);
            }
            bounds.pad(this.boundsPadding, this.boundsPadding);
        };
        /**
         * Transform points using matrix.
         *
         * @param points - Points to transform
         * @param matrix - Transform matrix
         */
        GraphicsGeometry.prototype.transformPoints = function (points, matrix) {
            for (var i = 0; i < points.length / 2; i++) {
                var x = points[(i * 2)];
                var y = points[(i * 2) + 1];
                points[(i * 2)] = (matrix.a * x) + (matrix.c * y) + matrix.tx;
                points[(i * 2) + 1] = (matrix.b * x) + (matrix.d * y) + matrix.ty;
            }
        };
        /**
         * Add colors.
         *
         * @param colors - List of colors to add to
         * @param color - Color to add
         * @param alpha - Alpha to use
         * @param size - Number of colors to add
         * @param offset
         */
        GraphicsGeometry.prototype.addColors = function (colors, color, alpha, size, offset) {
            if (offset === void 0) { offset = 0; }
            // TODO use the premultiply bits Ivan added
            var rgb = (color >> 16) + (color & 0xff00) + ((color & 0xff) << 16);
            var rgba = utils.premultiplyTint(rgb, alpha);
            colors.length = Math.max(colors.length, offset + size);
            for (var i = 0; i < size; i++) {
                colors[offset + i] = rgba;
            }
        };
        /** Add texture id that the shader/fragment wants to use. */
        GraphicsGeometry.prototype.addTextureIds = function (textureIds, id, size, offset) {
            if (offset === void 0) { offset = 0; }
            textureIds.length = Math.max(textureIds.length, offset + size);
            for (var i = 0; i < size; i++) {
                textureIds[offset + i] = id;
            }
        };
        /**
         * Generates the UVs for a shape.
         *
         * @param verts - Vertices
         * @param uvs - UVs
         * @param texture - Reference to Texture
         * @param start - Index buffer start index.
         * @param size - The size/length for index buffer.
         * @param matrix - Optional transform for all points.
         */
        GraphicsGeometry.prototype.addUvs = function (verts, uvs, texture, start, size, matrix) {
            if (matrix === void 0) { matrix = null; }
            var index = 0;
            var uvsStart = uvs.length;
            var frame = texture.frame;
            while (index < size) {
                var x = verts[(start + index) * 2];
                var y = verts[((start + index) * 2) + 1];
                if (matrix) {
                    var nx = (matrix.a * x) + (matrix.c * y) + matrix.tx;
                    y = (matrix.b * x) + (matrix.d * y) + matrix.ty;
                    x = nx;
                }
                index++;
                uvs.push(x / frame.width, y / frame.height);
            }
            var baseTexture = texture.baseTexture;
            if (frame.width < baseTexture.width
                || frame.height < baseTexture.height) {
                this.adjustUvs(uvs, texture, uvsStart, size);
            }
        };
        /**
         * Modify uvs array according to position of texture region
         * Does not work with rotated or trimmed textures
         *
         * @param uvs - array
         * @param texture - region
         * @param start - starting index for uvs
         * @param size - how many points to adjust
         */
        GraphicsGeometry.prototype.adjustUvs = function (uvs, texture, start, size) {
            var baseTexture = texture.baseTexture;
            var eps = 1e-6;
            var finish = start + (size * 2);
            var frame = texture.frame;
            var scaleX = frame.width / baseTexture.width;
            var scaleY = frame.height / baseTexture.height;
            var offsetX = frame.x / frame.width;
            var offsetY = frame.y / frame.height;
            var minX = Math.floor(uvs[start] + eps);
            var minY = Math.floor(uvs[start + 1] + eps);
            for (var i = start + 2; i < finish; i += 2) {
                minX = Math.min(minX, Math.floor(uvs[i] + eps));
                minY = Math.min(minY, Math.floor(uvs[i + 1] + eps));
            }
            offsetX -= minX;
            offsetY -= minY;
            for (var i = start; i < finish; i += 2) {
                uvs[i] = (uvs[i] + offsetX) * scaleX;
                uvs[i + 1] = (uvs[i + 1] + offsetY) * scaleY;
            }
        };
        /**
         * The maximum number of points to consider an object "batchable",
         * able to be batched by the renderer's batch system.
    \    */
        GraphicsGeometry.BATCHABLE_SIZE = 100;
        return GraphicsGeometry;
    }(core.BatchGeometry));

    /**
     * Represents the line style for Graphics.
     *
     * @memberof PIXI
     */
    var LineStyle = /** @class */ (function (_super) {
        __extends(LineStyle, _super);
        function LineStyle() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            /** The width (thickness) of any lines drawn. */
            _this.width = 0;
            /** The alignment of any lines drawn (0.5 = middle, 1 = outer, 0 = inner). WebGL only. */
            _this.alignment = 0.5;
            /** If true the lines will be draw using LINES instead of TRIANGLE_STRIP. */
            _this.native = false;
            /**
             * Line cap style.
             *
             * @member {PIXI.LINE_CAP}
             * @default PIXI.LINE_CAP.BUTT
             */
            _this.cap = exports.LINE_CAP.BUTT;
            /**
             * Line join style.
             *
             * @member {PIXI.LINE_JOIN}
             * @default PIXI.LINE_JOIN.MITER
             */
            _this.join = exports.LINE_JOIN.MITER;
            /** Miter limit. */
            _this.miterLimit = 10;
            return _this;
        }
        /** Clones the object. */
        LineStyle.prototype.clone = function () {
            var obj = new LineStyle();
            obj.color = this.color;
            obj.alpha = this.alpha;
            obj.texture = this.texture;
            obj.matrix = this.matrix;
            obj.visible = this.visible;
            obj.width = this.width;
            obj.alignment = this.alignment;
            obj.native = this.native;
            obj.cap = this.cap;
            obj.join = this.join;
            obj.miterLimit = this.miterLimit;
            return obj;
        };
        /** Reset the line style to default. */
        LineStyle.prototype.reset = function () {
            _super.prototype.reset.call(this);
            // Override default line style color
            this.color = 0x0;
            this.alignment = 0.5;
            this.width = 0;
            this.native = false;
        };
        return LineStyle;
    }(FillStyle));

    var temp = new Float32Array(3);
    // a default shaders map used by graphics..
    var DEFAULT_SHADERS = {};
    /**
     * The Graphics class is primarily used to render primitive shapes such as lines, circles and
     * rectangles to the display, and to color and fill them.  However, you can also use a Graphics
     * object to build a list of primitives to use as a mask, or as a complex hitArea.
     *
     * Please note that due to legacy naming conventions, the behavior of some functions in this class
     * can be confusing.  Each call to `drawRect()`, `drawPolygon()`, etc. actually stores that primitive
     * in the Geometry class's GraphicsGeometry object for later use in rendering or hit testing - the
     * functions do not directly draw anything to the screen.  Similarly, the `clear()` function doesn't
     * change the screen, it simply resets the list of primitives, which can be useful if you want to
     * rebuild the contents of an existing Graphics object.
     *
     * Once a GraphicsGeometry list is built, you can re-use it in other Geometry objects as
     * an optimization, by passing it into a new Geometry object's constructor.  Because of this
     * ability, it's important to call `destroy()` on Geometry objects once you are done with them, to
     * properly dereference each GraphicsGeometry and prevent memory leaks.
     *
     * @memberof PIXI
     */
    var Graphics = /** @class */ (function (_super) {
        __extends(Graphics, _super);
        /**
         * @param geometry - Geometry to use, if omitted will create a new GraphicsGeometry instance.
         */
        function Graphics(geometry) {
            if (geometry === void 0) { geometry = null; }
            var _this = _super.call(this) || this;
            /**
             * Represents the vertex and fragment shaders that processes the geometry and runs on the GPU.
             * Can be shared between multiple Graphics objects.
             */
            _this.shader = null;
            /** Renderer plugin for batching */
            _this.pluginName = 'batch';
            /**
             * Current path
             *
             * @readonly
             */
            _this.currentPath = null;
            /** A collections of batches! These can be drawn by the renderer batch system. */
            _this.batches = [];
            /** Update dirty for limiting calculating tints for batches. */
            _this.batchTint = -1;
            /** Update dirty for limiting calculating batches.*/
            _this.batchDirty = -1;
            /** Copy of the object vertex data. */
            _this.vertexData = null;
            /** Current fill style. */
            _this._fillStyle = new FillStyle();
            /** Current line style. */
            _this._lineStyle = new LineStyle();
            /** Current shape transform matrix. */
            _this._matrix = null;
            /** Current hole mode is enabled. */
            _this._holeMode = false;
            /**
             * Represents the WebGL state the Graphics required to render, excludes shader and geometry. E.g.,
             * blend mode, culling, depth testing, direction of rendering triangles, backface, etc.
             */
            _this.state = core.State.for2d();
            _this._geometry = geometry || new GraphicsGeometry();
            _this._geometry.refCount++;
            /**
             * When cacheAsBitmap is set to true the graphics object will be rendered as if it was a sprite.
             * This is useful if your graphics element does not change often, as it will speed up the rendering
             * of the object in exchange for taking up texture memory. It is also useful if you need the graphics
             * object to be anti-aliased, because it will be rendered using canvas. This is not recommended if
             * you are constantly redrawing the graphics element.
             *
             * @name cacheAsBitmap
             * @member {boolean}
             * @memberof PIXI.Graphics#
             * @default false
             */
            _this._transformID = -1;
            // Set default
            _this.tint = 0xFFFFFF;
            _this.blendMode = constants.BLEND_MODES.NORMAL;
            return _this;
        }
        Object.defineProperty(Graphics.prototype, "geometry", {
            /**
             * Includes vertex positions, face indices, normals, colors, UVs, and
             * custom attributes within buffers, reducing the cost of passing all
             * this data to the GPU. Can be shared between multiple Mesh or Graphics objects.
             *
             * @readonly
             */
            get: function () {
                return this._geometry;
            },
            enumerable: false,
            configurable: true
        });
        /**
         * Creates a new Graphics object with the same values as this one.
         * Note that only the geometry of the object is cloned, not its transform (position,scale,etc)
         *
         * @return - A clone of the graphics object
         */
        Graphics.prototype.clone = function () {
            this.finishPoly();
            return new Graphics(this._geometry);
        };
        Object.defineProperty(Graphics.prototype, "blendMode", {
            get: function () {
                return this.state.blendMode;
            },
            /**
             * The blend mode to be applied to the graphic shape. Apply a value of
             * `PIXI.BLEND_MODES.NORMAL` to reset the blend mode.  Note that, since each
             * primitive in the GraphicsGeometry list is rendered sequentially, modes
             * such as `PIXI.BLEND_MODES.ADD` and `PIXI.BLEND_MODES.MULTIPLY` will
             * be applied per-primitive.
             *
             * @default PIXI.BLEND_MODES.NORMAL
             */
            set: function (value) {
                this.state.blendMode = value;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(Graphics.prototype, "tint", {
            /**
             * The tint applied to each graphic shape. This is a hex value. A value of
             * 0xFFFFFF will remove any tint effect.
             *
             * @default 0xFFFFFF
             */
            get: function () {
                return this._tint;
            },
            set: function (value) {
                this._tint = value;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(Graphics.prototype, "fill", {
            /**
             * The current fill style.
             *
             * @readonly
             */
            get: function () {
                return this._fillStyle;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(Graphics.prototype, "line", {
            /**
             * The current line style.
             *
             * @readonly
             */
            get: function () {
                return this._lineStyle;
            },
            enumerable: false,
            configurable: true
        });
        Graphics.prototype.lineStyle = function (options, color, alpha, alignment, native) {
            if (options === void 0) { options = null; }
            if (color === void 0) { color = 0x0; }
            if (alpha === void 0) { alpha = 1; }
            if (alignment === void 0) { alignment = 0.5; }
            if (native === void 0) { native = false; }
            // Support non-object params: (width, color, alpha, alignment, native)
            if (typeof options === 'number') {
                options = { width: options, color: color, alpha: alpha, alignment: alignment, native: native };
            }
            return this.lineTextureStyle(options);
        };
        /**
         * Like line style but support texture for line fill.
         *
         * @param options - Collection of options for setting line style.
         * @param {number} [options.width=0] - width of the line to draw, will update the objects stored style
         * @param {PIXI.Texture} [options.texture=PIXI.Texture.WHITE] - Texture to use
         * @param {number} [options.color=0x0] - color of the line to draw, will update the objects stored style.
         *  Default 0xFFFFFF if texture present.
         * @param {number} [options.alpha=1] - alpha of the line to draw, will update the objects stored style
         * @param {PIXI.Matrix} [options.matrix=null] - Texture matrix to transform texture
         * @param {number} [options.alignment=0.5] - alignment of the line to draw, (0 = inner, 0.5 = middle, 1 = outer).
         *        WebGL only.
         * @param {boolean} [options.native=false] - If true the lines will be draw using LINES instead of TRIANGLE_STRIP
         * @param {PIXI.LINE_CAP}[options.cap=PIXI.LINE_CAP.BUTT] - line cap style
         * @param {PIXI.LINE_JOIN}[options.join=PIXI.LINE_JOIN.MITER] - line join style
         * @param {number}[options.miterLimit=10] - miter limit ratio
         * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.lineTextureStyle = function (options) {
            // Apply defaults
            options = Object.assign({
                width: 0,
                texture: core.Texture.WHITE,
                color: (options && options.texture) ? 0xFFFFFF : 0x0,
                alpha: 1,
                matrix: null,
                alignment: 0.5,
                native: false,
                cap: exports.LINE_CAP.BUTT,
                join: exports.LINE_JOIN.MITER,
                miterLimit: 10,
            }, options);
            if (this.currentPath) {
                this.startPoly();
            }
            var visible = options.width > 0 && options.alpha > 0;
            if (!visible) {
                this._lineStyle.reset();
            }
            else {
                if (options.matrix) {
                    options.matrix = options.matrix.clone();
                    options.matrix.invert();
                }
                Object.assign(this._lineStyle, { visible: visible }, options);
            }
            return this;
        };
        /**
         * Start a polygon object internally.
         *
         * @protected
         */
        Graphics.prototype.startPoly = function () {
            if (this.currentPath) {
                var points = this.currentPath.points;
                var len = this.currentPath.points.length;
                if (len > 2) {
                    this.drawShape(this.currentPath);
                    this.currentPath = new math.Polygon();
                    this.currentPath.closeStroke = false;
                    this.currentPath.points.push(points[len - 2], points[len - 1]);
                }
            }
            else {
                this.currentPath = new math.Polygon();
                this.currentPath.closeStroke = false;
            }
        };
        /**
         * Finish the polygon object.
         *
         * @protected
         */
        Graphics.prototype.finishPoly = function () {
            if (this.currentPath) {
                if (this.currentPath.points.length > 2) {
                    this.drawShape(this.currentPath);
                    this.currentPath = null;
                }
                else {
                    this.currentPath.points.length = 0;
                }
            }
        };
        /**
         * Moves the current drawing position to x, y.
         *
         * @param x - the X coordinate to move to
         * @param y - the Y coordinate to move to
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.moveTo = function (x, y) {
            this.startPoly();
            this.currentPath.points[0] = x;
            this.currentPath.points[1] = y;
            return this;
        };
        /**
         * Draws a line using the current line style from the current drawing position to (x, y);
         * The current drawing position is then set to (x, y).
         *
         * @param x - the X coordinate to draw to
         * @param y - the Y coordinate to draw to
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.lineTo = function (x, y) {
            if (!this.currentPath) {
                this.moveTo(0, 0);
            }
            // remove duplicates..
            var points = this.currentPath.points;
            var fromX = points[points.length - 2];
            var fromY = points[points.length - 1];
            if (fromX !== x || fromY !== y) {
                points.push(x, y);
            }
            return this;
        };
        /** Initialize the curve */
        Graphics.prototype._initCurve = function (x, y) {
            if (x === void 0) { x = 0; }
            if (y === void 0) { y = 0; }
            if (this.currentPath) {
                if (this.currentPath.points.length === 0) {
                    this.currentPath.points = [x, y];
                }
            }
            else {
                this.moveTo(x, y);
            }
        };
        /**
         * Calculate the points for a quadratic bezier curve and then draws it.
         * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c
         *
         * @param cpX - Control point x
         * @param cpY - Control point y
         * @param toX - Destination point x
         * @param toY - Destination point y
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.quadraticCurveTo = function (cpX, cpY, toX, toY) {
            this._initCurve();
            var points = this.currentPath.points;
            if (points.length === 0) {
                this.moveTo(0, 0);
            }
            QuadraticUtils.curveTo(cpX, cpY, toX, toY, points);
            return this;
        };
        /**
         * Calculate the points for a bezier curve and then draws it.
         *
         * @param cpX - Control point x
         * @param cpY - Control point y
         * @param cpX2 - Second Control point x
         * @param cpY2 - Second Control point y
         * @param toX - Destination point x
         * @param toY - Destination point y
         * @return This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.bezierCurveTo = function (cpX, cpY, cpX2, cpY2, toX, toY) {
            this._initCurve();
            BezierUtils.curveTo(cpX, cpY, cpX2, cpY2, toX, toY, this.currentPath.points);
            return this;
        };
        /**
         * The arcTo() method creates an arc/curve between two tangents on the canvas.
         *
         * "borrowed" from https://code.google.com/p/fxcanvas/ - thanks google!
         *
         * @param x1 - The x-coordinate of the first tangent point of the arc
         * @param y1 - The y-coordinate of the first tangent point of the arc
         * @param x2 - The x-coordinate of the end of the arc
         * @param y2 - The y-coordinate of the end of the arc
         * @param radius - The radius of the arc
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.arcTo = function (x1, y1, x2, y2, radius) {
            this._initCurve(x1, y1);
            var points = this.currentPath.points;
            var result = ArcUtils.curveTo(x1, y1, x2, y2, radius, points);
            if (result) {
                var cx = result.cx, cy = result.cy, radius_1 = result.radius, startAngle = result.startAngle, endAngle = result.endAngle, anticlockwise = result.anticlockwise;
                this.arc(cx, cy, radius_1, startAngle, endAngle, anticlockwise);
            }
            return this;
        };
        /**
         * The arc method creates an arc/curve (used to create circles, or parts of circles).
         *
         * @param cx - The x-coordinate of the center of the circle
         * @param cy - The y-coordinate of the center of the circle
         * @param radius - The radius of the circle
         * @param startAngle - The starting angle, in radians (0 is at the 3 o'clock position
         *  of the arc's circle)
         * @param endAngle - The ending angle, in radians
         * @param anticlockwise - Specifies whether the drawing should be
         *  counter-clockwise or clockwise. False is default, and indicates clockwise, while true
         *  indicates counter-clockwise.
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.arc = function (cx, cy, radius, startAngle, endAngle, anticlockwise) {
            if (anticlockwise === void 0) { anticlockwise = false; }
            if (startAngle === endAngle) {
                return this;
            }
            if (!anticlockwise && endAngle <= startAngle) {
                endAngle += math.PI_2;
            }
            else if (anticlockwise && startAngle <= endAngle) {
                startAngle += math.PI_2;
            }
            var sweep = endAngle - startAngle;
            if (sweep === 0) {
                return this;
            }
            var startX = cx + (Math.cos(startAngle) * radius);
            var startY = cy + (Math.sin(startAngle) * radius);
            var eps = this._geometry.closePointEps;
            // If the currentPath exists, take its points. Otherwise call `moveTo` to start a path.
            var points = this.currentPath ? this.currentPath.points : null;
            if (points) {
                // TODO: make a better fix.
                // We check how far our start is from the last existing point
                var xDiff = Math.abs(points[points.length - 2] - startX);
                var yDiff = Math.abs(points[points.length - 1] - startY);
                if (xDiff < eps && yDiff < eps) {
                    // If the point is very close, we don't add it, since this would lead to artifacts
                    // during tessellation due to floating point imprecision.
                }
                else {
                    points.push(startX, startY);
                }
            }
            else {
                this.moveTo(startX, startY);
                points = this.currentPath.points;
            }
            ArcUtils.arc(startX, startY, cx, cy, radius, startAngle, endAngle, anticlockwise, points);
            return this;
        };
        /**
         * Specifies a simple one-color fill that subsequent calls to other Graphics methods
         * (such as lineTo() or drawCircle()) use when drawing.
         *
         * @param color - the color of the fill
         * @param alpha - the alpha of the fill
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.beginFill = function (color, alpha) {
            if (color === void 0) { color = 0; }
            if (alpha === void 0) { alpha = 1; }
            return this.beginTextureFill({ texture: core.Texture.WHITE, color: color, alpha: alpha });
        };
        /**
         * Begin the texture fill
         *
         * @param options - Object object.
         * @param {PIXI.Texture} [options.texture=PIXI.Texture.WHITE] - Texture to fill
         * @param {number} [options.color=0xffffff] - Background to fill behind texture
         * @param {number} [options.alpha=1] - Alpha of fill
         * @param {PIXI.Matrix} [options.matrix=null] - Transform matrix
         * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.beginTextureFill = function (options) {
            // Apply defaults
            options = Object.assign({
                texture: core.Texture.WHITE,
                color: 0xFFFFFF,
                alpha: 1,
                matrix: null,
            }, options);
            if (this.currentPath) {
                this.startPoly();
            }
            var visible = options.alpha > 0;
            if (!visible) {
                this._fillStyle.reset();
            }
            else {
                if (options.matrix) {
                    options.matrix = options.matrix.clone();
                    options.matrix.invert();
                }
                Object.assign(this._fillStyle, { visible: visible }, options);
            }
            return this;
        };
        /**
         * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method.
         *
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.endFill = function () {
            this.finishPoly();
            this._fillStyle.reset();
            return this;
        };
        /**
         * Draws a rectangle shape.
         *
         * @param x - The X coord of the top-left of the rectangle
         * @param y - The Y coord of the top-left of the rectangle
         * @param width - The width of the rectangle
         * @param height - The height of the rectangle
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.drawRect = function (x, y, width, height) {
            return this.drawShape(new math.Rectangle(x, y, width, height));
        };
        /**
         * Draw a rectangle shape with rounded/beveled corners.
         *
         * @param x - The X coord of the top-left of the rectangle
         * @param y - The Y coord of the top-left of the rectangle
         * @param width - The width of the rectangle
         * @param height - The height of the rectangle
         * @param radius - Radius of the rectangle corners
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.drawRoundedRect = function (x, y, width, height, radius) {
            return this.drawShape(new math.RoundedRectangle(x, y, width, height, radius));
        };
        /**
         * Draws a circle.
         *
         * @param x - The X coordinate of the center of the circle
         * @param y - The Y coordinate of the center of the circle
         * @param radius - The radius of the circle
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.drawCircle = function (x, y, radius) {
            return this.drawShape(new math.Circle(x, y, radius));
        };
        /**
         * Draws an ellipse.
         *
         * @param x - The X coordinate of the center of the ellipse
         * @param y - The Y coordinate of the center of the ellipse
         * @param width - The half width of the ellipse
         * @param height - The half height of the ellipse
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.drawEllipse = function (x, y, width, height) {
            return this.drawShape(new math.Ellipse(x, y, width, height));
        };
        /**
         * Draws a polygon using the given path.
         *
         * @param {number[]|PIXI.Point[]|PIXI.Polygon} path - The path data used to construct the polygon.
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.drawPolygon = function () {
            var arguments$1 = arguments;

            var path = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                path[_i] = arguments$1[_i];
            }
            var points;
            var closeStroke = true; // !!this._fillStyle;
            var poly = path[0];
            // check if data has points..
            if (poly.points) {
                closeStroke = poly.closeStroke;
                points = poly.points;
            }
            else if (Array.isArray(path[0])) {
                points = path[0];
            }
            else {
                points = path;
            }
            var shape = new math.Polygon(points);
            shape.closeStroke = closeStroke;
            this.drawShape(shape);
            return this;
        };
        /**
         * Draw any shape.
         *
         * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - Shape to draw
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.drawShape = function (shape) {
            if (!this._holeMode) {
                this._geometry.drawShape(shape, this._fillStyle.clone(), this._lineStyle.clone(), this._matrix);
            }
            else {
                this._geometry.drawHole(shape, this._matrix);
            }
            return this;
        };
        /**
         * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
         *
         * @return - This Graphics object. Good for chaining method calls
         */
        Graphics.prototype.clear = function () {
            this._geometry.clear();
            this._lineStyle.reset();
            this._fillStyle.reset();
            this._boundsID++;
            this._matrix = null;
            this._holeMode = false;
            this.currentPath = null;
            return this;
        };
        /**
         * True if graphics consists of one rectangle, and thus, can be drawn like a Sprite and
         * masked with gl.scissor.
         *
         * @returns - True if only 1 rect.
         */
        Graphics.prototype.isFastRect = function () {
            var data = this._geometry.graphicsData;
            return data.length === 1
                && data[0].shape.type === math.SHAPES.RECT
                && !data[0].matrix
                && !data[0].holes.length
                && !(data[0].lineStyle.visible && data[0].lineStyle.width);
        };
        /**
         * Renders the object using the WebGL renderer
         *
         * @param renderer - The renderer
         */
        Graphics.prototype._render = function (renderer) {
            this.finishPoly();
            var geometry = this._geometry;
            var hasuint32 = renderer.context.supports.uint32Indices;
            // batch part..
            // batch it!
            geometry.updateBatches(hasuint32);
            if (geometry.batchable) {
                if (this.batchDirty !== geometry.batchDirty) {
                    this._populateBatches();
                }
                this._renderBatched(renderer);
            }
            else {
                // no batching...
                renderer.batch.flush();
                this._renderDirect(renderer);
            }
        };
        /** Populating batches for rendering. */
        Graphics.prototype._populateBatches = function () {
            var geometry = this._geometry;
            var blendMode = this.blendMode;
            var len = geometry.batches.length;
            this.batchTint = -1;
            this._transformID = -1;
            this.batchDirty = geometry.batchDirty;
            this.batches.length = len;
            this.vertexData = new Float32Array(geometry.points);
            for (var i = 0; i < len; i++) {
                var gI = geometry.batches[i];
                var color = gI.style.color;
                var vertexData = new Float32Array(this.vertexData.buffer, gI.attribStart * 4 * 2, gI.attribSize * 2);
                var uvs = new Float32Array(geometry.uvsFloat32.buffer, gI.attribStart * 4 * 2, gI.attribSize * 2);
                var indices = new Uint16Array(geometry.indicesUint16.buffer, gI.start * 2, gI.size);
                var batch = {
                    vertexData: vertexData,
                    blendMode: blendMode,
                    indices: indices,
                    uvs: uvs,
                    _batchRGB: utils.hex2rgb(color),
                    _tintRGB: color,
                    _texture: gI.style.texture,
                    alpha: gI.style.alpha,
                    worldAlpha: 1
                };
                this.batches[i] = batch;
            }
        };
        /**
         * Renders the batches using the BathedRenderer plugin
         *
         * @param renderer - The renderer
         */
        Graphics.prototype._renderBatched = function (renderer) {
            if (!this.batches.length) {
                return;
            }
            renderer.batch.setObjectRenderer(renderer.plugins[this.pluginName]);
            this.calculateVertices();
            this.calculateTints();
            for (var i = 0, l = this.batches.length; i < l; i++) {
                var batch = this.batches[i];
                batch.worldAlpha = this.worldAlpha * batch.alpha;
                renderer.plugins[this.pluginName].render(batch);
            }
        };
        /**
         * Renders the graphics direct
         *
         * @param renderer - The renderer
         */
        Graphics.prototype._renderDirect = function (renderer) {
            var shader = this._resolveDirectShader(renderer);
            var geometry = this._geometry;
            var tint = this.tint;
            var worldAlpha = this.worldAlpha;
            var uniforms = shader.uniforms;
            var drawCalls = geometry.drawCalls;
            // lets set the transfomr
            uniforms.translationMatrix = this.transform.worldTransform;
            // and then lets set the tint..
            uniforms.tint[0] = (((tint >> 16) & 0xFF) / 255) * worldAlpha;
            uniforms.tint[1] = (((tint >> 8) & 0xFF) / 255) * worldAlpha;
            uniforms.tint[2] = ((tint & 0xFF) / 255) * worldAlpha;
            uniforms.tint[3] = worldAlpha;
            // the first draw call, we can set the uniforms of the shader directly here.
            // this means that we can tack advantage of the sync function of pixi!
            // bind and sync uniforms..
            // there is a way to optimise this..
            renderer.shader.bind(shader);
            renderer.geometry.bind(geometry, shader);
            // set state..
            renderer.state.set(this.state);
            // then render the rest of them...
            for (var i = 0, l = drawCalls.length; i < l; i++) {
                this._renderDrawCallDirect(renderer, geometry.drawCalls[i]);
            }
        };
        /** Renders specific DrawCall */
        Graphics.prototype._renderDrawCallDirect = function (renderer, drawCall) {
            var texArray = drawCall.texArray, type = drawCall.type, size = drawCall.size, start = drawCall.start;
            var groupTextureCount = texArray.count;
            for (var j = 0; j < groupTextureCount; j++) {
                renderer.texture.bind(texArray.elements[j], j);
            }
            renderer.geometry.draw(type, size, start);
        };
        /**
         * Resolves shader for direct rendering
         *
         * @param renderer - The renderer
         */
        Graphics.prototype._resolveDirectShader = function (renderer) {
            var shader = this.shader;
            var pluginName = this.pluginName;
            if (!shader) {
                // if there is no shader here, we can use the default shader.
                // and that only gets created if we actually need it..
                // but may be more than one plugins for graphics
                if (!DEFAULT_SHADERS[pluginName]) {
                    var MAX_TEXTURES = renderer.plugins.batch.MAX_TEXTURES;
                    var sampleValues = new Int32Array(MAX_TEXTURES);
                    for (var i = 0; i < MAX_TEXTURES; i++) {
                        sampleValues[i] = i;
                    }
                    var uniforms = {
                        tint: new Float32Array([1, 1, 1, 1]),
                        translationMatrix: new math.Matrix(),
                        default: core.UniformGroup.from({ uSamplers: sampleValues }, true),
                    };
                    var program = renderer.plugins[pluginName]._shader.program;
                    DEFAULT_SHADERS[pluginName] = new core.Shader(program, uniforms);
                }
                shader = DEFAULT_SHADERS[pluginName];
            }
            return shader;
        };
        /** Retrieves the bounds of the graphic shape as a rectangle object. */
        Graphics.prototype._calculateBounds = function () {
            this.finishPoly();
            var geometry = this._geometry;
            // skipping when graphics is empty, like a container
            if (!geometry.graphicsData.length) {
                return;
            }
            var _a = geometry.bounds, minX = _a.minX, minY = _a.minY, maxX = _a.maxX, maxY = _a.maxY;
            this._bounds.addFrame(this.transform, minX, minY, maxX, maxY);
        };
        /**
         * Tests if a point is inside this graphics object
         *
         * @param point - the point to test
         * @return - the result of the test
         */
        Graphics.prototype.containsPoint = function (point) {
            this.worldTransform.applyInverse(point, Graphics._TEMP_POINT);
            return this._geometry.containsPoint(Graphics._TEMP_POINT);
        };
        /** Recalculate the tint by applying tint to batches using Graphics tint. */
        Graphics.prototype.calculateTints = function () {
            if (this.batchTint !== this.tint) {
                this.batchTint = this.tint;
                var tintRGB = utils.hex2rgb(this.tint, temp);
                for (var i = 0; i < this.batches.length; i++) {
                    var batch = this.batches[i];
                    var batchTint = batch._batchRGB;
                    var r = (tintRGB[0] * batchTint[0]) * 255;
                    var g = (tintRGB[1] * batchTint[1]) * 255;
                    var b = (tintRGB[2] * batchTint[2]) * 255;
                    // TODO Ivan, can this be done in one go?
                    var color = (r << 16) + (g << 8) + (b | 0);
                    batch._tintRGB = (color >> 16)
                        + (color & 0xff00)
                        + ((color & 0xff) << 16);
                }
            }
        };
        /**
         * If there's a transform update or a change to the shape of the
         * geometry, recalculate the vertices.
         */
        Graphics.prototype.calculateVertices = function () {
            var wtID = this.transform._worldID;
            if (this._transformID === wtID) {
                return;
            }
            this._transformID = wtID;
            var wt = this.transform.worldTransform;
            var a = wt.a;
            var b = wt.b;
            var c = wt.c;
            var d = wt.d;
            var tx = wt.tx;
            var ty = wt.ty;
            var data = this._geometry.points; // batch.vertexDataOriginal;
            var vertexData = this.vertexData;
            var count = 0;
            for (var i = 0; i < data.length; i += 2) {
                var x = data[i];
                var y = data[i + 1];
                vertexData[count++] = (a * x) + (c * y) + tx;
                vertexData[count++] = (d * y) + (b * x) + ty;
            }
        };
        /**
         * Closes the current path.
         *
         * @return - Returns itself.
         */
        Graphics.prototype.closePath = function () {
            var currentPath = this.currentPath;
            if (currentPath) {
                // we don't need to add extra point in the end because buildLine will take care of that
                currentPath.closeStroke = true;
                // ensure that the polygon is completed, and is available for hit detection
                // (even if the graphics is not rendered yet)
                this.finishPoly();
            }
            return this;
        };
        /**
         * Apply a matrix to the positional data.
         *
         * @param matrix - Matrix to use for transform current shape.
         * @return - Returns itself.
         */
        Graphics.prototype.setMatrix = function (matrix) {
            this._matrix = matrix;
            return this;
        };
        /**
         * Begin adding holes to the last draw shape
         * IMPORTANT: holes must be fully inside a shape to work
         * Also weirdness ensues if holes overlap!
         * Ellipses, Circles, Rectangles and Rounded Rectangles cannot be holes or host for holes in CanvasRenderer,
         * please use `moveTo` `lineTo`, `quadraticCurveTo` if you rely on pixi-legacy bundle.
         *
         * @return - Returns itself.
         */
        Graphics.prototype.beginHole = function () {
            this.finishPoly();
            this._holeMode = true;
            return this;
        };
        /**
         * End adding holes to the last draw shape.
         *
         * @return - Returns itself.
         */
        Graphics.prototype.endHole = function () {
            this.finishPoly();
            this._holeMode = false;
            return this;
        };
        /**
         * Destroys the Graphics object.
         *
         * @param options - Options parameter. A boolean will act as if all
         *  options have been set to that value
         * @param {boolean} [options.children=false] - if set to true, all the children will have
         *  their destroy method called as well. 'options' will be passed on to those calls.
         * @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true
         *  Should it destroy the texture of the child sprite
         * @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true
         *  Should it destroy the base texture of the child sprite
         */
        Graphics.prototype.destroy = function (options) {
            this._geometry.refCount--;
            if (this._geometry.refCount === 0) {
                this._geometry.dispose();
            }
            this._matrix = null;
            this.currentPath = null;
            this._lineStyle.destroy();
            this._lineStyle = null;
            this._fillStyle.destroy();
            this._fillStyle = null;
            this._geometry = null;
            this.shader = null;
            this.vertexData = null;
            this.batches.length = 0;
            this.batches = null;
            _super.prototype.destroy.call(this, options);
        };
        /**
         * New rendering behavior for rounded rectangles: circular arcs instead of quadratic bezier curves.
         * In the next major release, we'll enable this by default.
         */
        Graphics.nextRoundedRectBehavior = false;
        /**
         * Temporary point to use for containsPoint.
         *
         * @private
         */
        Graphics._TEMP_POINT = new math.Point();
        return Graphics;
    }(display.Container));

    var graphicsUtils = {
        buildPoly: buildPoly,
        buildCircle: buildCircle,
        buildRectangle: buildRectangle,
        buildRoundedRectangle: buildRoundedRectangle,
        buildLine: buildLine,
        ArcUtils: ArcUtils,
        BezierUtils: BezierUtils,
        QuadraticUtils: QuadraticUtils,
        BatchPart: BatchPart,
        FILL_COMMANDS: FILL_COMMANDS,
        BATCH_POOL: BATCH_POOL,
        DRAW_CALL_POOL: DRAW_CALL_POOL
    };

    exports.FillStyle = FillStyle;
    exports.GRAPHICS_CURVES = GRAPHICS_CURVES;
    exports.Graphics = Graphics;
    exports.GraphicsData = GraphicsData;
    exports.GraphicsGeometry = GraphicsGeometry;
    exports.LineStyle = LineStyle;
    exports.graphicsUtils = graphicsUtils;

    return exports;

}({}, PIXI, PIXI, PIXI.utils, PIXI, PIXI));
Object.assign(this.PIXI, _pixi_graphics);
//# sourceMappingURL=graphics.js.map
