(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory(require("echarts"));
	else if(typeof define === 'function' && define.amd)
		define(["echarts"], factory);
	else if(typeof exports === 'object')
		exports["echarts-gl"] = factory(require("echarts"));
	else
		root["echarts-gl"] = factory(root["echarts"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 106);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {

module.exports = __WEBPACK_EXTERNAL_MODULE_0__;

/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Mesh__ = __webpack_require__(40);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Renderer__ = __webpack_require__(52);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_Material__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_Node__ = __webpack_require__(35);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_claygl_src_Geometry__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_claygl_src_Scene__ = __webpack_require__(36);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10_zrender_lib_core_LRU__ = __webpack_require__(60);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10_zrender_lib_core_LRU___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_10_zrender_lib_core_LRU__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11_claygl_src_util_texture__ = __webpack_require__(61);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__EChartsSurface__ = __webpack_require__(124);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13_claygl_src_light_AmbientCubemap__ = __webpack_require__(125);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14_claygl_src_light_AmbientSH__ = __webpack_require__(129);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15_claygl_src_util_sh__ = __webpack_require__(130);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17_claygl_src_geometry_Sphere__ = __webpack_require__(132);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18_claygl_src_geometry_Plane__ = __webpack_require__(43);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19_claygl_src_geometry_Cube__ = __webpack_require__(76);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_20_claygl_src_light_Ambient__ = __webpack_require__(133);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21_claygl_src_light_Directional__ = __webpack_require__(134);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22_claygl_src_light_Point__ = __webpack_require__(135);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_23_claygl_src_light_Spot__ = __webpack_require__(136);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_24_claygl_src_camera_Perspective__ = __webpack_require__(41);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_25_claygl_src_camera_Orthographic__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_26_claygl_src_math_Vector2__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_27_claygl_src_math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_28_claygl_src_math_Vector4__ = __webpack_require__(137);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_29_claygl_src_math_Quaternion__ = __webpack_require__(56);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_30_claygl_src_math_Matrix2__ = __webpack_require__(138);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_31_claygl_src_math_Matrix2d__ = __webpack_require__(139);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_32_claygl_src_math_Matrix3__ = __webpack_require__(140);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_33_claygl_src_math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_34_claygl_src_math_Plane__ = __webpack_require__(74);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_35_claygl_src_math_Ray__ = __webpack_require__(54);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_36_claygl_src_math_BoundingBox__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_37_claygl_src_math_Frustum__ = __webpack_require__(59);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_38__animatableMixin__ = __webpack_require__(141);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_39_claygl_src_shader_source_util_glsl_js__ = __webpack_require__(146);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_40_claygl_src_shader_source_prez_glsl_js__ = __webpack_require__(71);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_41__shader_common_glsl_js__ = __webpack_require__(147);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_42__shader_color_glsl_js__ = __webpack_require__(148);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_43__shader_lambert_glsl_js__ = __webpack_require__(149);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_44__shader_realistic_glsl_js__ = __webpack_require__(150);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_45__shader_hatching_glsl_js__ = __webpack_require__(151);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_46__shader_shadow_glsl_js__ = __webpack_require__(152);






























// Math

















// Some common shaders










__WEBPACK_IMPORTED_MODULE_8_echarts_lib_echarts___default.a.util.extend(__WEBPACK_IMPORTED_MODULE_6_claygl_src_Node__["a" /* default */].prototype, __WEBPACK_IMPORTED_MODULE_38__animatableMixin__["a" /* default */]);

__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_39_claygl_src_shader_source_util_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_40_claygl_src_shader_source_prez_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_41__shader_common_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_42__shader_color_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_43__shader_lambert_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_44__shader_realistic_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_45__shader_hatching_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_46__shader_shadow_glsl_js__["a" /* default */]);

function isValueNone(value) {
    return !value || value === 'none';
}

function isValueImage(value) {
    return value instanceof HTMLCanvasElement
        || value instanceof HTMLImageElement
        || value instanceof Image;
}

function isECharts(value) {
    return value.getZr && value.setOption;
}

// Overwrite addToScene and removeFromScene
var oldAddToScene = __WEBPACK_IMPORTED_MODULE_9_claygl_src_Scene__["a" /* default */].prototype.addToScene;
var oldRemoveFromScene = __WEBPACK_IMPORTED_MODULE_9_claygl_src_Scene__["a" /* default */].prototype.removeFromScene;

__WEBPACK_IMPORTED_MODULE_9_claygl_src_Scene__["a" /* default */].prototype.addToScene = function (node) {
    oldAddToScene.call(this, node);

    if (this.__zr) {
        var zr = this.__zr;
        node.traverse(function (child) {
            child.__zr = zr;
            if (child.addAnimatorsToZr) {
                child.addAnimatorsToZr(zr);
            }
        });
    }
};

__WEBPACK_IMPORTED_MODULE_9_claygl_src_Scene__["a" /* default */].prototype.removeFromScene = function (node) {
    oldRemoveFromScene.call(this, node);

    node.traverse(function (child) {
        var zr = child.__zr;
        child.__zr = null;
        if (zr && child.removeAnimatorsFromZr) {
            child.removeAnimatorsFromZr(zr);
        }
    });
};

/**
 * @param {string} textureName
 * @param {string|HTMLImageElement|HTMLCanvasElement} imgValue
 * @param {module:echarts/ExtensionAPI} api
 * @param {Object} [textureOpts]
 */
__WEBPACK_IMPORTED_MODULE_5_claygl_src_Material__["a" /* default */].prototype.setTextureImage = function (textureName, imgValue, api, textureOpts) {
    if (!this.shader) {
        return;
    }

    var zr = api.getZr();
    var material = this;
    var texture;
    material.autoUpdateTextureStatus = false;
    // disableTexture first
    material.disableTexture(textureName);
    if (!isValueNone(imgValue)) {
        texture = graphicGL.loadTexture(imgValue, api, textureOpts, function (texture) {
            material.enableTexture(textureName);
            zr && zr.refresh();
        });
        // Set texture immediately for other code to verify if have this texture.
        material.set(textureName, texture);
    }

    return texture;
};

var graphicGL = {};

graphicGL.Renderer = __WEBPACK_IMPORTED_MODULE_1_claygl_src_Renderer__["a" /* default */];

graphicGL.Node = __WEBPACK_IMPORTED_MODULE_6_claygl_src_Node__["a" /* default */];

graphicGL.Mesh = __WEBPACK_IMPORTED_MODULE_0_claygl_src_Mesh__["a" /* default */];

graphicGL.Shader = __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */];

graphicGL.Material = __WEBPACK_IMPORTED_MODULE_5_claygl_src_Material__["a" /* default */];

graphicGL.Texture = __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */];

graphicGL.Texture2D = __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */];

// Geometries
graphicGL.Geometry = __WEBPACK_IMPORTED_MODULE_7_claygl_src_Geometry__["a" /* default */];
graphicGL.SphereGeometry = __WEBPACK_IMPORTED_MODULE_17_claygl_src_geometry_Sphere__["a" /* default */];
graphicGL.PlaneGeometry = __WEBPACK_IMPORTED_MODULE_18_claygl_src_geometry_Plane__["a" /* default */];
graphicGL.CubeGeometry = __WEBPACK_IMPORTED_MODULE_19_claygl_src_geometry_Cube__["a" /* default */];

// Lights
graphicGL.AmbientLight = __WEBPACK_IMPORTED_MODULE_20_claygl_src_light_Ambient__["a" /* default */];
graphicGL.DirectionalLight = __WEBPACK_IMPORTED_MODULE_21_claygl_src_light_Directional__["a" /* default */];
graphicGL.PointLight = __WEBPACK_IMPORTED_MODULE_22_claygl_src_light_Point__["a" /* default */];
graphicGL.SpotLight = __WEBPACK_IMPORTED_MODULE_23_claygl_src_light_Spot__["a" /* default */];

// Cameras
graphicGL.PerspectiveCamera = __WEBPACK_IMPORTED_MODULE_24_claygl_src_camera_Perspective__["a" /* default */];
graphicGL.OrthographicCamera = __WEBPACK_IMPORTED_MODULE_25_claygl_src_camera_Orthographic__["a" /* default */];

// Math
graphicGL.Vector2 = __WEBPACK_IMPORTED_MODULE_26_claygl_src_math_Vector2__["a" /* default */];
graphicGL.Vector3 = __WEBPACK_IMPORTED_MODULE_27_claygl_src_math_Vector3__["a" /* default */];
graphicGL.Vector4 = __WEBPACK_IMPORTED_MODULE_28_claygl_src_math_Vector4__["a" /* default */];

graphicGL.Quaternion = __WEBPACK_IMPORTED_MODULE_29_claygl_src_math_Quaternion__["a" /* default */];

graphicGL.Matrix2 = __WEBPACK_IMPORTED_MODULE_30_claygl_src_math_Matrix2__["a" /* default */];
graphicGL.Matrix2d = __WEBPACK_IMPORTED_MODULE_31_claygl_src_math_Matrix2d__["a" /* default */];
graphicGL.Matrix3 = __WEBPACK_IMPORTED_MODULE_32_claygl_src_math_Matrix3__["a" /* default */];
graphicGL.Matrix4 = __WEBPACK_IMPORTED_MODULE_33_claygl_src_math_Matrix4__["a" /* default */];

graphicGL.Plane = __WEBPACK_IMPORTED_MODULE_34_claygl_src_math_Plane__["a" /* default */];
graphicGL.Ray = __WEBPACK_IMPORTED_MODULE_35_claygl_src_math_Ray__["a" /* default */];
graphicGL.BoundingBox = __WEBPACK_IMPORTED_MODULE_36_claygl_src_math_BoundingBox__["a" /* default */];
graphicGL.Frustum = __WEBPACK_IMPORTED_MODULE_37_claygl_src_math_Frustum__["a" /* default */];

// Texture utilities

var blankImage = __WEBPACK_IMPORTED_MODULE_11_claygl_src_util_texture__["a" /* default */].createBlank('rgba(255,255,255,0)').image;


function nearestPowerOfTwo(val) {
    return Math.pow(2, Math.round(Math.log(val) / Math.LN2));
}
function convertTextureToPowerOfTwo(texture) {
    if ((texture.wrapS === __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].REPEAT || texture.wrapT === __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].REPEAT)
     && texture.image
     ) {
        // var canvas = document.createElement('canvas');
        var width = nearestPowerOfTwo(texture.width);
        var height = nearestPowerOfTwo(texture.height);
        if (width !== texture.width || height !== texture.height) {
            var canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
            var ctx = canvas.getContext('2d');
            ctx.drawImage(texture.image, 0, 0, width, height);
            texture.image = canvas;
        }
    }
}
/**
 * @param {string|HTMLImageElement|HTMLCanvasElement} imgValue
 * @param {module:echarts/ExtensionAPI} api
 * @param {Object} [textureOpts]
 * @param {Function} cb
 */
// TODO Promise, test
graphicGL.loadTexture = function (imgValue, api, textureOpts, cb) {
    if (typeof textureOpts === 'function') {
        cb = textureOpts;
        textureOpts = {};
    }
    textureOpts = textureOpts || {};

    var keys = Object.keys(textureOpts).sort();
    var prefix = '';
    for (var i = 0; i < keys.length; i++) {
        prefix += keys[i] + '_' + textureOpts[keys[i]] + '_';
    }

    var textureCache = api.__textureCache = api.__textureCache || new __WEBPACK_IMPORTED_MODULE_10_zrender_lib_core_LRU___default.a(20);

    if (isECharts(imgValue)) {
        var id = imgValue.__textureid__;
        var textureObj = textureCache.get(prefix + id);
        if (!textureObj) {
            var surface = new __WEBPACK_IMPORTED_MODULE_12__EChartsSurface__["a" /* default */](imgValue);
            surface.onupdate = function () {
                api.getZr().refresh();
            };
            textureObj = {
                texture: surface.getTexture()
            };
            for (var i = 0; i < keys.length; i++) {
                textureObj.texture[keys[i]] = textureOpts[keys[i]];
            }
            id = imgValue.__textureid__ || '__ecgl_ec__' + textureObj.texture.__uid__;
            imgValue.__textureid__ = id;
            textureCache.put(prefix + id, textureObj);
            cb && cb(textureObj.texture);
        }
        else {
            textureObj.texture.surface.setECharts(imgValue);

            cb && cb(textureObj.texture);
        }
        return textureObj.texture;
    }
    else if (isValueImage(imgValue)) {
        var id = imgValue.__textureid__;
        var textureObj = textureCache.get(prefix + id);
        if (!textureObj) {
            textureObj = {
                texture: new graphicGL.Texture2D({
                    image: imgValue
                })
            };
            for (var i = 0; i < keys.length; i++) {
                textureObj.texture[keys[i]] = textureOpts[keys[i]];
            }
            id = imgValue.__textureid__ || '__ecgl_image__' + textureObj.texture.__uid__;
            imgValue.__textureid__ = id;
            textureCache.put(prefix + id, textureObj);

            convertTextureToPowerOfTwo(textureObj.texture);
            // TODO Next tick?
            cb && cb(textureObj.texture);
        }
        return textureObj.texture;
    }
    else {
        var textureObj = textureCache.get(prefix + imgValue);
        if (textureObj) {
            if (textureObj.callbacks) {
                // Add to pending callbacks
                textureObj.callbacks.push(cb);
            }
            else {
                // TODO Next tick?
                cb && cb(textureObj.texture);
            }
        }
        else {
            // Maybe base64
            if (imgValue.match(/.hdr$|^data:application\/octet-stream/)) {
                textureObj = {
                    callbacks: [cb]
                };
                var texture = __WEBPACK_IMPORTED_MODULE_11_claygl_src_util_texture__["a" /* default */].loadTexture(imgValue, {
                    exposure: textureOpts.exposure,
                    fileType: 'hdr'
                }, function () {
                    texture.dirty();
                    textureObj.callbacks.forEach(function (cb) {
                        cb && cb(texture);
                    });
                    textureObj.callbacks = null;
                });
                textureObj.texture = texture;
                textureCache.put(prefix + imgValue, textureObj);
            }
            else {
                var texture = new graphicGL.Texture2D({
                    image: new Image()
                });
                for (var i = 0; i < keys.length; i++) {
                    texture[keys[i]] = textureOpts[keys[i]];
                }

                textureObj = {
                    texture: texture,
                    callbacks: [cb]
                };
                var originalImage = texture.image;
                originalImage.onload = function () {
                    texture.image = originalImage;
                    convertTextureToPowerOfTwo(texture);

                    texture.dirty();
                    textureObj.callbacks.forEach(function (cb) {
                        cb && cb(texture);
                    });
                    textureObj.callbacks = null;
                };
                originalImage.src = imgValue;
                // Use blank image as place holder.
                texture.image = blankImage;

                textureCache.put(prefix + imgValue, textureObj);
            }
        }

        return textureObj.texture;
    }
};

/**
 * Create ambientCubemap and ambientSH light. respectively to have specular and diffuse light
 * @return {Object} { specular, diffuse }
 */
graphicGL.createAmbientCubemap = function (opt, renderer, api, cb) {
    opt = opt || {};
    var textureUrl = opt.texture;
    var exposure = __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(opt.exposure, 1.0);

    var ambientCubemap = new __WEBPACK_IMPORTED_MODULE_13_claygl_src_light_AmbientCubemap__["a" /* default */]({
        intensity: __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(opt.specularIntensity, 1.0)
    });
    var ambientSH = new __WEBPACK_IMPORTED_MODULE_14_claygl_src_light_AmbientSH__["a" /* default */]({
        intensity: __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(opt.diffuseIntensity, 1.0),
        coefficients: [0.844, 0.712, 0.691, -0.037, 0.083, 0.167, 0.343, 0.288, 0.299, -0.041, -0.021, -0.009, -0.003, -0.041, -0.064, -0.011, -0.007, -0.004, -0.031, 0.034, 0.081, -0.060, -0.049, -0.060, 0.046, 0.056, 0.050]
    });


    ambientCubemap.cubemap = graphicGL.loadTexture(textureUrl, api, {
        exposure: exposure
    }, function () {
        // TODO Performance when multiple view
        ambientCubemap.cubemap.flipY = false;
        if (true) {
            var time = Date.now();
        }
        ambientCubemap.prefilter(renderer, 32);
        if (true) {
            var dTime = Date.now() - time;
            console.log('Prefilter environment map: ' + dTime + 'ms');
        }
        ambientSH.coefficients = __WEBPACK_IMPORTED_MODULE_15_claygl_src_util_sh__["a" /* default */].projectEnvironmentMap(renderer, ambientCubemap.cubemap, {
            lod: 1
        });

        cb && cb();

        // TODO Refresh ?
    });

    return {
        specular: ambientCubemap,
        diffuse: ambientSH
    };
};

/**
 * Create a blank texture for placeholder
 */
graphicGL.createBlankTexture = __WEBPACK_IMPORTED_MODULE_11_claygl_src_util_texture__["a" /* default */].createBlank;

/**
 * If value is image
 * @param {*}
 * @return {boolean}
 */
graphicGL.isImage = isValueImage;

graphicGL.additiveBlend = function (gl) {
    gl.blendEquation(gl.FUNC_ADD);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
};

/**
 * @param {string|Array.<number>} colorStr
 * @param {Array.<number>} [rgba]
 * @return {Array.<number>} rgba
 */
graphicGL.parseColor = function (colorStr, rgba) {
    if (colorStr instanceof Array) {
        if (!rgba) {
            rgba = [];
        }
        // Color has been parsed.
        rgba[0] = colorStr[0];
        rgba[1] = colorStr[1];
        rgba[2] = colorStr[2];
        if (colorStr.length > 3) {
            rgba[3] = colorStr[3];
        }
        else {
            rgba[3] = 1;
        }
        return rgba;
    }

    rgba = __WEBPACK_IMPORTED_MODULE_8_echarts_lib_echarts___default.a.color.parse(colorStr || '#000', rgba) || [0, 0, 0, 0];
    rgba[0] /= 255;
    rgba[1] /= 255;
    rgba[2] /= 255;
    return rgba;
};

/**
 * Convert alpha beta rotation to direction.
 * @param {number} alpha
 * @param {number} beta
 * @return {Array.<number>}
 */
graphicGL.directionFromAlphaBeta = function (alpha, beta) {
    var theta = alpha / 180 * Math.PI + Math.PI / 2;
    var phi = -beta / 180 * Math.PI + Math.PI / 2;

    var dir = [];
    var r = Math.sin(theta);
    dir[0] = r * Math.cos(phi);
    dir[1] = -Math.cos(theta);
    dir[2] = r * Math.sin(phi);

    return dir;
};
/**
 * Get shadow resolution from shadowQuality configuration
 */
graphicGL.getShadowResolution = function (shadowQuality) {
    var shadowResolution = 1024;
    switch (shadowQuality) {
        case 'low':
            shadowResolution = 512;
            break;
        case 'medium':
            break;
        case 'high':
            shadowResolution = 2048;
            break;
        case 'ultra':
            shadowResolution = 4096;
            break;
    }
    return shadowResolution;
};

/**
 * Shading utilities
 */
graphicGL.COMMON_SHADERS = ['lambert', 'color', 'realistic', 'hatching'];

/**
 * Create shader including vertex and fragment
 * @param {string} prefix.
 */
graphicGL.createShader = function (prefix) {
    var vertexShaderStr = __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source(prefix + '.vertex');
    var fragmentShaderStr = __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source(prefix + '.fragment');
    if (!vertexShaderStr) {
        console.error('Vertex shader of \'%s\' not exits', prefix);
    }
    if (!fragmentShaderStr) {
        console.error('Fragment shader of \'%s\' not exits', prefix);
    }
    var shader = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */](vertexShaderStr, fragmentShaderStr);
    shader.name = prefix;
    return shader;
};

graphicGL.createMaterial = function (prefix, defines) {
    if (!(defines instanceof Array)) {
        defines = [defines];
    }
    var shader = graphicGL.createShader(prefix);
    var material = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Material__["a" /* default */]({
        shader: shader
    });
    defines.forEach(function (defineName) {
        if (typeof defineName === 'string') {
            material.define(defineName);
        }
    });
    return material;
};
/**
 * Set material from model.
 * @param {clay.Material} material
 * @param {module:echarts/model/Model} model
 * @param {module:echarts/ExtensionAPI} api
 */
graphicGL.setMaterialFromModel = function (shading, material, model, api) {
    material.autoUpdateTextureStatus = false;

    var materialModel = model.getModel(shading + 'Material');
    var detailTexture = materialModel.get('detailTexture');
    var uvRepeat = __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(materialModel.get('textureTiling'), 1.0);
    var uvOffset = __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(materialModel.get('textureOffset'), 0.0);
    if (typeof uvRepeat === 'number') {
        uvRepeat = [uvRepeat, uvRepeat];
    }
    if (typeof uvOffset === 'number') {
        uvOffset = [uvOffset, uvOffset];
    }
    var repeatParam = (uvRepeat[0] > 1 || uvRepeat[1] > 1) ? graphicGL.Texture.REPEAT : graphicGL.Texture.CLAMP_TO_EDGE;
    var textureOpt = {
        anisotropic: 8,
        wrapS: repeatParam,
        wrapT: repeatParam
    };
    if (shading === 'realistic') {
        var roughness = materialModel.get('roughness');
        var metalness = materialModel.get('metalness');
        if (metalness != null) {
            // Try to treat as a texture, TODO More check
            if (isNaN(metalness)) {
                material.setTextureImage('metalnessMap', metalness, api, textureOpt);
                metalness = __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(materialModel.get('metalnessAdjust'), 0.5);
            }
        }
        else {
            // Default metalness.
            metalness = 0;
        }
        if (roughness != null) {
            // Try to treat as a texture, TODO More check
            if (isNaN(roughness)) {
                material.setTextureImage('roughnessMap', roughness, api, textureOpt);
                roughness = __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(materialModel.get('roughnessAdjust'), 0.5);
            }
        }
        else {
            // Default roughness.
            roughness = 0.5;
        }
        var normalTextureVal = materialModel.get('normalTexture');
        material.setTextureImage('detailMap', detailTexture, api, textureOpt);
        material.setTextureImage('normalMap', normalTextureVal, api, textureOpt);
        material.set({
            roughness: roughness,
            metalness: metalness,
            detailUvRepeat: uvRepeat,
            detailUvOffset: uvOffset
        });
        // var normalTexture = material.get('normalMap');
        // if (normalTexture) {
            // PENDING
            // normalTexture.format = Texture.SRGB;
        // }
    }
    else if (shading === 'lambert') {
        material.setTextureImage('detailMap', detailTexture, api, textureOpt);
        material.set({
            detailUvRepeat: uvRepeat,
            detailUvOffset: uvOffset
        });
    }
    else if (shading === 'color') {
        material.setTextureImage('detailMap', detailTexture, api, textureOpt);
        material.set({
            detailUvRepeat: uvRepeat,
            detailUvOffset: uvOffset
        });
    }
    else if (shading === 'hatching') {
        var tams = materialModel.get('hatchingTextures') || [];
        if (tams.length < 6) {
            if (true) {
                console.error('Invalid hatchingTextures.');
            }
        }
        for (var i = 0; i < 6; i++) {
            material.setTextureImage('hatch' + (i + 1), tams[i], api, {
                anisotropic: 8,
                wrapS: graphicGL.Texture.REPEAT,
                wrapT: graphicGL.Texture.REPEAT
            });
        }
        material.set({
            detailUvRepeat: uvRepeat,
            detailUvOffset: uvOffset
        });
    }
};

graphicGL.updateVertexAnimation = function (
    mappingAttributes, previousMesh, currentMesh, seriesModel
) {
    var enableAnimation = seriesModel.get('animation');
    var duration = seriesModel.get('animationDurationUpdate');
    var easing = seriesModel.get('animationEasingUpdate');
    var shadowDepthMaterial = currentMesh.shadowDepthMaterial;

    if (enableAnimation && previousMesh && duration > 0
    // Only animate when bar count are not changed
    && previousMesh.geometry.vertexCount === currentMesh.geometry.vertexCount
    ) {
        currentMesh.material.define('vertex', 'VERTEX_ANIMATION');
        currentMesh.ignorePreZ = true;
        if (shadowDepthMaterial) {
            shadowDepthMaterial.define('vertex', 'VERTEX_ANIMATION');
        }
        for (var i = 0; i < mappingAttributes.length; i++) {
            currentMesh.geometry.attributes[mappingAttributes[i][0]].value =
            previousMesh.geometry.attributes[mappingAttributes[i][1]].value;
        }
        currentMesh.geometry.dirty();
        currentMesh.__percent = 0;
        currentMesh.material.set('percent', 0);
        currentMesh.stopAnimation();
        currentMesh.animate()
            .when(duration, {
                __percent: 1
            })
            .during(function () {
                currentMesh.material.set('percent', currentMesh.__percent);
                if (shadowDepthMaterial) {
                    shadowDepthMaterial.set('percent', currentMesh.__percent);
                }
            })
            .done(function () {
                currentMesh.ignorePreZ = false;
                currentMesh.material.undefine('vertex', 'VERTEX_ANIMATION');
                if (shadowDepthMaterial) {
                    shadowDepthMaterial.undefine('vertex', 'VERTEX_ANIMATION');
                }
            })
            .start(easing);
    }
    else {
        currentMesh.material.undefine('vertex', 'VERTEX_ANIMATION');
        if (shadowDepthMaterial) {
            shadowDepthMaterial.undefine('vertex', 'VERTEX_ANIMATION');
        }
    }
};

/* harmony default export */ __webpack_exports__["a"] = (graphicGL);

/***/ }),
/* 2 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


var retrieve = {

    firstNotNull: function () {
        for (var i = 0, len = arguments.length; i < len; i++) {
            if (arguments[i] != null) {
                return arguments[i];
            }
        }
    },

    /**
     * @param {module:echarts/data/List} data
     * @param {Object} payload Contains dataIndex (means rawIndex) / dataIndexInside / name
     *                         each of which can be Array or primary type.
     * @return {number|Array.<number>} dataIndex If not found, return undefined/null.
     */
    queryDataIndex: function (data, payload) {
        if (payload.dataIndexInside != null) {
            return payload.dataIndexInside;
        }
        else if (payload.dataIndex != null) {
            return __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(payload.dataIndex)
                ? __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.map(payload.dataIndex, function (value) {
                    return data.indexOfRawIndex(value);
                })
                : data.indexOfRawIndex(payload.dataIndex);
        }
        else if (payload.name != null) {
            return __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(payload.name)
                ? __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.map(payload.name, function (value) {
                    return data.indexOfName(value);
                })
                : data.indexOfName(payload.name);
        }
    }
};

/* harmony default export */ __webpack_exports__["a"] = (retrieve);

/***/ }),
/* 3 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__ = __webpack_require__(12);


/**
 * @constructor
 * @alias clay.Vector3
 * @param {number} x
 * @param {number} y
 * @param {number} z
 */
var Vector3 = function(x, y, z) {

    x = x || 0;
    y = y || 0;
    z = z || 0;

    /**
     * Storage of Vector3, read and write of x, y, z will change the values in array
     * All methods also operate on the array instead of x, y, z components
     * @name array
     * @type {Float32Array}
     * @memberOf clay.Vector3#
     */
    this.array = __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].fromValues(x, y, z);

    /**
     * Dirty flag is used by the Node to determine
     * if the matrix is updated to latest
     * @name _dirty
     * @type {boolean}
     * @memberOf clay.Vector3#
     */
    this._dirty = true;
};

Vector3.prototype = {

    constructor: Vector3,

    /**
     * Add b to self
     * @param  {clay.Vector3} b
     * @return {clay.Vector3}
     */
    add: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].add(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Set x, y and z components
     * @param  {number}  x
     * @param  {number}  y
     * @param  {number}  z
     * @return {clay.Vector3}
     */
    set: function (x, y, z) {
        this.array[0] = x;
        this.array[1] = y;
        this.array[2] = z;
        this._dirty = true;
        return this;
    },

    /**
     * Set x, y and z components from array
     * @param  {Float32Array|number[]} arr
     * @return {clay.Vector3}
     */
    setArray: function (arr) {
        this.array[0] = arr[0];
        this.array[1] = arr[1];
        this.array[2] = arr[2];

        this._dirty = true;
        return this;
    },

    /**
     * Clone a new Vector3
     * @return {clay.Vector3}
     */
    clone: function () {
        return new Vector3(this.x, this.y, this.z);
    },

    /**
     * Copy from b
     * @param  {clay.Vector3} b
     * @return {clay.Vector3}
     */
    copy: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].copy(this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Cross product of self and b, written to a Vector3 out
     * @param  {clay.Vector3} a
     * @param  {clay.Vector3} b
     * @return {clay.Vector3}
     */
    cross: function (a, b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].cross(this.array, a.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for distance
     * @param  {clay.Vector3} b
     * @return {number}
     */
    dist: function (b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].dist(this.array, b.array);
    },

    /**
     * Distance between self and b
     * @param  {clay.Vector3} b
     * @return {number}
     */
    distance: function (b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].distance(this.array, b.array);
    },

    /**
     * Alias for divide
     * @param  {clay.Vector3} b
     * @return {clay.Vector3}
     */
    div: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].div(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Divide self by b
     * @param  {clay.Vector3} b
     * @return {clay.Vector3}
     */
    divide: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].divide(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Dot product of self and b
     * @param  {clay.Vector3} b
     * @return {number}
     */
    dot: function (b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].dot(this.array, b.array);
    },

    /**
     * Alias of length
     * @return {number}
     */
    len: function () {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].len(this.array);
    },

    /**
     * Calculate the length
     * @return {number}
     */
    length: function () {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].length(this.array);
    },
    /**
     * Linear interpolation between a and b
     * @param  {clay.Vector3} a
     * @param  {clay.Vector3} b
     * @param  {number}  t
     * @return {clay.Vector3}
     */
    lerp: function (a, b, t) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].lerp(this.array, a.array, b.array, t);
        this._dirty = true;
        return this;
    },

    /**
     * Minimum of self and b
     * @param  {clay.Vector3} b
     * @return {clay.Vector3}
     */
    min: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].min(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Maximum of self and b
     * @param  {clay.Vector3} b
     * @return {clay.Vector3}
     */
    max: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].max(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for multiply
     * @param  {clay.Vector3} b
     * @return {clay.Vector3}
     */
    mul: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].mul(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Mutiply self and b
     * @param  {clay.Vector3} b
     * @return {clay.Vector3}
     */
    multiply: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].multiply(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Negate self
     * @return {clay.Vector3}
     */
    negate: function () {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].negate(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Normalize self
     * @return {clay.Vector3}
     */
    normalize: function () {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].normalize(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Generate random x, y, z components with a given scale
     * @param  {number} scale
     * @return {clay.Vector3}
     */
    random: function (scale) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].random(this.array, scale);
        this._dirty = true;
        return this;
    },

    /**
     * Scale self
     * @param  {number}  scale
     * @return {clay.Vector3}
     */
    scale: function (s) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].scale(this.array, this.array, s);
        this._dirty = true;
        return this;
    },

    /**
     * Scale b and add to self
     * @param  {clay.Vector3} b
     * @param  {number}  scale
     * @return {clay.Vector3}
     */
    scaleAndAdd: function (b, s) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].scaleAndAdd(this.array, this.array, b.array, s);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for squaredDistance
     * @param  {clay.Vector3} b
     * @return {number}
     */
    sqrDist: function (b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].sqrDist(this.array, b.array);
    },

    /**
     * Squared distance between self and b
     * @param  {clay.Vector3} b
     * @return {number}
     */
    squaredDistance: function (b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].squaredDistance(this.array, b.array);
    },

    /**
     * Alias for squaredLength
     * @return {number}
     */
    sqrLen: function () {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].sqrLen(this.array);
    },

    /**
     * Squared length of self
     * @return {number}
     */
    squaredLength: function () {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].squaredLength(this.array);
    },

    /**
     * Alias for subtract
     * @param  {clay.Vector3} b
     * @return {clay.Vector3}
     */
    sub: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].sub(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Subtract b from self
     * @param  {clay.Vector3} b
     * @return {clay.Vector3}
     */
    subtract: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].subtract(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Transform self with a Matrix3 m
     * @param  {clay.Matrix3} m
     * @return {clay.Vector3}
     */
    transformMat3: function (m) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].transformMat3(this.array, this.array, m.array);
        this._dirty = true;
        return this;
    },

    /**
     * Transform self with a Matrix4 m
     * @param  {clay.Matrix4} m
     * @return {clay.Vector3}
     */
    transformMat4: function (m) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].transformMat4(this.array, this.array, m.array);
        this._dirty = true;
        return this;
    },
    /**
     * Transform self with a Quaternion q
     * @param  {clay.Quaternion} q
     * @return {clay.Vector3}
     */
    transformQuat: function (q) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].transformQuat(this.array, this.array, q.array);
        this._dirty = true;
        return this;
    },

    /**
     * Trasnform self into projection space with m
     * @param  {clay.Matrix4} m
     * @return {clay.Vector3}
     */
    applyProjection: function (m) {
        var v = this.array;
        m = m.array;

        // Perspective projection
        if (m[15] === 0) {
            var w = -1 / v[2];
            v[0] = m[0] * v[0] * w;
            v[1] = m[5] * v[1] * w;
            v[2] = (m[10] * v[2] + m[14]) * w;
        }
        else {
            v[0] = m[0] * v[0] + m[12];
            v[1] = m[5] * v[1] + m[13];
            v[2] = m[10] * v[2] + m[14];
        }
        this._dirty = true;

        return this;
    },

    eulerFromQuat: function(q, order) {
        Vector3.eulerFromQuat(this, q, order);
    },

    eulerFromMat3: function (m, order) {
        Vector3.eulerFromMat3(this, m, order);
    },

    toString: function() {
        return '[' + Array.prototype.join.call(this.array, ',') + ']';
    },

    toArray: function () {
        return Array.prototype.slice.call(this.array);
    }
};

var defineProperty = Object.defineProperty;
// Getter and Setter
if (defineProperty) {

    var proto = Vector3.prototype;
    /**
     * @name x
     * @type {number}
     * @memberOf clay.Vector3
     * @instance
     */
    defineProperty(proto, 'x', {
        get: function () {
            return this.array[0];
        },
        set: function (value) {
            this.array[0] = value;
            this._dirty = true;
        }
    });

    /**
     * @name y
     * @type {number}
     * @memberOf clay.Vector3
     * @instance
     */
    defineProperty(proto, 'y', {
        get: function () {
            return this.array[1];
        },
        set: function (value) {
            this.array[1] = value;
            this._dirty = true;
        }
    });

    /**
     * @name z
     * @type {number}
     * @memberOf clay.Vector3
     * @instance
     */
    defineProperty(proto, 'z', {
        get: function () {
            return this.array[2];
        },
        set: function (value) {
            this.array[2] = value;
            this._dirty = true;
        }
    });
}


// Supply methods that are not in place

/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {clay.Vector3}
 */
Vector3.add = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].add(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector3} out
 * @param  {number}  x
 * @param  {number}  y
 * @param  {number}  z
 * @return {clay.Vector3}
 */
Vector3.set = function(out, x, y, z) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].set(out.array, x, y, z);
    out._dirty = true;
};

/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} b
 * @return {clay.Vector3}
 */
Vector3.copy = function(out, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].copy(out.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {clay.Vector3}
 */
Vector3.cross = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].cross(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {number}
 */
Vector3.dist = function(a, b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].distance(a.array, b.array);
};

/**
 * @function
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {number}
 */
Vector3.distance = Vector3.dist;

/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {clay.Vector3}
 */
Vector3.div = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].divide(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @function
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {clay.Vector3}
 */
Vector3.divide = Vector3.div;

/**
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {number}
 */
Vector3.dot = function(a, b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].dot(a.array, b.array);
};

/**
 * @param  {clay.Vector3} a
 * @return {number}
 */
Vector3.len = function(b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].length(b.array);
};

// Vector3.length = Vector3.len;

/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @param  {number}  t
 * @return {clay.Vector3}
 */
Vector3.lerp = function(out, a, b, t) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].lerp(out.array, a.array, b.array, t);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {clay.Vector3}
 */
Vector3.min = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].min(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {clay.Vector3}
 */
Vector3.max = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].max(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {clay.Vector3}
 */
Vector3.mul = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].multiply(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};
/**
 * @function
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {clay.Vector3}
 */
Vector3.multiply = Vector3.mul;
/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @return {clay.Vector3}
 */
Vector3.negate = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].negate(out.array, a.array);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @return {clay.Vector3}
 */
Vector3.normalize = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].normalize(out.array, a.array);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector3} out
 * @param  {number}  scale
 * @return {clay.Vector3}
 */
Vector3.random = function(out, scale) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].random(out.array, scale);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {number}  scale
 * @return {clay.Vector3}
 */
Vector3.scale = function(out, a, scale) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].scale(out.array, a.array, scale);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @param  {number}  scale
 * @return {clay.Vector3}
 */
Vector3.scaleAndAdd = function(out, a, b, scale) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].scaleAndAdd(out.array, a.array, b.array, scale);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {number}
 */
Vector3.sqrDist = function(a, b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].sqrDist(a.array, b.array);
};
/**
 * @function
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {number}
 */
Vector3.squaredDistance = Vector3.sqrDist;
/**
 * @param  {clay.Vector3} a
 * @return {number}
 */
Vector3.sqrLen = function(a) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].sqrLen(a.array);
};
/**
 * @function
 * @param  {clay.Vector3} a
 * @return {number}
 */
Vector3.squaredLength = Vector3.sqrLen;

/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {clay.Vector3}
 */
Vector3.sub = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].subtract(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};
/**
 * @function
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Vector3} b
 * @return {clay.Vector3}
 */
Vector3.subtract = Vector3.sub;

/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {Matrix3} m
 * @return {clay.Vector3}
 */
Vector3.transformMat3 = function(out, a, m) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].transformMat3(out.array, a.array, m.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Matrix4} m
 * @return {clay.Vector3}
 */
Vector3.transformMat4 = function(out, a, m) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].transformMat4(out.array, a.array, m.array);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector3} a
 * @param  {clay.Quaternion} q
 * @return {clay.Vector3}
 */
Vector3.transformQuat = function(out, a, q) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec3__["a" /* default */].transformQuat(out.array, a.array, q.array);
    out._dirty = true;
    return out;
};

function clamp(val, min, max) {
    return val < min ? min : (val > max ? max : val);
}
var atan2 = Math.atan2;
var asin = Math.asin;
var abs = Math.abs;
/**
 * Convert quaternion to euler angle
 * Quaternion must be normalized
 * From three.js
 */
Vector3.eulerFromQuat = function (out, q, order) {
    out._dirty = true;
    q = q.array;

    var target = out.array;
    var x = q[0], y = q[1], z = q[2], w = q[3];
    var x2 = x * x;
    var y2 = y * y;
    var z2 = z * z;
    var w2 = w * w;

    var order = (order || 'XYZ').toUpperCase();

    switch (order) {
        case 'XYZ':
            target[0] = atan2(2 * (x * w - y * z), (w2 - x2 - y2 + z2));
            target[1] = asin(clamp(2 * (x * z + y * w), - 1, 1));
            target[2] = atan2(2 * (z * w - x * y), (w2 + x2 - y2 - z2));
            break;
        case 'YXZ':
            target[0] = asin(clamp(2 * (x * w - y * z), - 1, 1));
            target[1] = atan2(2 * (x * z + y * w), (w2 - x2 - y2 + z2));
            target[2] = atan2(2 * (x * y + z * w), (w2 - x2 + y2 - z2));
            break;
        case 'ZXY':
            target[0] = asin(clamp(2 * (x * w + y * z), - 1, 1));
            target[1] = atan2(2 * (y * w - z * x), (w2 - x2 - y2 + z2));
            target[2] = atan2(2 * (z * w - x * y), (w2 - x2 + y2 - z2));
            break;
        case 'ZYX':
            target[0] = atan2(2 * (x * w + z * y), (w2 - x2 - y2 + z2));
            target[1] = asin(clamp(2 * (y * w - x * z), - 1, 1));
            target[2] = atan2(2 * (x * y + z * w), (w2 + x2 - y2 - z2));
            break;
        case 'YZX':
            target[0] = atan2(2 * (x * w - z * y), (w2 - x2 + y2 - z2));
            target[1] = atan2(2 * (y * w - x * z), (w2 + x2 - y2 - z2));
            target[2] = asin(clamp(2 * (x * y + z * w), - 1, 1));
            break;
        case 'XZY':
            target[0] = atan2(2 * (x * w + y * z), (w2 - x2 + y2 - z2));
            target[1] = atan2(2 * (x * z + y * w), (w2 + x2 - y2 - z2));
            target[2] = asin(clamp(2 * (z * w - x * y), - 1, 1));
            break;
        default:
            console.warn('Unkown order: ' + order);
    }
    return out;
};

/**
 * Convert rotation matrix to euler angle
 * from three.js
 */
Vector3.eulerFromMat3 = function (out, m, order) {
    // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
    var te = m.array;
    var m11 = te[0], m12 = te[3], m13 = te[6];
    var m21 = te[1], m22 = te[4], m23 = te[7];
    var m31 = te[2], m32 = te[5], m33 = te[8];
    var target = out.array;

    var order = (order || 'XYZ').toUpperCase();

    switch (order) {
        case 'XYZ':
            target[1] = asin(clamp(m13, -1, 1));
            if (abs(m13) < 0.99999) {
                target[0] = atan2(-m23, m33);
                target[2] = atan2(-m12, m11);
            }
            else {
                target[0] = atan2(m32, m22);
                target[2] = 0;
            }
            break;
        case 'YXZ':
            target[0] = asin(-clamp(m23, -1, 1));
            if (abs(m23) < 0.99999) {
                target[1] = atan2(m13, m33);
                target[2] = atan2(m21, m22);
            }
            else {
                target[1] = atan2(-m31, m11);
                target[2] = 0;
            }
            break;
        case 'ZXY':
            target[0] = asin(clamp(m32, -1, 1));
            if (abs(m32) < 0.99999) {
                target[1] = atan2(-m31, m33);
                target[2] = atan2(-m12, m22);
            }
            else {
                target[1] = 0;
                target[2] = atan2(m21, m11);
            }
            break;
        case 'ZYX':
            target[1] = asin(-clamp(m31, -1, 1));
            if (abs(m31) < 0.99999) {
                target[0] = atan2(m32, m33);
                target[2] = atan2(m21, m11);
            }
            else {
                target[0] = 0;
                target[2] = atan2(-m12, m22);
            }
            break;
        case 'YZX':
            target[2] = asin(clamp(m21, -1, 1));
            if (abs(m21) < 0.99999) {
                target[0] = atan2(-m23, m22);
                target[1] = atan2(-m31, m11);
            }
            else {
                target[0] = 0;
                target[1] = atan2(m13, m33);
            }
            break;
        case 'XZY':
            target[2] = asin(-clamp(m12, -1, 1));
            if (abs(m12) < 0.99999) {
                target[0] = atan2(m32, m22);
                target[1] = atan2(m13, m11);
            }
            else {
                target[0] = atan2(-m23, m33);
                target[1] = 0;
            }
            break;
        default:
            console.warn('Unkown order: ' + order);
    }
    out._dirty = true;

    return out;
};

Object.defineProperties(Vector3, {
    /**
     * @type {clay.Vector3}
     * @readOnly
     * @memberOf clay.Vector3
     */
    POSITIVE_X: {
        get: function () {
            return new Vector3(1, 0, 0);
        }
    },
    /**
     * @type {clay.Vector3}
     * @readOnly
     * @memberOf clay.Vector3
     */
    NEGATIVE_X: {
        get: function () {
            return new Vector3(-1, 0, 0);
        }
    },
    /**
     * @type {clay.Vector3}
     * @readOnly
     * @memberOf clay.Vector3
     */
    POSITIVE_Y: {
        get: function () {
            return new Vector3(0, 1, 0);
        }
    },
    /**
     * @type {clay.Vector3}
     * @readOnly
     * @memberOf clay.Vector3
     */
    NEGATIVE_Y: {
        get: function () {
            return new Vector3(0, -1, 0);
        }
    },
    /**
     * @type {clay.Vector3}
     * @readOnly
     * @memberOf clay.Vector3
     */
    POSITIVE_Z: {
        get: function () {
            return new Vector3(0, 0, 1);
        }
    },
    /**
     * @type {clay.Vector3}
     * @readOnly
     */
    NEGATIVE_Z: {
        get: function () {
            return new Vector3(0, 0, -1);
        }
    },
    /**
     * @type {clay.Vector3}
     * @readOnly
     * @memberOf clay.Vector3
     */
    UP: {
        get: function () {
            return new Vector3(0, 1, 0);
        }
    },
    /**
     * @type {clay.Vector3}
     * @readOnly
     * @memberOf clay.Vector3
     */
    ZERO: {
        get: function () {
            return new Vector3();
        }
    }
});

/* harmony default export */ __webpack_exports__["a"] = (Vector3);


/***/ }),
/* 4 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_Cache__ = __webpack_require__(57);
/**
 * Base class for all textures like compressed texture, texture2d, texturecube
 * TODO mapping
 */




/**
 * @constructor
 * @alias clay.Texture
 * @extends clay.core.Base
 */
var Texture = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend( /** @lends clay.Texture# */ {
    /**
     * Texture width, readonly when the texture source is image
     * @type {number}
     */
    width: 512,
    /**
     * Texture height, readonly when the texture source is image
     * @type {number}
     */
    height: 512,
    /**
     * Texel data type.
     * Possible values:
     *  + {@link clay.Texture.UNSIGNED_BYTE}
     *  + {@link clay.Texture.HALF_FLOAT}
     *  + {@link clay.Texture.FLOAT}
     *  + {@link clay.Texture.UNSIGNED_INT_24_8_WEBGL}
     *  + {@link clay.Texture.UNSIGNED_INT}
     * @type {number}
     */
    type: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].UNSIGNED_BYTE,
    /**
     * Format of texel data
     * Possible values:
     *  + {@link clay.Texture.RGBA}
     *  + {@link clay.Texture.DEPTH_COMPONENT}
     *  + {@link clay.Texture.DEPTH_STENCIL}
     * @type {number}
     */
    format: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].RGBA,
    /**
     * Texture wrap. Default to be REPEAT.
     * Possible values:
     *  + {@link clay.Texture.CLAMP_TO_EDGE}
     *  + {@link clay.Texture.REPEAT}
     *  + {@link clay.Texture.MIRRORED_REPEAT}
     * @type {number}
     */
    wrapS: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].REPEAT,
    /**
     * Texture wrap. Default to be REPEAT.
     * Possible values:
     *  + {@link clay.Texture.CLAMP_TO_EDGE}
     *  + {@link clay.Texture.REPEAT}
     *  + {@link clay.Texture.MIRRORED_REPEAT}
     * @type {number}
     */
    wrapT: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].REPEAT,
    /**
     * Possible values:
     *  + {@link clay.Texture.NEAREST}
     *  + {@link clay.Texture.LINEAR}
     *  + {@link clay.Texture.NEAREST_MIPMAP_NEAREST}
     *  + {@link clay.Texture.LINEAR_MIPMAP_NEAREST}
     *  + {@link clay.Texture.NEAREST_MIPMAP_LINEAR}
     *  + {@link clay.Texture.LINEAR_MIPMAP_LINEAR}
     * @type {number}
     */
    minFilter: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_LINEAR,
    /**
     * Possible values:
     *  + {@link clay.Texture.NEAREST}
     *  + {@link clay.Texture.LINEAR}
     * @type {number}
     */
    magFilter: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR,
    /**
     * If enable mimap.
     * @type {boolean}
     */
    useMipmap: true,

    /**
     * Anisotropic filtering, enabled if value is larger than 1
     * @see https://developer.mozilla.org/en-US/docs/Web/API/EXT_texture_filter_anisotropic
     * @type {number}
     */
    anisotropic: 1,
    // pixelStorei parameters, not available when texture is used as render target
    // http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml
    /**
     * If flip in y axis for given image source
     * @type {boolean}
     * @default true
     */
    flipY: true,

    /**
     * A flag to indicate if texture source is sRGB
     */
    sRGB: true,
    /**
     * @type {number}
     * @default 4
     */
    unpackAlignment: 4,
    /**
     * @type {boolean}
     * @default false
     */
    premultiplyAlpha: false,

    /**
     * Dynamic option for texture like video
     * @type {boolean}
     */
    dynamic: false,

    NPOT: false,

    // PENDING
    // Init it here to avoid deoptimization when it's assigned in application dynamically
    __used: 0

}, function () {
    this._cache = new __WEBPACK_IMPORTED_MODULE_2__core_Cache__["a" /* default */]();
},
/** @lends clay.Texture.prototype */
{

    getWebGLTexture: function (renderer) {
        var _gl = renderer.gl;
        var cache = this._cache;
        cache.use(renderer.__uid__);

        if (cache.miss('webgl_texture')) {
            // In a new gl context, create new texture and set dirty true
            cache.put('webgl_texture', _gl.createTexture());
        }
        if (this.dynamic) {
            this.update(renderer);
        }
        else if (cache.isDirty()) {
            this.update(renderer);
            cache.fresh();
        }

        return cache.get('webgl_texture');
    },

    bind: function () {},
    unbind: function () {},

    /**
     * Mark texture is dirty and update in the next frame
     */
    dirty: function () {
        if (this._cache) {
            this._cache.dirtyAll();
        }
    },

    update: function (renderer) {},

    // Update the common parameters of texture
    updateCommon: function (renderer) {
        var _gl = renderer.gl;
        _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, this.flipY);
        _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);
        _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, this.unpackAlignment);

        // Use of none-power of two texture
        // http://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences
        if (this.format === __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DEPTH_COMPONENT) {
            this.useMipmap = false;
        }

        var sRGBExt = renderer.getGLExtension('EXT_sRGB');
        // Fallback
        if (this.format === Texture.SRGB && !sRGBExt) {
            this.format = Texture.RGB;
        }
        if (this.format === Texture.SRGB_ALPHA && !sRGBExt) {
            this.format = Texture.RGBA;
        }

        this.NPOT = !this.isPowerOfTwo();
    },

    getAvailableWrapS: function () {
        if (this.NPOT) {
            return __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE;
        }
        return this.wrapS;
    },
    getAvailableWrapT: function () {
        if (this.NPOT) {
            return __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE;
        }
        return this.wrapT;
    },
    getAvailableMinFilter: function () {
        var minFilter = this.minFilter;
        if (this.NPOT || !this.useMipmap) {
            if (minFilter === __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST_MIPMAP_NEAREST ||
                minFilter === __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST_MIPMAP_LINEAR
            ) {
                return __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST;
            }
            else if (minFilter === __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_LINEAR ||
                minFilter === __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_NEAREST
            ) {
                return __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR;
            }
            else {
                return minFilter;
            }
        }
        else {
            return minFilter;
        }
    },
    getAvailableMagFilter: function () {
        return this.magFilter;
    },

    nextHighestPowerOfTwo: function (x) {
        --x;
        for (var i = 1; i < 32; i <<= 1) {
            x = x | x >> i;
        }
        return x + 1;
    },
    /**
     * @param  {clay.Renderer} renderer
     */
    dispose: function (renderer) {

        var cache = this._cache;

        cache.use(renderer.__uid__);

        var webglTexture = cache.get('webgl_texture');
        if (webglTexture){
            renderer.gl.deleteTexture(webglTexture);
        }
        cache.deleteContext(renderer.__uid__);

    },
    /**
     * Test if image of texture is valid and loaded.
     * @return {boolean}
     */
    isRenderable: function () {},

    /**
     * Test if texture size is power of two
     * @return {boolean}
     */
    isPowerOfTwo: function () {}
});

Object.defineProperty(Texture.prototype, 'width', {
    get: function () {
        return this._width;
    },
    set: function (value) {
        this._width = value;
    }
});
Object.defineProperty(Texture.prototype, 'height', {
    get: function () {
        return this._height;
    },
    set: function (value) {
        this._height = value;
    }
});

/* DataType */

/**
 * @type {number}
 */
Texture.BYTE = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].BYTE;
/**
 * @type {number}
 */
Texture.UNSIGNED_BYTE = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].UNSIGNED_BYTE;
/**
 * @type {number}
 */
Texture.SHORT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].SHORT;
/**
 * @type {number}
 */
Texture.UNSIGNED_SHORT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].UNSIGNED_SHORT;
/**
 * @type {number}
 */
Texture.INT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].INT;
/**
 * @type {number}
 */
Texture.UNSIGNED_INT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].UNSIGNED_INT;
/**
 * @type {number}
 */
Texture.FLOAT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FLOAT;
/**
 * @type {number}
 */
Texture.HALF_FLOAT = 0x8D61;

/**
 * UNSIGNED_INT_24_8_WEBGL for WEBGL_depth_texture extension
 * @type {number}
 */
Texture.UNSIGNED_INT_24_8_WEBGL = 34042;

/* PixelFormat */
/**
 * @type {number}
 */
Texture.DEPTH_COMPONENT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DEPTH_COMPONENT;
/**
 * @type {number}
 */
Texture.DEPTH_STENCIL = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DEPTH_STENCIL;
/**
 * @type {number}
 */
Texture.ALPHA = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].ALPHA;
/**
 * @type {number}
 */
Texture.RGB = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].RGB;
/**
 * @type {number}
 */
Texture.RGBA = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].RGBA;
/**
 * @type {number}
 */
Texture.LUMINANCE = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LUMINANCE;
/**
 * @type {number}
 */
Texture.LUMINANCE_ALPHA = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LUMINANCE_ALPHA;

/**
 * @see https://www.khronos.org/registry/webgl/extensions/EXT_sRGB/
 * @type {number}
 */
Texture.SRGB = 0x8C40;
/**
 * @see https://www.khronos.org/registry/webgl/extensions/EXT_sRGB/
 * @type {number}
 */
Texture.SRGB_ALPHA = 0x8C42;

/* Compressed Texture */
Texture.COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0;
Texture.COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
Texture.COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
Texture.COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;

/* TextureMagFilter */
/**
 * @type {number}
 */
Texture.NEAREST = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST;
/**
 * @type {number}
 */
Texture.LINEAR = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR;

/* TextureMinFilter */
/**
 * @type {number}
 */
Texture.NEAREST_MIPMAP_NEAREST = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST_MIPMAP_NEAREST;
/**
 * @type {number}
 */
Texture.LINEAR_MIPMAP_NEAREST = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_NEAREST;
/**
 * @type {number}
 */
Texture.NEAREST_MIPMAP_LINEAR = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST_MIPMAP_LINEAR;
/**
 * @type {number}
 */
Texture.LINEAR_MIPMAP_LINEAR = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_LINEAR;

/* TextureWrapMode */
/**
 * @type {number}
 */
Texture.REPEAT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].REPEAT;
/**
 * @type {number}
 */
Texture.CLAMP_TO_EDGE = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE;
/**
 * @type {number}
 */
Texture.MIRRORED_REPEAT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].MIRRORED_REPEAT;


/* harmony default export */ __webpack_exports__["a"] = (Texture);


/***/ }),
/* 5 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_vendor__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_util__ = __webpack_require__(73);




var isPowerOfTwo = __WEBPACK_IMPORTED_MODULE_3__math_util__["a" /* default */].isPowerOfTwo;

function nearestPowerOfTwo(val) {
    return Math.pow(2, Math.round(Math.log(val) / Math.LN2));
}
function convertTextureToPowerOfTwo(texture, canvas) {
    // var canvas = document.createElement('canvas');
    var width = nearestPowerOfTwo(texture.width);
    var height = nearestPowerOfTwo(texture.height);
    canvas = canvas || document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    var ctx = canvas.getContext('2d');
    ctx.drawImage(texture.image, 0, 0, width, height);

    return canvas;
}

/**
 * @constructor clay.Texture2D
 * @extends clay.Texture
 *
 * @example
 *     ...
 *     var mat = new clay.Material({
 *         shader: clay.shader.library.get('clay.phong', 'diffuseMap')
 *     });
 *     var diffuseMap = new clay.Texture2D();
 *     diffuseMap.load('assets/textures/diffuse.jpg');
 *     mat.set('diffuseMap', diffuseMap);
 *     ...
 *     diffuseMap.success(function () {
 *         // Wait for the diffuse texture loaded
 *         animation.on('frame', function (frameTime) {
 *             renderer.render(scene, camera);
 *         });
 *     });
 */
var Texture2D = __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].extend(function () {
    return /** @lends clay.Texture2D# */ {
        /**
         * @type {?HTMLImageElement|HTMLCanvasElemnet}
         */
        // TODO mark dirty when assigned.
        image: null,
        /**
         * Pixels data. Will be ignored if image is set.
         * @type {?Uint8Array|Float32Array}
         */
        pixels: null,
        /**
         * @type {Array.<Object>}
         * @example
         *     [{
         *         image: mipmap0,
         *         pixels: null
         *     }, {
         *         image: mipmap1,
         *         pixels: null
         *     }, ....]
         */
        mipmaps: [],

        /**
         * If convert texture to power-of-two
         * @type {boolean}
         */
        convertToPOT: false
    };
}, {

    textureType: 'texture2D',

    update: function (renderer) {

        var _gl = renderer.gl;
        _gl.bindTexture(_gl.TEXTURE_2D, this._cache.get('webgl_texture'));

        this.updateCommon(renderer);

        var glFormat = this.format;
        var glType = this.type;

        // Convert to pot is only available when using image/canvas/video element.
        var convertToPOT = !!(this.convertToPOT
            && !this.mipmaps.length && this.image
            && (this.wrapS === __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].REPEAT || this.wrapT === __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].REPEAT)
            && this.NPOT
        );

        _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, convertToPOT ? this.wrapS : this.getAvailableWrapS());
        _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, convertToPOT ? this.wrapT : this.getAvailableWrapT());

        _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, convertToPOT ? this.magFilter : this.getAvailableMagFilter());
        _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, convertToPOT ? this.minFilter : this.getAvailableMinFilter());

        var anisotropicExt = renderer.getGLExtension('EXT_texture_filter_anisotropic');
        if (anisotropicExt && this.anisotropic > 1) {
            _gl.texParameterf(_gl.TEXTURE_2D, anisotropicExt.TEXTURE_MAX_ANISOTROPY_EXT, this.anisotropic);
        }

        // Fallback to float type if browser don't have half float extension
        if (glType === 36193) {
            var halfFloatExt = renderer.getGLExtension('OES_texture_half_float');
            if (!halfFloatExt) {
                glType = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FLOAT;
            }
        }

        if (this.mipmaps.length) {
            var width = this.width;
            var height = this.height;
            for (var i = 0; i < this.mipmaps.length; i++) {
                var mipmap = this.mipmaps[i];
                this._updateTextureData(_gl, mipmap, i, width, height, glFormat, glType, false);
                width /= 2;
                height /= 2;
            }
        }
        else {
            this._updateTextureData(_gl, this, 0, this.width, this.height, glFormat, glType, convertToPOT);

            if (this.useMipmap && (!this.NPOT || convertToPOT)) {
                _gl.generateMipmap(_gl.TEXTURE_2D);
            }
        }

        _gl.bindTexture(_gl.TEXTURE_2D, null);
    },

    _updateTextureData: function (_gl, data, level, width, height, glFormat, glType, convertToPOT) {
        if (data.image) {
            var imgData = data.image;
            if (convertToPOT) {
                this._potCanvas = convertTextureToPowerOfTwo(this, this._potCanvas);
                imgData = this._potCanvas;
            }
            _gl.texImage2D(_gl.TEXTURE_2D, level, glFormat, glFormat, glType, imgData);
        }
        else {
            // Can be used as a blank texture when writing render to texture(RTT)
            if (
                glFormat <= __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].COMPRESSED_RGBA_S3TC_DXT5_EXT
                && glFormat >= __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].COMPRESSED_RGB_S3TC_DXT1_EXT
            ) {
                _gl.compressedTexImage2D(_gl.TEXTURE_2D, level, glFormat, width, height, 0, data.pixels);
            }
            else {
                // Is a render target if pixels is null
                _gl.texImage2D(_gl.TEXTURE_2D, level, glFormat, width, height, 0, glFormat, glType, data.pixels);
            }
        }
    },

    /**
     * @param  {clay.Renderer} renderer
     * @memberOf clay.Texture2D.prototype
     */
    generateMipmap: function (renderer) {
        var _gl = renderer.gl;
        if (this.useMipmap && !this.NPOT) {
            _gl.bindTexture(_gl.TEXTURE_2D, this._cache.get('webgl_texture'));
            _gl.generateMipmap(_gl.TEXTURE_2D);
        }
    },

    isPowerOfTwo: function () {
        return isPowerOfTwo(this.width) && isPowerOfTwo(this.height);
    },

    isRenderable: function () {
        if (this.image) {
            return this.image.nodeName === 'CANVAS'
                || this.image.nodeName === 'VIDEO'
                || this.image.complete;
        }
        else {
            return !!(this.width && this.height);
        }
    },

    bind: function (renderer) {
        renderer.gl.bindTexture(renderer.gl.TEXTURE_2D, this.getWebGLTexture(renderer));
    },

    unbind: function (renderer) {
        renderer.gl.bindTexture(renderer.gl.TEXTURE_2D, null);
    },

    load: function (src, crossOrigin) {
        var image = __WEBPACK_IMPORTED_MODULE_2__core_vendor__["a" /* default */].createImage();
        if (crossOrigin) {
            image.crossOrigin = crossOrigin;
        }
        var self = this;
        image.onload = function () {
            self.dirty();
            self.trigger('success', self);
            image.onload = null;
        };
        image.onerror = function () {
            self.trigger('error', self);
            image.onerror = null;
        };

        image.src = src;
        this.image = image;

        return this;
    }
});

Object.defineProperty(Texture2D.prototype, 'width', {
    get: function () {
        if (this.image) {
            return this.image.width;
        }
        return this._width;
    },
    set: function (value) {
        if (this.image) {
            console.warn('Texture from image can\'t set width');
        }
        else {
            if (this._width !== value) {
                this.dirty();
            }
            this._width = value;
        }
    }
});
Object.defineProperty(Texture2D.prototype, 'height', {
    get: function () {
        if (this.image) {
            return this.image.height;
        }
        return this._height;
    },
    set: function (value) {
        if (this.image) {
            console.warn('Texture from image can\'t set height');
        }
        else {
            if (this._height !== value) {
                this.dirty();
            }
            this._height = value;
        }
    }
});

/* harmony default export */ __webpack_exports__["a"] = (Texture2D);


/***/ }),
/* 6 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__glmatrix__ = __webpack_require__(161);
// DEPRECATED


/* harmony default export */ __webpack_exports__["a"] = (__WEBPACK_IMPORTED_MODULE_0__glmatrix__["a" /* default */]);


/***/ }),
/* 7 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__mixin_extend__ = __webpack_require__(110);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__mixin_notifier__ = __webpack_require__(53);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util__ = __webpack_require__(23);




/**
 * Base class of all objects
 * @constructor
 * @alias clay.core.Base
 * @mixes clay.core.mixin.notifier
 */
var Base = function () {
    /**
     * @type {number}
     */
    this.__uid__ = __WEBPACK_IMPORTED_MODULE_2__util__["a" /* default */].genGUID();
};

Base.__initializers__ = [
    function (opts) {
        __WEBPACK_IMPORTED_MODULE_2__util__["a" /* default */].extend(this, opts);
    }
];

__WEBPACK_IMPORTED_MODULE_2__util__["a" /* default */].extend(Base, __WEBPACK_IMPORTED_MODULE_0__mixin_extend__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_2__util__["a" /* default */].extend(Base.prototype, __WEBPACK_IMPORTED_MODULE_1__mixin_notifier__["a" /* default */]);

/* harmony default export */ __webpack_exports__["a"] = (Base);


/***/ }),
/* 8 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_util__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_vendor__ = __webpack_require__(14);
/**
 * Mainly do the parse and compile of shader string
 * Support shader code chunk import and export
 * Support shader semantics
 * http://www.nvidia.com/object/using_sas.html
 * https://github.com/KhronosGroup/collada2json/issues/45
 */



var uniformRegex = /uniform\s+(bool|float|int|vec2|vec3|vec4|ivec2|ivec3|ivec4|mat2|mat3|mat4|sampler2D|samplerCube)\s+([\s\S]*?);/g;
var attributeRegex = /attribute\s+(float|int|vec2|vec3|vec4)\s+([\s\S]*?);/g;
// Only parse number define.
var defineRegex = /#define\s+(\w+)?(\s+[\d-.]+)?\s*;?\s*\n/g;

var uniformTypeMap = {
    'bool': '1i',
    'int': '1i',
    'sampler2D': 't',
    'samplerCube': 't',
    'float': '1f',
    'vec2': '2f',
    'vec3': '3f',
    'vec4': '4f',
    'ivec2': '2i',
    'ivec3': '3i',
    'ivec4': '4i',
    'mat2': 'm2',
    'mat3': 'm3',
    'mat4': 'm4'
};

function createZeroArray(len) {
    var arr = [];
    for (var i = 0; i < len; i++) {
        arr[i] = 0;
    }
    return arr;
}

var uniformValueConstructor = {
    'bool': function () { return true; },
    'int': function () { return 0; },
    'float': function () { return 0; },
    'sampler2D': function () { return null; },
    'samplerCube': function () { return null; },

    'vec2': function () { return createZeroArray(2); },
    'vec3': function () { return createZeroArray(3); },
    'vec4': function () { return createZeroArray(4); },

    'ivec2': function () { return createZeroArray(2); },
    'ivec3': function () { return createZeroArray(3); },
    'ivec4': function () { return createZeroArray(4); },

    'mat2': function () { return createZeroArray(4); },
    'mat3': function () { return createZeroArray(9); },
    'mat4': function () { return createZeroArray(16); },

    'array': function () { return []; }
};

var attributeSemantics = [
    'POSITION',
    'NORMAL',
    'BINORMAL',
    'TANGENT',
    'TEXCOORD',
    'TEXCOORD_0',
    'TEXCOORD_1',
    'COLOR',
    // Skinning
    // https://github.com/KhronosGroup/glTF/blob/master/specification/README.md#semantics
    'JOINT',
    'WEIGHT'
];
var uniformSemantics = [
    'SKIN_MATRIX',
    // Information about viewport
    'VIEWPORT_SIZE',
    'VIEWPORT',
    'DEVICEPIXELRATIO',
    // Window size for window relative coordinate
    // https://www.opengl.org/sdk/docs/man/html/gl_FragCoord.xhtml
    'WINDOW_SIZE',
    // Infomation about camera
    'NEAR',
    'FAR',
    // Time
    'TIME'
];
var matrixSemantics = [
    'WORLD',
    'VIEW',
    'PROJECTION',
    'WORLDVIEW',
    'VIEWPROJECTION',
    'WORLDVIEWPROJECTION',
    'WORLDINVERSE',
    'VIEWINVERSE',
    'PROJECTIONINVERSE',
    'WORLDVIEWINVERSE',
    'VIEWPROJECTIONINVERSE',
    'WORLDVIEWPROJECTIONINVERSE',
    'WORLDTRANSPOSE',
    'VIEWTRANSPOSE',
    'PROJECTIONTRANSPOSE',
    'WORLDVIEWTRANSPOSE',
    'VIEWPROJECTIONTRANSPOSE',
    'WORLDVIEWPROJECTIONTRANSPOSE',
    'WORLDINVERSETRANSPOSE',
    'VIEWINVERSETRANSPOSE',
    'PROJECTIONINVERSETRANSPOSE',
    'WORLDVIEWINVERSETRANSPOSE',
    'VIEWPROJECTIONINVERSETRANSPOSE',
    'WORLDVIEWPROJECTIONINVERSETRANSPOSE'
];

var attributeSizeMap = {
    // WebGL does not support integer attributes
    'vec4': 4,
    'vec3': 3,
    'vec2': 2,
    'float': 1
};


var shaderIDCache = {};
var shaderCodeCache = {};

function getShaderID(vertex, fragment) {
    var key = 'vertex:' + vertex + 'fragment:' + fragment;
    if (shaderIDCache[key]) {
        return shaderIDCache[key];
    }
    var id = __WEBPACK_IMPORTED_MODULE_0__core_util__["a" /* default */].genGUID();
    shaderIDCache[key] = id;

    shaderCodeCache[id] = {
        vertex: vertex,
        fragment: fragment
    };

    return id;
}

function removeComment(code) {
    return code.replace(/[ \t]*\/\/.*\n/g, '' )   // remove //
        .replace(/[ \t]*\/\*[\s\S]*?\*\//g, '' ); // remove /* */
}

function logSyntaxError() {
    console.error('Wrong uniform/attributes syntax');
}

function parseDeclarations(type, line) {
    var speratorsRegexp = /[,=\(\):]/;
    var tokens = line
        // Convert `symbol: [1,2,3]` to `symbol: vec3(1,2,3)`
        .replace(/:\s*\[\s*(.*)\s*\]/g, '=' + type + '($1)')
        .replace(/\s+/g, '')
        .split(/(?=[,=\(\):])/g);

    var newTokens = [];
    for (var i = 0; i < tokens.length; i++) {
        if (tokens[i].match(speratorsRegexp)) {
            newTokens.push(
                tokens[i].charAt(0),
                tokens[i].slice(1)
            );
        }
        else {
            newTokens.push(tokens[i]);
        }
    }
    tokens = newTokens;

    var TYPE_SYMBOL = 0;
    var TYPE_ASSIGN = 1;
    var TYPE_VEC = 2;
    var TYPE_ARR = 3;
    var TYPE_SEMANTIC = 4;
    var TYPE_NORMAL = 5;

    var opType = TYPE_SYMBOL;
    var declarations = {};
    var declarationValue = null;
    var currentDeclaration;

    addSymbol(tokens[0]);

    function addSymbol(symbol) {
        if (!symbol) {
            logSyntaxError();
        }
        var arrResult = symbol.match(/\[(.*?)\]/);
        currentDeclaration = symbol.replace(/\[(.*?)\]/, '');
        declarations[currentDeclaration] = {};
        if (arrResult) {
            declarations[currentDeclaration].isArray = true;
            declarations[currentDeclaration].arraySize = arrResult[1];
        }
    }

    for (var i = 1; i < tokens.length; i++) {
        var token = tokens[i];
        if (!token) {   // Empty token;
            continue;
        }
        if (token === '=') {
            if (opType !== TYPE_SYMBOL
            && opType !== TYPE_ARR) {
                logSyntaxError();
                break;
            }
            opType = TYPE_ASSIGN;

            continue;
        }
        else if (token === ':') {
            opType = TYPE_SEMANTIC;

            continue;
        }
        else if (token === ',') {
            if (opType === TYPE_VEC) {
                if (!(declarationValue instanceof Array)) {
                    logSyntaxError();
                    break;
                }
                declarationValue.push(+tokens[++i]);
            }
            else {
                opType = TYPE_NORMAL;
            }

            continue;
        }
        else if (token === ')') {
            declarations[currentDeclaration].value = new __WEBPACK_IMPORTED_MODULE_1__core_vendor__["a" /* default */].Float32Array(declarationValue);
            declarationValue = null;
            opType = TYPE_NORMAL;
            continue;
        }
        else if (token === '(') {
            if (opType !== TYPE_VEC) {
                logSyntaxError();
                break;
            }
            if (!(declarationValue instanceof Array)) {
                logSyntaxError();
                break;
            }
            declarationValue.push(+tokens[++i]);
            continue;
        }
        else if (token.indexOf('vec') >= 0) {
            if (opType !== TYPE_ASSIGN
            // Compatitable with old syntax `symbol: [1,2,3]`
            && opType !== TYPE_SEMANTIC) {
                logSyntaxError();
                break;
            }
            opType = TYPE_VEC;
            declarationValue = [];
            continue;
        }
        else if (opType === TYPE_ASSIGN) {
            if (type === 'bool') {
                declarations[currentDeclaration].value = token === 'true';
            }
            else {
                declarations[currentDeclaration].value = parseFloat(token);
            }
            declarationValue = null;
            continue;
        }
        else if (opType === TYPE_SEMANTIC) {
            var semantic = token;
            if (attributeSemantics.indexOf(semantic) >= 0
                || uniformSemantics.indexOf(semantic) >= 0
                || matrixSemantics.indexOf(semantic) >= 0
            ) {
                declarations[currentDeclaration].semantic = semantic;
            }
            else if (semantic === 'ignore' || semantic === 'unconfigurable') {
                declarations[currentDeclaration].ignore = true;
            }
            else {
                // Try to parse as a default tvalue.
                if (type === 'bool') {
                    declarations[currentDeclaration].value = semantic === 'true';
                }
                else {
                    declarations[currentDeclaration].value = parseFloat(semantic);
                }
            }
            continue;
        }

        // treat as symbol.
        addSymbol(token);
        opType = TYPE_SYMBOL;
    }

    return declarations;
}


/**
 * @constructor
 * @extends clay.core.Base
 * @alias clay.Shader
 * @param {string} vertex
 * @param {string} fragment
 * @example
 * // Create a phong shader
 * var shader = new clay.Shader(
 *      clay.Shader.source('clay.standard.vertex'),
 *      clay.Shader.source('clay.standard.fragment')
 * );
 */
function Shader(vertex, fragment) {
    // First argument can be { vertex, fragment }
    if (typeof vertex === 'object') {
        fragment = vertex.fragment;
        vertex = vertex.vertex;
    }

    vertex = removeComment(vertex);
    fragment = removeComment(fragment);

    this._shaderID = getShaderID(vertex, fragment);

    this._vertexCode = Shader.parseImport(vertex);
    this._fragmentCode = Shader.parseImport(fragment);

    /**
     * @readOnly
     */
    this.attributeSemantics = {};
    /**
     * @readOnly
     */
    this.matrixSemantics = {};
    /**
     * @readOnly
     */
    this.uniformSemantics = {};
    /**
     * @readOnly
     */
    this.matrixSemanticKeys = [];
    /**
     * @readOnly
     */
    this.uniformTemplates = {};
    /**
     * @readOnly
     */
    this.attributes = {};
    /**
     * @readOnly
     */
    this.textures = {};
    /**
     * @readOnly
     */
    this.vertexDefines = {};
    /**
     * @readOnly
     */
    this.fragmentDefines = {};

    this._parseAttributes();
    this._parseUniforms();
    this._parseDefines();
}

Shader.prototype = {

    constructor: Shader,

    // Create a new uniform instance for material
    createUniforms: function () {
        var uniforms = {};

        for (var symbol in this.uniformTemplates){
            var uniformTpl = this.uniformTemplates[symbol];
            uniforms[symbol] = {
                type: uniformTpl.type,
                value: uniformTpl.value()
            };
        }

        return uniforms;
    },

    _parseImport: function () {
        this._vertexCode = Shader.parseImport(this.vertex);
        this._fragmentCode = Shader.parseImport(this.fragment);
    },

    _addSemanticUniform: function (symbol, uniformType, semantic) {
        // This case is only for SKIN_MATRIX
        // TODO
        if (attributeSemantics.indexOf(semantic) >= 0) {
            this.attributeSemantics[semantic] = {
                symbol: symbol,
                type: uniformType
            };
        }
        else if (matrixSemantics.indexOf(semantic) >= 0) {
            var isTranspose = false;
            var semanticNoTranspose = semantic;
            if (semantic.match(/TRANSPOSE$/)) {
                isTranspose = true;
                semanticNoTranspose = semantic.slice(0, -9);
            }
            this.matrixSemantics[semantic] = {
                symbol: symbol,
                type: uniformType,
                isTranspose: isTranspose,
                semanticNoTranspose: semanticNoTranspose
            };
        }
        else if (uniformSemantics.indexOf(semantic) >= 0) {
            this.uniformSemantics[semantic] = {
                symbol: symbol,
                type: uniformType
            };
        }
    },

    _addMaterialUniform: function (symbol, type, uniformType, defaultValueFunc, isArray, materialUniforms) {
        materialUniforms[symbol] = {
            type: uniformType,
            value: isArray ? uniformValueConstructor['array'] : (defaultValueFunc || uniformValueConstructor[type]),
            semantic: null
        };
    },

    _parseUniforms: function () {
        var uniforms = {};
        var self = this;
        var shaderType = 'vertex';
        this._uniformList = [];

        this._vertexCode = this._vertexCode.replace(uniformRegex, _uniformParser);
        shaderType = 'fragment';
        this._fragmentCode = this._fragmentCode.replace(uniformRegex, _uniformParser);

        self.matrixSemanticKeys = Object.keys(this.matrixSemantics);

        function makeDefaultValueFunc(value) {
            return value != null ? function () { return value; } : null;
        }

        function _uniformParser(str, type, content) {
            var declaredUniforms = parseDeclarations(type, content);
            var uniformMainStr = [];
            for (var symbol in declaredUniforms) {

                var uniformInfo = declaredUniforms[symbol];
                var semantic = uniformInfo.semantic;
                var tmpStr = symbol;
                var uniformType = uniformTypeMap[type];
                var defaultValueFunc = makeDefaultValueFunc(declaredUniforms[symbol].value);
                if (declaredUniforms[symbol].isArray) {
                    tmpStr += '[' + declaredUniforms[symbol].arraySize + ']';
                    uniformType += 'v';
                }

                uniformMainStr.push(tmpStr);

                self._uniformList.push(symbol);

                if (!uniformInfo.ignore) {
                    if (type === 'sampler2D' || type === 'samplerCube') {
                        // Texture is default disabled
                        self.textures[symbol] = {
                            shaderType: shaderType,
                            type: type
                        };
                    }

                    if (semantic) {
                        // TODO Should not declare multiple symbols if have semantic.
                        self._addSemanticUniform(symbol, uniformType, semantic);
                    }
                    else {
                        self._addMaterialUniform(
                            symbol, type, uniformType, defaultValueFunc,
                            declaredUniforms[symbol].isArray, uniforms
                        );
                    }
                }
            }
            return uniformMainStr.length > 0
                ? 'uniform ' + type + ' ' + uniformMainStr.join(',') + ';\n' : '';
        }

        this.uniformTemplates = uniforms;
    },

    _parseAttributes: function () {
        var attributes = {};
        var self = this;
        this._vertexCode = this._vertexCode.replace(attributeRegex, _attributeParser);

        function _attributeParser(str, type, content) {
            var declaredAttributes = parseDeclarations(type, content);

            var size = attributeSizeMap[type] || 1;
            var attributeMainStr = [];
            for (var symbol in declaredAttributes) {
                var semantic = declaredAttributes[symbol].semantic;
                attributes[symbol] = {
                    // TODO Can only be float
                    type: 'float',
                    size: size,
                    semantic: semantic || null
                };
                // TODO Should not declare multiple symbols if have semantic.
                if (semantic) {
                    if (attributeSemantics.indexOf(semantic) < 0) {
                        throw new Error('Unkown semantic "' + semantic + '"');
                    }
                    else {
                        self.attributeSemantics[semantic] = {
                            symbol: symbol,
                            type: type
                        };
                    }
                }
                attributeMainStr.push(symbol);
            }

            return 'attribute ' + type + ' ' + attributeMainStr.join(',') + ';\n';
        }

        this.attributes = attributes;
    },

    _parseDefines: function () {
        var self = this;
        var shaderType = 'vertex';
        this._vertexCode = this._vertexCode.replace(defineRegex, _defineParser);
        shaderType = 'fragment';
        this._fragmentCode = this._fragmentCode.replace(defineRegex, _defineParser);

        function _defineParser(str, symbol, value) {
            var defines = shaderType === 'vertex' ? self.vertexDefines : self.fragmentDefines;
            if (!defines[symbol]) { // Haven't been defined by user
                if (value === 'false') {
                    defines[symbol] = false;
                }
                else if (value === 'true') {
                    defines[symbol] = true;
                }
                else {
                    defines[symbol] = value
                        // If can parse to float
                        ? (isNaN(parseFloat(value)) ? value.trim() : parseFloat(value))
                        : null;
                }
            }
            return '';
        }
    },

    /**
     * Clone a new shader
     * @return {clay.Shader}
     */
    clone: function () {
        var code = shaderCodeCache[this._shaderID];
        var shader = new Shader(code.vertex, code.fragment);
        return shader;
    }
};

if (Object.defineProperty) {
    Object.defineProperty(Shader.prototype, 'shaderID', {
        get: function () {
            return this._shaderID;
        }
    });
    Object.defineProperty(Shader.prototype, 'vertex', {
        get: function () {
            return this._vertexCode;
        }
    });
    Object.defineProperty(Shader.prototype, 'fragment', {
        get: function () {
            return this._fragmentCode;
        }
    });
    Object.defineProperty(Shader.prototype, 'uniforms', {
        get: function () {
            return this._uniformList;
        }
    });
}

var importRegex = /(@import)\s*([0-9a-zA-Z_\-\.]*)/g;
Shader.parseImport = function (shaderStr) {
    shaderStr = shaderStr.replace(importRegex, function (str, importSymbol, importName) {
        var str = Shader.source(importName);
        if (str) {
            // Recursively parse
            return Shader.parseImport(str);
        }
        else {
            console.error('Shader chunk "' + importName + '" not existed in library');
            return '';
        }
    });
    return shaderStr;
};

var exportRegex = /(@export)\s*([0-9a-zA-Z_\-\.]*)\s*\n([\s\S]*?)@end/g;

/**
 * Import shader source
 * @param  {string} shaderStr
 * @memberOf clay.Shader
 */
Shader['import'] = function (shaderStr) {
    shaderStr.replace(exportRegex, function (str, exportSymbol, exportName, code) {
        var code = code.replace(/(^[\s\t\xa0\u3000]+)|([\u3000\xa0\s\t]+\x24)/g, '');
        if (code) {
            var parts = exportName.split('.');
            var obj = Shader.codes;
            var i = 0;
            var key;
            while (i < parts.length - 1) {
                key = parts[i++];
                if (!obj[key]) {
                    obj[key] = {};
                }
                obj = obj[key];
            }
            key = parts[i];
            obj[key] = code;
        }
        return code;
    });
};

/**
 * Library to store all the loaded shader codes
 * @type {Object}
 * @readOnly
 * @memberOf clay.Shader
 */
Shader.codes = {};

/**
 * Get shader source
 * @param  {string} name
 * @return {string}
 */
Shader.source = function (name) {
    var parts = name.split('.');
    var obj = Shader.codes;
    var i = 0;
    while (obj && i < parts.length) {
        var key = parts[i++];
        obj = obj[key];
    }
    if (typeof obj !== 'string') {
        // FIXME Use default instead
        console.error('Shader "' + name + '" not existed in library');
        return '';
    }
    return obj;
};

/* harmony default export */ __webpack_exports__["a"] = (Shader);


/***/ }),
/* 9 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__ = __webpack_require__(12);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__glmatrix_quat__ = __webpack_require__(55);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__glmatrix_mat3__ = __webpack_require__(34);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Vector3__ = __webpack_require__(3);






/**
 * @constructor
 * @alias clay.Matrix4
 */
var Matrix4 = function() {

    this._axisX = new __WEBPACK_IMPORTED_MODULE_4__Vector3__["a" /* default */]();
    this._axisY = new __WEBPACK_IMPORTED_MODULE_4__Vector3__["a" /* default */]();
    this._axisZ = new __WEBPACK_IMPORTED_MODULE_4__Vector3__["a" /* default */]();

    /**
     * Storage of Matrix4
     * @name array
     * @type {Float32Array}
     * @memberOf clay.Matrix4#
     */
    this.array = __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].create();

    /**
     * @name _dirty
     * @type {boolean}
     * @memberOf clay.Matrix4#
     */
    this._dirty = true;
};

Matrix4.prototype = {

    constructor: Matrix4,

    /**
     * Set components from array
     * @param  {Float32Array|number[]} arr
     */
    setArray: function (arr) {
        for (var i = 0; i < this.array.length; i++) {
            this.array[i] = arr[i];
        }
        this._dirty = true;
        return this;
    },
    /**
     * Calculate the adjugate of self, in-place
     * @return {clay.Matrix4}
     */
    adjoint: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].adjoint(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Clone a new Matrix4
     * @return {clay.Matrix4}
     */
    clone: function() {
        return (new Matrix4()).copy(this);
    },

    /**
     * Copy from b
     * @param  {clay.Matrix4} b
     * @return {clay.Matrix4}
     */
    copy: function(a) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].copy(this.array, a.array);
        this._dirty = true;
        return this;
    },

    /**
     * Calculate matrix determinant
     * @return {number}
     */
    determinant: function() {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].determinant(this.array);
    },

    /**
     * Set upper 3x3 part from quaternion
     * @param  {clay.Quaternion} q
     * @return {clay.Matrix4}
     */
    fromQuat: function(q) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].fromQuat(this.array, q.array);
        this._dirty = true;
        return this;
    },

    /**
     * Set from a quaternion rotation and a vector translation
     * @param  {clay.Quaternion} q
     * @param  {clay.Vector3} v
     * @return {clay.Matrix4}
     */
    fromRotationTranslation: function(q, v) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].fromRotationTranslation(this.array, q.array, v.array);
        this._dirty = true;
        return this;
    },

    /**
     * Set from Matrix2d, it is used when converting a 2d shape to 3d space.
     * In 3d space it is equivalent to ranslate on xy plane and rotate about z axis
     * @param  {clay.Matrix2d} m2d
     * @return {clay.Matrix4}
     */
    fromMat2d: function(m2d) {
        Matrix4.fromMat2d(this, m2d);
        return this;
    },

    /**
     * Set from frustum bounds
     * @param  {number} left
     * @param  {number} right
     * @param  {number} bottom
     * @param  {number} top
     * @param  {number} near
     * @param  {number} far
     * @return {clay.Matrix4}
     */
    frustum: function (left, right, bottom, top, near, far) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].frustum(this.array, left, right, bottom, top, near, far);
        this._dirty = true;
        return this;
    },

    /**
     * Set to a identity matrix
     * @return {clay.Matrix4}
     */
    identity: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].identity(this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Invert self
     * @return {clay.Matrix4}
     */
    invert: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].invert(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Set as a matrix with the given eye position, focal point, and up axis
     * @param  {clay.Vector3} eye
     * @param  {clay.Vector3} center
     * @param  {clay.Vector3} up
     * @return {clay.Matrix4}
     */
    lookAt: function(eye, center, up) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].lookAt(this.array, eye.array, center.array, up.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for mutiply
     * @param  {clay.Matrix4} b
     * @return {clay.Matrix4}
     */
    mul: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].mul(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for multiplyLeft
     * @param  {clay.Matrix4} a
     * @return {clay.Matrix4}
     */
    mulLeft: function(a) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].mul(this.array, a.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Multiply self and b
     * @param  {clay.Matrix4} b
     * @return {clay.Matrix4}
     */
    multiply: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].multiply(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Multiply a and self, a is on the left
     * @param  {clay.Matrix3} a
     * @return {clay.Matrix3}
     */
    multiplyLeft: function(a) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].multiply(this.array, a.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Set as a orthographic projection matrix
     * @param  {number} left
     * @param  {number} right
     * @param  {number} bottom
     * @param  {number} top
     * @param  {number} near
     * @param  {number} far
     * @return {clay.Matrix4}
     */
    ortho: function(left, right, bottom, top, near, far) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].ortho(this.array, left, right, bottom, top, near, far);
        this._dirty = true;
        return this;
    },
    /**
     * Set as a perspective projection matrix
     * @param  {number} fovy
     * @param  {number} aspect
     * @param  {number} near
     * @param  {number} far
     * @return {clay.Matrix4}
     */
    perspective: function(fovy, aspect, near, far) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].perspective(this.array, fovy, aspect, near, far);
        this._dirty = true;
        return this;
    },

    /**
     * Rotate self by rad about axis.
     * Equal to right-multiply a rotaion matrix
     * @param  {number}   rad
     * @param  {clay.Vector3} axis
     * @return {clay.Matrix4}
     */
    rotate: function(rad, axis) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].rotate(this.array, this.array, rad, axis.array);
        this._dirty = true;
        return this;
    },

    /**
     * Rotate self by a given radian about X axis.
     * Equal to right-multiply a rotaion matrix
     * @param {number} rad
     * @return {clay.Matrix4}
     */
    rotateX: function(rad) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].rotateX(this.array, this.array, rad);
        this._dirty = true;
        return this;
    },

    /**
     * Rotate self by a given radian about Y axis.
     * Equal to right-multiply a rotaion matrix
     * @param {number} rad
     * @return {clay.Matrix4}
     */
    rotateY: function(rad) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].rotateY(this.array, this.array, rad);
        this._dirty = true;
        return this;
    },

    /**
     * Rotate self by a given radian about Z axis.
     * Equal to right-multiply a rotaion matrix
     * @param {number} rad
     * @return {clay.Matrix4}
     */
    rotateZ: function(rad) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].rotateZ(this.array, this.array, rad);
        this._dirty = true;
        return this;
    },

    /**
     * Scale self by s
     * Equal to right-multiply a scale matrix
     * @param  {clay.Vector3}  s
     * @return {clay.Matrix4}
     */
    scale: function(v) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].scale(this.array, this.array, v.array);
        this._dirty = true;
        return this;
    },

    /**
     * Translate self by v.
     * Equal to right-multiply a translate matrix
     * @param  {clay.Vector3}  v
     * @return {clay.Matrix4}
     */
    translate: function(v) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].translate(this.array, this.array, v.array);
        this._dirty = true;
        return this;
    },

    /**
     * Transpose self, in-place.
     * @return {clay.Matrix2}
     */
    transpose: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].transpose(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Decompose a matrix to SRT
     * @param {clay.Vector3} [scale]
     * @param {clay.Quaternion} rotation
     * @param {clay.Vector} position
     * @see http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.matrix.decompose.aspx
     */
    decomposeMatrix: (function() {

        var x = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();
        var y = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();
        var z = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();

        var m3 = __WEBPACK_IMPORTED_MODULE_3__glmatrix_mat3__["a" /* default */].create();

        return function(scale, rotation, position) {

            var el = this.array;
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].set(x, el[0], el[1], el[2]);
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].set(y, el[4], el[5], el[6]);
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].set(z, el[8], el[9], el[10]);

            var sx = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].length(x);
            var sy = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].length(y);
            var sz = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].length(z);

            // if determine is negative, we need to invert one scale
            var det = this.determinant();
            if (det < 0) {
                sx = -sx;
            }

            if (scale) {
                scale.set(sx, sy, sz);
            }

            position.set(el[12], el[13], el[14]);

            __WEBPACK_IMPORTED_MODULE_3__glmatrix_mat3__["a" /* default */].fromMat4(m3, el);
            // Not like mat4, mat3 in glmatrix seems to be row-based
            // Seems fixed in gl-matrix 2.2.2
            // https://github.com/toji/gl-matrix/issues/114
            // mat3.transpose(m3, m3);

            m3[0] /= sx;
            m3[1] /= sx;
            m3[2] /= sx;

            m3[3] /= sy;
            m3[4] /= sy;
            m3[5] /= sy;

            m3[6] /= sz;
            m3[7] /= sz;
            m3[8] /= sz;

            __WEBPACK_IMPORTED_MODULE_2__glmatrix_quat__["a" /* default */].fromMat3(rotation.array, m3);
            __WEBPACK_IMPORTED_MODULE_2__glmatrix_quat__["a" /* default */].normalize(rotation.array, rotation.array);

            rotation._dirty = true;
            position._dirty = true;
        };
    })(),

    toString: function() {
        return '[' + Array.prototype.join.call(this.array, ',') + ']';
    },

    toArray: function () {
        return Array.prototype.slice.call(this.array);
    }
};

var defineProperty = Object.defineProperty;

if (defineProperty) {
    var proto = Matrix4.prototype;
    /**
     * Z Axis of local transform
     * @name z
     * @type {clay.Vector3}
     * @memberOf clay.Matrix4
     * @instance
     */
    defineProperty(proto, 'z', {
        get: function () {
            var el = this.array;
            this._axisZ.set(el[8], el[9], el[10]);
            return this._axisZ;
        },
        set: function (v) {
            // TODO Here has a problem
            // If only set an item of vector will not work
            var el = this.array;
            v = v.array;
            el[8] = v[0];
            el[9] = v[1];
            el[10] = v[2];

            this._dirty = true;
        }
    });

    /**
     * Y Axis of local transform
     * @name y
     * @type {clay.Vector3}
     * @memberOf clay.Matrix4
     * @instance
     */
    defineProperty(proto, 'y', {
        get: function () {
            var el = this.array;
            this._axisY.set(el[4], el[5], el[6]);
            return this._axisY;
        },
        set: function (v) {
            var el = this.array;
            v = v.array;
            el[4] = v[0];
            el[5] = v[1];
            el[6] = v[2];

            this._dirty = true;
        }
    });

    /**
     * X Axis of local transform
     * @name x
     * @type {clay.Vector3}
     * @memberOf clay.Matrix4
     * @instance
     */
    defineProperty(proto, 'x', {
        get: function () {
            var el = this.array;
            this._axisX.set(el[0], el[1], el[2]);
            return this._axisX;
        },
        set: function (v) {
            var el = this.array;
            v = v.array;
            el[0] = v[0];
            el[1] = v[1];
            el[2] = v[2];

            this._dirty = true;
        }
    })
}

/**
 * @param  {clay.Matrix4} out
 * @param  {clay.Matrix4} a
 * @return {clay.Matrix4}
 */
Matrix4.adjoint = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].adjoint(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {clay.Matrix4} a
 * @return {clay.Matrix4}
 */
Matrix4.copy = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].copy(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} a
 * @return {number}
 */
Matrix4.determinant = function(a) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].determinant(a.array);
};

/**
 * @param  {clay.Matrix4} out
 * @return {clay.Matrix4}
 */
Matrix4.identity = function(out) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].identity(out.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {number}  left
 * @param  {number}  right
 * @param  {number}  bottom
 * @param  {number}  top
 * @param  {number}  near
 * @param  {number}  far
 * @return {clay.Matrix4}
 */
Matrix4.ortho = function(out, left, right, bottom, top, near, far) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].ortho(out.array, left, right, bottom, top, near, far);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {number}  fovy
 * @param  {number}  aspect
 * @param  {number}  near
 * @param  {number}  far
 * @return {clay.Matrix4}
 */
Matrix4.perspective = function(out, fovy, aspect, near, far) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].perspective(out.array, fovy, aspect, near, far);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {clay.Vector3} eye
 * @param  {clay.Vector3} center
 * @param  {clay.Vector3} up
 * @return {clay.Matrix4}
 */
Matrix4.lookAt = function(out, eye, center, up) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].lookAt(out.array, eye.array, center.array, up.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {clay.Matrix4} a
 * @return {clay.Matrix4}
 */
Matrix4.invert = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].invert(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {clay.Matrix4} a
 * @param  {clay.Matrix4} b
 * @return {clay.Matrix4}
 */
Matrix4.mul = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].mul(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @function
 * @param  {clay.Matrix4} out
 * @param  {clay.Matrix4} a
 * @param  {clay.Matrix4} b
 * @return {clay.Matrix4}
 */
Matrix4.multiply = Matrix4.mul;

/**
 * @param  {clay.Matrix4}    out
 * @param  {clay.Quaternion} q
 * @return {clay.Matrix4}
 */
Matrix4.fromQuat = function(out, q) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].fromQuat(out.array, q.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4}    out
 * @param  {clay.Quaternion} q
 * @param  {clay.Vector3}    v
 * @return {clay.Matrix4}
 */
Matrix4.fromRotationTranslation = function(out, q, v) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].fromRotationTranslation(out.array, q.array, v.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} m4
 * @param  {clay.Matrix2d} m2d
 * @return {clay.Matrix4}
 */
Matrix4.fromMat2d = function(m4, m2d) {
    m4._dirty = true;
    var m2d = m2d.array;
    var m4 = m4.array;

    m4[0] = m2d[0];
    m4[4] = m2d[2];
    m4[12] = m2d[4];

    m4[1] = m2d[1];
    m4[5] = m2d[3];
    m4[13] = m2d[5];

    return m4;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {clay.Matrix4} a
 * @param  {number}  rad
 * @param  {clay.Vector3} axis
 * @return {clay.Matrix4}
 */
Matrix4.rotate = function(out, a, rad, axis) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].rotate(out.array, a.array, rad, axis.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {clay.Matrix4} a
 * @param  {number}  rad
 * @return {clay.Matrix4}
 */
Matrix4.rotateX = function(out, a, rad) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].rotateX(out.array, a.array, rad);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {clay.Matrix4} a
 * @param  {number}  rad
 * @return {clay.Matrix4}
 */
Matrix4.rotateY = function(out, a, rad) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].rotateY(out.array, a.array, rad);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {clay.Matrix4} a
 * @param  {number}  rad
 * @return {clay.Matrix4}
 */
Matrix4.rotateZ = function(out, a, rad) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].rotateZ(out.array, a.array, rad);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {clay.Matrix4} a
 * @param  {clay.Vector3} v
 * @return {clay.Matrix4}
 */
Matrix4.scale = function(out, a, v) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].scale(out.array, a.array, v.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {clay.Matrix4} a
 * @return {clay.Matrix4}
 */
Matrix4.transpose = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].transpose(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix4} out
 * @param  {clay.Matrix4} a
 * @param  {clay.Vector3} v
 * @return {clay.Matrix4}
 */
Matrix4.translate = function(out, a, v) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat4__["a" /* default */].translate(out.array, a.array, v.array);
    out._dirty = true;
    return out;
};

/* harmony default export */ __webpack_exports__["a"] = (Matrix4);


/***/ }),
/* 10 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__TextureCube__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__core_Cache__ = __webpack_require__(57);






var KEY_FRAMEBUFFER = 'framebuffer';
var KEY_RENDERBUFFER = 'renderbuffer';
var KEY_RENDERBUFFER_WIDTH = KEY_RENDERBUFFER + '_width';
var KEY_RENDERBUFFER_HEIGHT = KEY_RENDERBUFFER + '_height';
var KEY_RENDERBUFFER_ATTACHED = KEY_RENDERBUFFER + '_attached';
var KEY_DEPTHTEXTURE_ATTACHED = 'depthtexture_attached';

var GL_FRAMEBUFFER = __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].FRAMEBUFFER;
var GL_RENDERBUFFER = __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].RENDERBUFFER;
var GL_DEPTH_ATTACHMENT = __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].DEPTH_ATTACHMENT;
var GL_COLOR_ATTACHMENT0 = __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].COLOR_ATTACHMENT0;
/**
 * @constructor clay.FrameBuffer
 * @extends clay.core.Base
 */
var FrameBuffer = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(
/** @lends clay.FrameBuffer# */
{
    /**
     * If use depth buffer
     * @type {boolean}
     */
    depthBuffer: true,

    /**
     * @type {Object}
     */
    viewport: null,

    _width: 0,
    _height: 0,

    _textures: null,

    _boundRenderer: null,
}, function () {
    // Use cache
    this._cache = new __WEBPACK_IMPORTED_MODULE_4__core_Cache__["a" /* default */]();

    this._textures = {};
},

/**@lends clay.FrameBuffer.prototype. */
{
    /**
     * Get attached texture width
     * {number}
     */
    // FIXME Can't use before #bind
    getTextureWidth: function () {
        return this._width;
    },

    /**
     * Get attached texture height
     * {number}
     */
    getTextureHeight: function () {
        return this._height;
    },

    /**
     * Bind the framebuffer to given renderer before rendering
     * @param  {clay.Renderer} renderer
     */
    bind: function (renderer) {

        if (renderer.__currentFrameBuffer) {
            // Already bound
            if (renderer.__currentFrameBuffer === this) {
                return;
            }

            console.warn('Renderer already bound with another framebuffer. Unbind it first');
        }
        renderer.__currentFrameBuffer = this;

        var _gl = renderer.gl;

        _gl.bindFramebuffer(GL_FRAMEBUFFER, this._getFrameBufferGL(renderer));
        this._boundRenderer = renderer;
        var cache = this._cache;

        cache.put('viewport', renderer.viewport);

        var hasTextureAttached = false;
        var width;
        var height;
        for (var attachment in this._textures) {
            hasTextureAttached = true;
            var obj = this._textures[attachment];
            if (obj) {
                // TODO Do width, height checking, make sure size are same
                width = obj.texture.width;
                height = obj.texture.height;
                // Attach textures
                this._doAttach(renderer, obj.texture, attachment, obj.target);
            }
        }

        this._width = width;
        this._height = height;

        if (!hasTextureAttached && this.depthBuffer) {
            console.error('Must attach texture before bind, or renderbuffer may have incorrect width and height.')
        }

        if (this.viewport) {
            renderer.setViewport(this.viewport);
        }
        else {
            renderer.setViewport(0, 0, width, height, 1);
        }

        var attachedTextures = cache.get('attached_textures');
        if (attachedTextures) {
            for (var attachment in attachedTextures) {
                if (!this._textures[attachment]) {
                    var target = attachedTextures[attachment];
                    this._doDetach(_gl, attachment, target);
                }
            }
        }
        if (!cache.get(KEY_DEPTHTEXTURE_ATTACHED) && this.depthBuffer) {
            // Create a new render buffer
            if (cache.miss(KEY_RENDERBUFFER)) {
                cache.put(KEY_RENDERBUFFER, _gl.createRenderbuffer());
            }
            var renderbuffer = cache.get(KEY_RENDERBUFFER);

            if (width !== cache.get(KEY_RENDERBUFFER_WIDTH)
                    || height !== cache.get(KEY_RENDERBUFFER_HEIGHT)) {
                _gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
                _gl.renderbufferStorage(GL_RENDERBUFFER, _gl.DEPTH_COMPONENT16, width, height);
                cache.put(KEY_RENDERBUFFER_WIDTH, width);
                cache.put(KEY_RENDERBUFFER_HEIGHT, height);
                _gl.bindRenderbuffer(GL_RENDERBUFFER, null);
            }
            if (!cache.get(KEY_RENDERBUFFER_ATTACHED)) {
                _gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
                cache.put(KEY_RENDERBUFFER_ATTACHED, true);
            }
        }
    },

    /**
     * Unbind the frame buffer after rendering
     * @param  {clay.Renderer} renderer
     */
    unbind: function (renderer) {
        // Remove status record on renderer
        renderer.__currentFrameBuffer = null;

        var _gl = renderer.gl;

        _gl.bindFramebuffer(GL_FRAMEBUFFER, null);
        this._boundRenderer = null;

        this._cache.use(renderer.__uid__);
        var viewport = this._cache.get('viewport');
        // Reset viewport;
        if (viewport) {
            renderer.setViewport(viewport);
        }

        this.updateMipmap(renderer);
    },

    // Because the data of texture is changed over time,
    // Here update the mipmaps of texture each time after rendered;
    updateMipmap: function (renderer) {
        var _gl = renderer.gl;
        for (var attachment in this._textures) {
            var obj = this._textures[attachment];
            if (obj) {
                var texture = obj.texture;
                // FIXME some texture format can't generate mipmap
                if (!texture.NPOT && texture.useMipmap
                    && texture.minFilter === __WEBPACK_IMPORTED_MODULE_1__Texture__["a" /* default */].LINEAR_MIPMAP_LINEAR) {
                    var target = texture.textureType === 'textureCube' ? __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].TEXTURE_CUBE_MAP : __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].TEXTURE_2D;
                    _gl.bindTexture(target, texture.getWebGLTexture(renderer));
                    _gl.generateMipmap(target);
                    _gl.bindTexture(target, null);
                }
            }
        }
    },


    // 0x8CD5, 36053, FRAMEBUFFER_COMPLETE
    // 0x8CD6, 36054, FRAMEBUFFER_INCOMPLETE_ATTACHMENT
    // 0x8CD7, 36055, FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
    // 0x8CD9, 36057, FRAMEBUFFER_INCOMPLETE_DIMENSIONS
    // 0x8CDD, 36061, FRAMEBUFFER_UNSUPPORTED
    checkStatus: function (_gl) {
        return _gl.checkFramebufferStatus(GL_FRAMEBUFFER);
    },

    _getFrameBufferGL: function (renderer) {
        var cache = this._cache;
        cache.use(renderer.__uid__);

        if (cache.miss(KEY_FRAMEBUFFER)) {
            cache.put(KEY_FRAMEBUFFER, renderer.gl.createFramebuffer());
        }

        return cache.get(KEY_FRAMEBUFFER);
    },

    /**
     * Attach a texture(RTT) to the framebuffer
     * @param  {clay.Texture} texture
     * @param  {number} [attachment=gl.COLOR_ATTACHMENT0]
     * @param  {number} [target=gl.TEXTURE_2D]
     */
    attach: function (texture, attachment, target) {

        if (!texture.width) {
            throw new Error('The texture attached to color buffer is not a valid.');
        }
        // TODO width and height check

        // If the depth_texture extension is enabled, developers
        // Can attach a depth texture to the depth buffer
        // http://blog.tojicode.com/2012/07/using-webgldepthtexture.html
        attachment = attachment || GL_COLOR_ATTACHMENT0;
        target = target || __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].TEXTURE_2D;

        var boundRenderer = this._boundRenderer;
        var _gl = boundRenderer && boundRenderer.gl;
        var attachedTextures;

        if (_gl) {
            var cache = this._cache;
            cache.use(boundRenderer.__uid__);
            attachedTextures = cache.get('attached_textures');
        }

        // Check if texture attached
        var previous = this._textures[attachment];
        if (previous && previous.target === target
            && previous.texture === texture
            && (attachedTextures && attachedTextures[attachment] != null)
        ) {
            return;
        }

        var canAttach = true;
        if (boundRenderer) {
            canAttach = this._doAttach(boundRenderer, texture, attachment, target);
            // Set viewport again incase attached to different size textures.
            if (!this.viewport) {
                boundRenderer.setViewport(0, 0, texture.width, texture.height, 1);
            }
        }

        if (canAttach) {
            this._textures[attachment] = this._textures[attachment] || {};
            this._textures[attachment].texture = texture;
            this._textures[attachment].target = target;
        }
    },

    _doAttach: function (renderer, texture, attachment, target) {
        var _gl = renderer.gl;
        // Make sure texture is always updated
        // Because texture width or height may be changed and in this we can't be notified
        // FIXME awkward;
        var webglTexture = texture.getWebGLTexture(renderer);
        // Assume cache has been used.
        var attachedTextures = this._cache.get('attached_textures');
        if (attachedTextures && attachedTextures[attachment]) {
            var obj = attachedTextures[attachment];
            // Check if texture and target not changed
            if (obj.texture === texture && obj.target === target) {
                return;
            }
        }
        attachment = +attachment;

        var canAttach = true;
        if (attachment === GL_DEPTH_ATTACHMENT || attachment === __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].DEPTH_STENCIL_ATTACHMENT) {
            var extension = renderer.getGLExtension('WEBGL_depth_texture');

            if (!extension) {
                console.error('Depth texture is not supported by the browser');
                canAttach = false;
            }
            if (texture.format !== __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].DEPTH_COMPONENT
                && texture.format !== __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].DEPTH_STENCIL
            ) {
                console.error('The texture attached to depth buffer is not a valid.');
                canAttach = false;
            }

            // Dispose render buffer created previous
            if (canAttach) {
                var renderbuffer = this._cache.get(KEY_RENDERBUFFER);
                if (renderbuffer) {
                    _gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, null);
                    _gl.deleteRenderbuffer(renderbuffer);
                    this._cache.put(KEY_RENDERBUFFER, false);
                }

                this._cache.put(KEY_RENDERBUFFER_ATTACHED, false);
                this._cache.put(KEY_DEPTHTEXTURE_ATTACHED, true);
            }
        }

        // Mipmap level can only be 0
        _gl.framebufferTexture2D(GL_FRAMEBUFFER, attachment, target, webglTexture, 0);

        if (!attachedTextures) {
            attachedTextures = {};
            this._cache.put('attached_textures', attachedTextures);
        }
        attachedTextures[attachment] = attachedTextures[attachment] || {};
        attachedTextures[attachment].texture = texture;
        attachedTextures[attachment].target = target;

        return canAttach;
    },

    _doDetach: function (_gl, attachment, target) {
        // Detach a texture from framebuffer
        // https://github.com/KhronosGroup/WebGL/blob/master/conformance-suites/1.0.0/conformance/framebuffer-test.html#L145
        _gl.framebufferTexture2D(GL_FRAMEBUFFER, attachment, target, null, 0);

        // Assume cache has been used.
        var attachedTextures = this._cache.get('attached_textures');
        if (attachedTextures && attachedTextures[attachment]) {
            attachedTextures[attachment] = null;
        }

        if (attachment === GL_DEPTH_ATTACHMENT || attachment === __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].DEPTH_STENCIL_ATTACHMENT) {
            this._cache.put(KEY_DEPTHTEXTURE_ATTACHED, false);
        }
    },

    /**
     * Detach a texture
     * @param  {number} [attachment=gl.COLOR_ATTACHMENT0]
     * @param  {number} [target=gl.TEXTURE_2D]
     */
    detach: function (attachment, target) {
        // TODO depth extension check ?
        this._textures[attachment] = null;
        if (this._boundRenderer) {
            var cache = this._cache;
            cache.use(this._boundRenderer.__uid__);
            this._doDetach(this._boundRenderer.gl, attachment, target);
        }
    },
    /**
     * Dispose
     * @param  {WebGLRenderingContext} _gl
     */
    dispose: function (renderer) {

        var _gl = renderer.gl;
        var cache = this._cache;

        cache.use(renderer.__uid__);

        var renderBuffer = cache.get(KEY_RENDERBUFFER);
        if (renderBuffer) {
            _gl.deleteRenderbuffer(renderBuffer);
        }
        var frameBuffer = cache.get(KEY_FRAMEBUFFER);
        if (frameBuffer) {
            _gl.deleteFramebuffer(frameBuffer);
        }
        cache.deleteContext(renderer.__uid__);

        // Clear cache for reusing
        this._textures = {};

    }
});

FrameBuffer.DEPTH_ATTACHMENT = GL_DEPTH_ATTACHMENT;
FrameBuffer.COLOR_ATTACHMENT0 = GL_COLOR_ATTACHMENT0;
FrameBuffer.STENCIL_ATTACHMENT = __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].STENCIL_ATTACHMENT;
FrameBuffer.DEPTH_STENCIL_ATTACHMENT = __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].DEPTH_STENCIL_ATTACHMENT;

/* harmony default export */ __webpack_exports__["a"] = (FrameBuffer);


/***/ }),
/* 11 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/**
 * @namespace clay.core.glenum
 * @see http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14
 */
/* harmony default export */ __webpack_exports__["a"] = ({
    /* ClearBufferMask */
    DEPTH_BUFFER_BIT               : 0x00000100,
    STENCIL_BUFFER_BIT             : 0x00000400,
    COLOR_BUFFER_BIT               : 0x00004000,

    /* BeginMode */
    POINTS                         : 0x0000,
    LINES                          : 0x0001,
    LINE_LOOP                      : 0x0002,
    LINE_STRIP                     : 0x0003,
    TRIANGLES                      : 0x0004,
    TRIANGLE_STRIP                 : 0x0005,
    TRIANGLE_FAN                   : 0x0006,

    /* AlphaFunction (not supported in ES20) */
    /*      NEVER */
    /*      LESS */
    /*      EQUAL */
    /*      LEQUAL */
    /*      GREATER */
    /*      NOTEQUAL */
    /*      GEQUAL */
    /*      ALWAYS */

    /* BlendingFactorDest */
    ZERO                           : 0,
    ONE                            : 1,
    SRC_COLOR                      : 0x0300,
    ONE_MINUS_SRC_COLOR            : 0x0301,
    SRC_ALPHA                      : 0x0302,
    ONE_MINUS_SRC_ALPHA            : 0x0303,
    DST_ALPHA                      : 0x0304,
    ONE_MINUS_DST_ALPHA            : 0x0305,

    /* BlendingFactorSrc */
    /*      ZERO */
    /*      ONE */
    DST_COLOR                      : 0x0306,
    ONE_MINUS_DST_COLOR            : 0x0307,
    SRC_ALPHA_SATURATE             : 0x0308,
    /*      SRC_ALPHA */
    /*      ONE_MINUS_SRC_ALPHA */
    /*      DST_ALPHA */
    /*      ONE_MINUS_DST_ALPHA */

    /* BlendEquationSeparate */
    FUNC_ADD                       : 0x8006,
    BLEND_EQUATION                 : 0x8009,
    BLEND_EQUATION_RGB             : 0x8009, /* same as BLEND_EQUATION */
    BLEND_EQUATION_ALPHA           : 0x883D,

    /* BlendSubtract */
    FUNC_SUBTRACT                  : 0x800A,
    FUNC_REVERSE_SUBTRACT          : 0x800B,

    /* Separate Blend Functions */
    BLEND_DST_RGB                  : 0x80C8,
    BLEND_SRC_RGB                  : 0x80C9,
    BLEND_DST_ALPHA                : 0x80CA,
    BLEND_SRC_ALPHA                : 0x80CB,
    CONSTANT_COLOR                 : 0x8001,
    ONE_MINUS_CONSTANT_COLOR       : 0x8002,
    CONSTANT_ALPHA                 : 0x8003,
    ONE_MINUS_CONSTANT_ALPHA       : 0x8004,
    BLEND_COLOR                    : 0x8005,

    /* Buffer Objects */
    ARRAY_BUFFER                   : 0x8892,
    ELEMENT_ARRAY_BUFFER           : 0x8893,
    ARRAY_BUFFER_BINDING           : 0x8894,
    ELEMENT_ARRAY_BUFFER_BINDING   : 0x8895,

    STREAM_DRAW                    : 0x88E0,
    STATIC_DRAW                    : 0x88E4,
    DYNAMIC_DRAW                   : 0x88E8,

    BUFFER_SIZE                    : 0x8764,
    BUFFER_USAGE                   : 0x8765,

    CURRENT_VERTEX_ATTRIB          : 0x8626,

    /* CullFaceMode */
    FRONT                          : 0x0404,
    BACK                           : 0x0405,
    FRONT_AND_BACK                 : 0x0408,

    /* DepthFunction */
    /*      NEVER */
    /*      LESS */
    /*      EQUAL */
    /*      LEQUAL */
    /*      GREATER */
    /*      NOTEQUAL */
    /*      GEQUAL */
    /*      ALWAYS */

    /* EnableCap */
    /* TEXTURE_2D */
    CULL_FACE                      : 0x0B44,
    BLEND                          : 0x0BE2,
    DITHER                         : 0x0BD0,
    STENCIL_TEST                   : 0x0B90,
    DEPTH_TEST                     : 0x0B71,
    SCISSOR_TEST                   : 0x0C11,
    POLYGON_OFFSET_FILL            : 0x8037,
    SAMPLE_ALPHA_TO_COVERAGE       : 0x809E,
    SAMPLE_COVERAGE                : 0x80A0,

    /* ErrorCode */
    NO_ERROR                       : 0,
    INVALID_ENUM                   : 0x0500,
    INVALID_VALUE                  : 0x0501,
    INVALID_OPERATION              : 0x0502,
    OUT_OF_MEMORY                  : 0x0505,

    /* FrontFaceDirection */
    CW                             : 0x0900,
    CCW                            : 0x0901,

    /* GetPName */
    LINE_WIDTH                     : 0x0B21,
    ALIASED_POINT_SIZE_RANGE       : 0x846D,
    ALIASED_LINE_WIDTH_RANGE       : 0x846E,
    CULL_FACE_MODE                 : 0x0B45,
    FRONT_FACE                     : 0x0B46,
    DEPTH_RANGE                    : 0x0B70,
    DEPTH_WRITEMASK                : 0x0B72,
    DEPTH_CLEAR_VALUE              : 0x0B73,
    DEPTH_FUNC                     : 0x0B74,
    STENCIL_CLEAR_VALUE            : 0x0B91,
    STENCIL_FUNC                   : 0x0B92,
    STENCIL_FAIL                   : 0x0B94,
    STENCIL_PASS_DEPTH_FAIL        : 0x0B95,
    STENCIL_PASS_DEPTH_PASS        : 0x0B96,
    STENCIL_REF                    : 0x0B97,
    STENCIL_VALUE_MASK             : 0x0B93,
    STENCIL_WRITEMASK              : 0x0B98,
    STENCIL_BACK_FUNC              : 0x8800,
    STENCIL_BACK_FAIL              : 0x8801,
    STENCIL_BACK_PASS_DEPTH_FAIL   : 0x8802,
    STENCIL_BACK_PASS_DEPTH_PASS   : 0x8803,
    STENCIL_BACK_REF               : 0x8CA3,
    STENCIL_BACK_VALUE_MASK        : 0x8CA4,
    STENCIL_BACK_WRITEMASK         : 0x8CA5,
    VIEWPORT                       : 0x0BA2,
    SCISSOR_BOX                    : 0x0C10,
    /*      SCISSOR_TEST */
    COLOR_CLEAR_VALUE              : 0x0C22,
    COLOR_WRITEMASK                : 0x0C23,
    UNPACK_ALIGNMENT               : 0x0CF5,
    PACK_ALIGNMENT                 : 0x0D05,
    MAX_TEXTURE_SIZE               : 0x0D33,
    MAX_VIEWPORT_DIMS              : 0x0D3A,
    SUBPIXEL_BITS                  : 0x0D50,
    RED_BITS                       : 0x0D52,
    GREEN_BITS                     : 0x0D53,
    BLUE_BITS                      : 0x0D54,
    ALPHA_BITS                     : 0x0D55,
    DEPTH_BITS                     : 0x0D56,
    STENCIL_BITS                   : 0x0D57,
    POLYGON_OFFSET_UNITS           : 0x2A00,
    /*      POLYGON_OFFSET_FILL */
    POLYGON_OFFSET_FACTOR          : 0x8038,
    TEXTURE_BINDING_2D             : 0x8069,
    SAMPLE_BUFFERS                 : 0x80A8,
    SAMPLES                        : 0x80A9,
    SAMPLE_COVERAGE_VALUE          : 0x80AA,
    SAMPLE_COVERAGE_INVERT         : 0x80AB,

    /* GetTextureParameter */
    /*      TEXTURE_MAG_FILTER */
    /*      TEXTURE_MIN_FILTER */
    /*      TEXTURE_WRAP_S */
    /*      TEXTURE_WRAP_T */

    COMPRESSED_TEXTURE_FORMATS     : 0x86A3,

    /* HintMode */
    DONT_CARE                      : 0x1100,
    FASTEST                        : 0x1101,
    NICEST                         : 0x1102,

    /* HintTarget */
    GENERATE_MIPMAP_HINT            : 0x8192,

    /* DataType */
    BYTE                           : 0x1400,
    UNSIGNED_BYTE                  : 0x1401,
    SHORT                          : 0x1402,
    UNSIGNED_SHORT                 : 0x1403,
    INT                            : 0x1404,
    UNSIGNED_INT                   : 0x1405,
    FLOAT                          : 0x1406,

    /* PixelFormat */
    DEPTH_COMPONENT                : 0x1902,
    ALPHA                          : 0x1906,
    RGB                            : 0x1907,
    RGBA                           : 0x1908,
    LUMINANCE                      : 0x1909,
    LUMINANCE_ALPHA                : 0x190A,

    /* PixelType */
    /*      UNSIGNED_BYTE */
    UNSIGNED_SHORT_4_4_4_4         : 0x8033,
    UNSIGNED_SHORT_5_5_5_1         : 0x8034,
    UNSIGNED_SHORT_5_6_5           : 0x8363,

    /* Shaders */
    FRAGMENT_SHADER                  : 0x8B30,
    VERTEX_SHADER                    : 0x8B31,
    MAX_VERTEX_ATTRIBS               : 0x8869,
    MAX_VERTEX_UNIFORM_VECTORS       : 0x8DFB,
    MAX_VARYING_VECTORS              : 0x8DFC,
    MAX_COMBINED_TEXTURE_IMAGE_UNITS : 0x8B4D,
    MAX_VERTEX_TEXTURE_IMAGE_UNITS   : 0x8B4C,
    MAX_TEXTURE_IMAGE_UNITS          : 0x8872,
    MAX_FRAGMENT_UNIFORM_VECTORS     : 0x8DFD,
    SHADER_TYPE                      : 0x8B4F,
    DELETE_STATUS                    : 0x8B80,
    LINK_STATUS                      : 0x8B82,
    VALIDATE_STATUS                  : 0x8B83,
    ATTACHED_SHADERS                 : 0x8B85,
    ACTIVE_UNIFORMS                  : 0x8B86,
    ACTIVE_ATTRIBUTES                : 0x8B89,
    SHADING_LANGUAGE_VERSION         : 0x8B8C,
    CURRENT_PROGRAM                  : 0x8B8D,

    /* StencilFunction */
    NEVER                          : 0x0200,
    LESS                           : 0x0201,
    EQUAL                          : 0x0202,
    LEQUAL                         : 0x0203,
    GREATER                        : 0x0204,
    NOTEQUAL                       : 0x0205,
    GEQUAL                         : 0x0206,
    ALWAYS                         : 0x0207,

    /* StencilOp */
    /*      ZERO */
    KEEP                           : 0x1E00,
    REPLACE                        : 0x1E01,
    INCR                           : 0x1E02,
    DECR                           : 0x1E03,
    INVERT                         : 0x150A,
    INCR_WRAP                      : 0x8507,
    DECR_WRAP                      : 0x8508,

    /* StringName */
    VENDOR                         : 0x1F00,
    RENDERER                       : 0x1F01,
    VERSION                        : 0x1F02,

    /* TextureMagFilter */
    NEAREST                        : 0x2600,
    LINEAR                         : 0x2601,

    /* TextureMinFilter */
    /*      NEAREST */
    /*      LINEAR */
    NEAREST_MIPMAP_NEAREST         : 0x2700,
    LINEAR_MIPMAP_NEAREST          : 0x2701,
    NEAREST_MIPMAP_LINEAR          : 0x2702,
    LINEAR_MIPMAP_LINEAR           : 0x2703,

    /* TextureParameterName */
    TEXTURE_MAG_FILTER             : 0x2800,
    TEXTURE_MIN_FILTER             : 0x2801,
    TEXTURE_WRAP_S                 : 0x2802,
    TEXTURE_WRAP_T                 : 0x2803,

    /* TextureTarget */
    TEXTURE_2D                     : 0x0DE1,
    TEXTURE                        : 0x1702,

    TEXTURE_CUBE_MAP               : 0x8513,
    TEXTURE_BINDING_CUBE_MAP       : 0x8514,
    TEXTURE_CUBE_MAP_POSITIVE_X    : 0x8515,
    TEXTURE_CUBE_MAP_NEGATIVE_X    : 0x8516,
    TEXTURE_CUBE_MAP_POSITIVE_Y    : 0x8517,
    TEXTURE_CUBE_MAP_NEGATIVE_Y    : 0x8518,
    TEXTURE_CUBE_MAP_POSITIVE_Z    : 0x8519,
    TEXTURE_CUBE_MAP_NEGATIVE_Z    : 0x851A,
    MAX_CUBE_MAP_TEXTURE_SIZE      : 0x851C,

    /* TextureUnit */
    TEXTURE0                       : 0x84C0,
    TEXTURE1                       : 0x84C1,
    TEXTURE2                       : 0x84C2,
    TEXTURE3                       : 0x84C3,
    TEXTURE4                       : 0x84C4,
    TEXTURE5                       : 0x84C5,
    TEXTURE6                       : 0x84C6,
    TEXTURE7                       : 0x84C7,
    TEXTURE8                       : 0x84C8,
    TEXTURE9                       : 0x84C9,
    TEXTURE10                      : 0x84CA,
    TEXTURE11                      : 0x84CB,
    TEXTURE12                      : 0x84CC,
    TEXTURE13                      : 0x84CD,
    TEXTURE14                      : 0x84CE,
    TEXTURE15                      : 0x84CF,
    TEXTURE16                      : 0x84D0,
    TEXTURE17                      : 0x84D1,
    TEXTURE18                      : 0x84D2,
    TEXTURE19                      : 0x84D3,
    TEXTURE20                      : 0x84D4,
    TEXTURE21                      : 0x84D5,
    TEXTURE22                      : 0x84D6,
    TEXTURE23                      : 0x84D7,
    TEXTURE24                      : 0x84D8,
    TEXTURE25                      : 0x84D9,
    TEXTURE26                      : 0x84DA,
    TEXTURE27                      : 0x84DB,
    TEXTURE28                      : 0x84DC,
    TEXTURE29                      : 0x84DD,
    TEXTURE30                      : 0x84DE,
    TEXTURE31                      : 0x84DF,
    ACTIVE_TEXTURE                 : 0x84E0,

    /* TextureWrapMode */
    REPEAT                         : 0x2901,
    CLAMP_TO_EDGE                  : 0x812F,
    MIRRORED_REPEAT                : 0x8370,

    /* Uniform Types */
    FLOAT_VEC2                     : 0x8B50,
    FLOAT_VEC3                     : 0x8B51,
    FLOAT_VEC4                     : 0x8B52,
    INT_VEC2                       : 0x8B53,
    INT_VEC3                       : 0x8B54,
    INT_VEC4                       : 0x8B55,
    BOOL                           : 0x8B56,
    BOOL_VEC2                      : 0x8B57,
    BOOL_VEC3                      : 0x8B58,
    BOOL_VEC4                      : 0x8B59,
    FLOAT_MAT2                     : 0x8B5A,
    FLOAT_MAT3                     : 0x8B5B,
    FLOAT_MAT4                     : 0x8B5C,
    SAMPLER_2D                     : 0x8B5E,
    SAMPLER_CUBE                   : 0x8B60,

    /* Vertex Arrays */
    VERTEX_ATTRIB_ARRAY_ENABLED        : 0x8622,
    VERTEX_ATTRIB_ARRAY_SIZE           : 0x8623,
    VERTEX_ATTRIB_ARRAY_STRIDE         : 0x8624,
    VERTEX_ATTRIB_ARRAY_TYPE           : 0x8625,
    VERTEX_ATTRIB_ARRAY_NORMALIZED     : 0x886A,
    VERTEX_ATTRIB_ARRAY_POINTER        : 0x8645,
    VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F,

    /* Shader Source */
    COMPILE_STATUS                 : 0x8B81,

    /* Shader Precision-Specified Types */
    LOW_FLOAT                      : 0x8DF0,
    MEDIUM_FLOAT                   : 0x8DF1,
    HIGH_FLOAT                     : 0x8DF2,
    LOW_INT                        : 0x8DF3,
    MEDIUM_INT                     : 0x8DF4,
    HIGH_INT                       : 0x8DF5,

    /* Framebuffer Object. */
    FRAMEBUFFER                    : 0x8D40,
    RENDERBUFFER                   : 0x8D41,

    RGBA4                          : 0x8056,
    RGB5_A1                        : 0x8057,
    RGB565                         : 0x8D62,
    DEPTH_COMPONENT16              : 0x81A5,
    STENCIL_INDEX                  : 0x1901,
    STENCIL_INDEX8                 : 0x8D48,
    DEPTH_STENCIL                  : 0x84F9,

    RENDERBUFFER_WIDTH             : 0x8D42,
    RENDERBUFFER_HEIGHT            : 0x8D43,
    RENDERBUFFER_INTERNAL_FORMAT   : 0x8D44,
    RENDERBUFFER_RED_SIZE          : 0x8D50,
    RENDERBUFFER_GREEN_SIZE        : 0x8D51,
    RENDERBUFFER_BLUE_SIZE         : 0x8D52,
    RENDERBUFFER_ALPHA_SIZE        : 0x8D53,
    RENDERBUFFER_DEPTH_SIZE        : 0x8D54,
    RENDERBUFFER_STENCIL_SIZE      : 0x8D55,

    FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE           : 0x8CD0,
    FRAMEBUFFER_ATTACHMENT_OBJECT_NAME           : 0x8CD1,
    FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL         : 0x8CD2,
    FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3,

    COLOR_ATTACHMENT0              : 0x8CE0,
    DEPTH_ATTACHMENT               : 0x8D00,
    STENCIL_ATTACHMENT             : 0x8D20,
    DEPTH_STENCIL_ATTACHMENT       : 0x821A,

    NONE                           : 0,

    FRAMEBUFFER_COMPLETE                      : 0x8CD5,
    FRAMEBUFFER_INCOMPLETE_ATTACHMENT         : 0x8CD6,
    FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : 0x8CD7,
    FRAMEBUFFER_INCOMPLETE_DIMENSIONS         : 0x8CD9,
    FRAMEBUFFER_UNSUPPORTED                   : 0x8CDD,

    FRAMEBUFFER_BINDING            : 0x8CA6,
    RENDERBUFFER_BINDING           : 0x8CA7,
    MAX_RENDERBUFFER_SIZE          : 0x84E8,

    INVALID_FRAMEBUFFER_OPERATION  : 0x0506,

    /* WebGL-specific enums */
    UNPACK_FLIP_Y_WEBGL            : 0x9240,
    UNPACK_PREMULTIPLY_ALPHA_WEBGL : 0x9241,
    CONTEXT_LOST_WEBGL             : 0x9242,
    UNPACK_COLORSPACE_CONVERSION_WEBGL : 0x9243,
    BROWSER_DEFAULT_WEBGL          : 0x9244,
});


/***/ }),
/* 12 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common__ = __webpack_require__(20);

/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */



/**
 * @class 3 Dimensional Vector
 * @name vec3
 */

var vec3 = {};

/**
 * Creates a new, empty vec3
 *
 * @returns {vec3} a new 3D vector
 */
vec3.create = function() {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](3);
    out[0] = 0;
    out[1] = 0;
    out[2] = 0;
    return out;
};

/**
 * Creates a new vec3 initialized with values from an existing vector
 *
 * @param {vec3} a vector to clone
 * @returns {vec3} a new 3D vector
 */
vec3.clone = function(a) {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](3);
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    return out;
};

/**
 * Creates a new vec3 initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @returns {vec3} a new 3D vector
 */
vec3.fromValues = function(x, y, z) {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](3);
    out[0] = x;
    out[1] = y;
    out[2] = z;
    return out;
};

/**
 * Copy the values from one vec3 to another
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the source vector
 * @returns {vec3} out
 */
vec3.copy = function(out, a) {
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    return out;
};

/**
 * Set the components of a vec3 to the given values
 *
 * @param {vec3} out the receiving vector
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @returns {vec3} out
 */
vec3.set = function(out, x, y, z) {
    out[0] = x;
    out[1] = y;
    out[2] = z;
    return out;
};

/**
 * Adds two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */
vec3.add = function(out, a, b) {
    out[0] = a[0] + b[0];
    out[1] = a[1] + b[1];
    out[2] = a[2] + b[2];
    return out;
};

/**
 * Subtracts vector b from vector a
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */
vec3.subtract = function(out, a, b) {
    out[0] = a[0] - b[0];
    out[1] = a[1] - b[1];
    out[2] = a[2] - b[2];
    return out;
};

/**
 * Alias for {@link vec3.subtract}
 * @function
 */
vec3.sub = vec3.subtract;

/**
 * Multiplies two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */
vec3.multiply = function(out, a, b) {
    out[0] = a[0] * b[0];
    out[1] = a[1] * b[1];
    out[2] = a[2] * b[2];
    return out;
};

/**
 * Alias for {@link vec3.multiply}
 * @function
 */
vec3.mul = vec3.multiply;

/**
 * Divides two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */
vec3.divide = function(out, a, b) {
    out[0] = a[0] / b[0];
    out[1] = a[1] / b[1];
    out[2] = a[2] / b[2];
    return out;
};

/**
 * Alias for {@link vec3.divide}
 * @function
 */
vec3.div = vec3.divide;

/**
 * Returns the minimum of two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */
vec3.min = function(out, a, b) {
    out[0] = Math.min(a[0], b[0]);
    out[1] = Math.min(a[1], b[1]);
    out[2] = Math.min(a[2], b[2]);
    return out;
};

/**
 * Returns the maximum of two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */
vec3.max = function(out, a, b) {
    out[0] = Math.max(a[0], b[0]);
    out[1] = Math.max(a[1], b[1]);
    out[2] = Math.max(a[2], b[2]);
    return out;
};

/**
 * Scales a vec3 by a scalar number
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {vec3} out
 */
vec3.scale = function(out, a, b) {
    out[0] = a[0] * b;
    out[1] = a[1] * b;
    out[2] = a[2] * b;
    return out;
};

/**
 * Adds two vec3's after scaling the second operand by a scalar value
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @param {Number} scale the amount to scale b by before adding
 * @returns {vec3} out
 */
vec3.scaleAndAdd = function(out, a, b, scale) {
    out[0] = a[0] + (b[0] * scale);
    out[1] = a[1] + (b[1] * scale);
    out[2] = a[2] + (b[2] * scale);
    return out;
};

/**
 * Calculates the euclidian distance between two vec3's
 *
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {Number} distance between a and b
 */
vec3.distance = function(a, b) {
    var x = b[0] - a[0],
        y = b[1] - a[1],
        z = b[2] - a[2];
    return Math.sqrt(x*x + y*y + z*z);
};

/**
 * Alias for {@link vec3.distance}
 * @function
 */
vec3.dist = vec3.distance;

/**
 * Calculates the squared euclidian distance between two vec3's
 *
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {Number} squared distance between a and b
 */
vec3.squaredDistance = function(a, b) {
    var x = b[0] - a[0],
        y = b[1] - a[1],
        z = b[2] - a[2];
    return x*x + y*y + z*z;
};

/**
 * Alias for {@link vec3.squaredDistance}
 * @function
 */
vec3.sqrDist = vec3.squaredDistance;

/**
 * Calculates the length of a vec3
 *
 * @param {vec3} a vector to calculate length of
 * @returns {Number} length of a
 */
vec3.length = function (a) {
    var x = a[0],
        y = a[1],
        z = a[2];
    return Math.sqrt(x*x + y*y + z*z);
};

/**
 * Alias for {@link vec3.length}
 * @function
 */
vec3.len = vec3.length;

/**
 * Calculates the squared length of a vec3
 *
 * @param {vec3} a vector to calculate squared length of
 * @returns {Number} squared length of a
 */
vec3.squaredLength = function (a) {
    var x = a[0],
        y = a[1],
        z = a[2];
    return x*x + y*y + z*z;
};

/**
 * Alias for {@link vec3.squaredLength}
 * @function
 */
vec3.sqrLen = vec3.squaredLength;

/**
 * Negates the components of a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a vector to negate
 * @returns {vec3} out
 */
vec3.negate = function(out, a) {
    out[0] = -a[0];
    out[1] = -a[1];
    out[2] = -a[2];
    return out;
};

/**
 * Returns the inverse of the components of a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a vector to invert
 * @returns {vec3} out
 */
vec3.inverse = function(out, a) {
  out[0] = 1.0 / a[0];
  out[1] = 1.0 / a[1];
  out[2] = 1.0 / a[2];
  return out;
};

/**
 * Normalize a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a vector to normalize
 * @returns {vec3} out
 */
vec3.normalize = function(out, a) {
    var x = a[0],
        y = a[1],
        z = a[2];
    var len = x*x + y*y + z*z;
    if (len > 0) {
        //TODO: evaluate use of glm_invsqrt here?
        len = 1 / Math.sqrt(len);
        out[0] = a[0] * len;
        out[1] = a[1] * len;
        out[2] = a[2] * len;
    }
    return out;
};

/**
 * Calculates the dot product of two vec3's
 *
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {Number} dot product of a and b
 */
vec3.dot = function (a, b) {
    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
};

/**
 * Computes the cross product of two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */
vec3.cross = function(out, a, b) {
    var ax = a[0], ay = a[1], az = a[2],
        bx = b[0], by = b[1], bz = b[2];

    out[0] = ay * bz - az * by;
    out[1] = az * bx - ax * bz;
    out[2] = ax * by - ay * bx;
    return out;
};

/**
 * Performs a linear interpolation between two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @param {Number} t interpolation amount between the two inputs
 * @returns {vec3} out
 */
vec3.lerp = function (out, a, b, t) {
    var ax = a[0],
        ay = a[1],
        az = a[2];
    out[0] = ax + t * (b[0] - ax);
    out[1] = ay + t * (b[1] - ay);
    out[2] = az + t * (b[2] - az);
    return out;
};

/**
 * Generates a random vector with the given scale
 *
 * @param {vec3} out the receiving vector
 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
 * @returns {vec3} out
 */
vec3.random = function (out, scale) {
    scale = scale || 1.0;

    var r = Object(__WEBPACK_IMPORTED_MODULE_0__common__["c" /* GLMAT_RANDOM */])() * 2.0 * Math.PI;
    var z = (Object(__WEBPACK_IMPORTED_MODULE_0__common__["c" /* GLMAT_RANDOM */])() * 2.0) - 1.0;
    var zScale = Math.sqrt(1.0-z*z) * scale;

    out[0] = Math.cos(r) * zScale;
    out[1] = Math.sin(r) * zScale;
    out[2] = z * scale;
    return out;
};

/**
 * Transforms the vec3 with a mat4.
 * 4th vector component is implicitly '1'
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the vector to transform
 * @param {mat4} m matrix to transform with
 * @returns {vec3} out
 */
vec3.transformMat4 = function(out, a, m) {
    var x = a[0], y = a[1], z = a[2],
        w = m[3] * x + m[7] * y + m[11] * z + m[15];
    w = w || 1.0;
    out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
    out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
    out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
    return out;
};

/**
 * Transforms the vec3 with a mat3.
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the vector to transform
 * @param {mat4} m the 3x3 matrix to transform with
 * @returns {vec3} out
 */
vec3.transformMat3 = function(out, a, m) {
    var x = a[0], y = a[1], z = a[2];
    out[0] = x * m[0] + y * m[3] + z * m[6];
    out[1] = x * m[1] + y * m[4] + z * m[7];
    out[2] = x * m[2] + y * m[5] + z * m[8];
    return out;
};

/**
 * Transforms the vec3 with a quat
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the vector to transform
 * @param {quat} q quaternion to transform with
 * @returns {vec3} out
 */
vec3.transformQuat = function(out, a, q) {
    // benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations

    var x = a[0], y = a[1], z = a[2],
        qx = q[0], qy = q[1], qz = q[2], qw = q[3],

        // calculate quat * vec
        ix = qw * x + qy * z - qz * y,
        iy = qw * y + qz * x - qx * z,
        iz = qw * z + qx * y - qy * x,
        iw = -qx * x - qy * y - qz * z;

    // calculate result * inverse quat
    out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
    out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
    out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
    return out;
};

/**
 * Rotate a 3D vector around the x-axis
 * @param {vec3} out The receiving vec3
 * @param {vec3} a The vec3 point to rotate
 * @param {vec3} b The origin of the rotation
 * @param {Number} c The angle of rotation
 * @returns {vec3} out
 */
vec3.rotateX = function(out, a, b, c){
   var p = [], r=[];
      //Translate point to the origin
      p[0] = a[0] - b[0];
      p[1] = a[1] - b[1];
    p[2] = a[2] - b[2];

      //perform rotation
      r[0] = p[0];
      r[1] = p[1]*Math.cos(c) - p[2]*Math.sin(c);
      r[2] = p[1]*Math.sin(c) + p[2]*Math.cos(c);

      //translate to correct position
      out[0] = r[0] + b[0];
      out[1] = r[1] + b[1];
      out[2] = r[2] + b[2];

    return out;
};

/**
 * Rotate a 3D vector around the y-axis
 * @param {vec3} out The receiving vec3
 * @param {vec3} a The vec3 point to rotate
 * @param {vec3} b The origin of the rotation
 * @param {Number} c The angle of rotation
 * @returns {vec3} out
 */
vec3.rotateY = function(out, a, b, c){
    var p = [], r=[];
    //Translate point to the origin
    p[0] = a[0] - b[0];
    p[1] = a[1] - b[1];
    p[2] = a[2] - b[2];

    //perform rotation
    r[0] = p[2]*Math.sin(c) + p[0]*Math.cos(c);
    r[1] = p[1];
    r[2] = p[2]*Math.cos(c) - p[0]*Math.sin(c);

    //translate to correct position
    out[0] = r[0] + b[0];
    out[1] = r[1] + b[1];
    out[2] = r[2] + b[2];

    return out;
};

/**
 * Rotate a 3D vector around the z-axis
 * @param {vec3} out The receiving vec3
 * @param {vec3} a The vec3 point to rotate
 * @param {vec3} b The origin of the rotation
 * @param {Number} c The angle of rotation
 * @returns {vec3} out
 */
vec3.rotateZ = function(out, a, b, c){
    var p = [], r=[];
    //Translate point to the origin
    p[0] = a[0] - b[0];
    p[1] = a[1] - b[1];
    p[2] = a[2] - b[2];

    //perform rotation
    r[0] = p[0]*Math.cos(c) - p[1]*Math.sin(c);
    r[1] = p[0]*Math.sin(c) + p[1]*Math.cos(c);
    r[2] = p[2];

    //translate to correct position
    out[0] = r[0] + b[0];
    out[1] = r[1] + b[1];
    out[2] = r[2] + b[2];

    return out;
};

/**
 * Perform some operation over an array of vec3s.
 *
 * @param {Array} a the array of vectors to iterate over
 * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
 * @param {Number} offset Number of elements to skip at the beginning of the array
 * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
 * @param {Function} fn Function to call for each vector in the array
 * @param {Object} [arg] additional argument to pass to fn
 * @returns {Array} a
 * @function
 */
vec3.forEach = (function() {
    var vec = vec3.create();

    return function(a, stride, offset, count, fn, arg) {
        var i, l;
        if(!stride) {
            stride = 3;
        }

        if(!offset) {
            offset = 0;
        }

        if(count) {
            l = Math.min((count * stride) + offset, a.length);
        } else {
            l = a.length;
        }

        for(i = offset; i < l; i += stride) {
            vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2];
            fn(vec, vec, arg);
            a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2];
        }

        return a;
    };
})();

/**
 * Get the angle between two 3D vectors
 * @param {vec3} a The first operand
 * @param {vec3} b The second operand
 * @returns {Number} The angle in radians
 */
vec3.angle = function(a, b) {

    var tempA = vec3.fromValues(a[0], a[1], a[2]);
    var tempB = vec3.fromValues(b[0], b[1], b[2]);

    vec3.normalize(tempA, tempA);
    vec3.normalize(tempB, tempB);

    var cosine = vec3.dot(tempA, tempB);

    if(cosine > 1.0){
        return 0;
    } else {
        return Math.acos(cosine);
    }
};

/* harmony default export */ __webpack_exports__["a"] = (vec3);

/***/ }),
/* 13 */
/***/ (function(module, exports) {

/**
 * @module zrender/core/util
 */
// 用于处理merge时无法遍历Date等对象的问题
var BUILTIN_OBJECT = {
  '[object Function]': 1,
  '[object RegExp]': 1,
  '[object Date]': 1,
  '[object Error]': 1,
  '[object CanvasGradient]': 1,
  '[object CanvasPattern]': 1,
  // For node-canvas
  '[object Image]': 1,
  '[object Canvas]': 1
};
var TYPED_ARRAY = {
  '[object Int8Array]': 1,
  '[object Uint8Array]': 1,
  '[object Uint8ClampedArray]': 1,
  '[object Int16Array]': 1,
  '[object Uint16Array]': 1,
  '[object Int32Array]': 1,
  '[object Uint32Array]': 1,
  '[object Float32Array]': 1,
  '[object Float64Array]': 1
};
var objToString = Object.prototype.toString;
var arrayProto = Array.prototype;
var nativeForEach = arrayProto.forEach;
var nativeFilter = arrayProto.filter;
var nativeSlice = arrayProto.slice;
var nativeMap = arrayProto.map;
var nativeReduce = arrayProto.reduce; // Avoid assign to an exported variable, for transforming to cjs.

var methods = {};

function $override(name, fn) {
  // Clear ctx instance for different environment
  if (name === 'createCanvas') {
    _ctx = null;
  }

  methods[name] = fn;
}
/**
 * Those data types can be cloned:
 *     Plain object, Array, TypedArray, number, string, null, undefined.
 * Those data types will be assgined using the orginal data:
 *     BUILTIN_OBJECT
 * Instance of user defined class will be cloned to a plain object, without
 * properties in prototype.
 * Other data types is not supported (not sure what will happen).
 *
 * Caution: do not support clone Date, for performance consideration.
 * (There might be a large number of date in `series.data`).
 * So date should not be modified in and out of echarts.
 *
 * @param {*} source
 * @return {*} new
 */


function clone(source) {
  if (source == null || typeof source != 'object') {
    return source;
  }

  var result = source;
  var typeStr = objToString.call(source);

  if (typeStr === '[object Array]') {
    if (!isPrimitive(source)) {
      result = [];

      for (var i = 0, len = source.length; i < len; i++) {
        result[i] = clone(source[i]);
      }
    }
  } else if (TYPED_ARRAY[typeStr]) {
    if (!isPrimitive(source)) {
      var Ctor = source.constructor;

      if (source.constructor.from) {
        result = Ctor.from(source);
      } else {
        result = new Ctor(source.length);

        for (var i = 0, len = source.length; i < len; i++) {
          result[i] = clone(source[i]);
        }
      }
    }
  } else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) {
    result = {};

    for (var key in source) {
      if (source.hasOwnProperty(key)) {
        result[key] = clone(source[key]);
      }
    }
  }

  return result;
}
/**
 * @memberOf module:zrender/core/util
 * @param {*} target
 * @param {*} source
 * @param {boolean} [overwrite=false]
 */


function merge(target, source, overwrite) {
  // We should escapse that source is string
  // and enter for ... in ...
  if (!isObject(source) || !isObject(target)) {
    return overwrite ? clone(source) : target;
  }

  for (var key in source) {
    if (source.hasOwnProperty(key)) {
      var targetProp = target[key];
      var sourceProp = source[key];

      if (isObject(sourceProp) && isObject(targetProp) && !isArray(sourceProp) && !isArray(targetProp) && !isDom(sourceProp) && !isDom(targetProp) && !isBuiltInObject(sourceProp) && !isBuiltInObject(targetProp) && !isPrimitive(sourceProp) && !isPrimitive(targetProp)) {
        // 如果需要递归覆盖，就递归调用merge
        merge(targetProp, sourceProp, overwrite);
      } else if (overwrite || !(key in target)) {
        // 否则只处理overwrite为true，或者在目标对象中没有此属性的情况
        // NOTE，在 target[key] 不存在的时候也是直接覆盖
        target[key] = clone(source[key], true);
      }
    }
  }

  return target;
}
/**
 * @param {Array} targetAndSources The first item is target, and the rests are source.
 * @param {boolean} [overwrite=false]
 * @return {*} target
 */


function mergeAll(targetAndSources, overwrite) {
  var result = targetAndSources[0];

  for (var i = 1, len = targetAndSources.length; i < len; i++) {
    result = merge(result, targetAndSources[i], overwrite);
  }

  return result;
}
/**
 * @param {*} target
 * @param {*} source
 * @memberOf module:zrender/core/util
 */


function extend(target, source) {
  for (var key in source) {
    if (source.hasOwnProperty(key)) {
      target[key] = source[key];
    }
  }

  return target;
}
/**
 * @param {*} target
 * @param {*} source
 * @param {boolean} [overlay=false]
 * @memberOf module:zrender/core/util
 */


function defaults(target, source, overlay) {
  for (var key in source) {
    if (source.hasOwnProperty(key) && (overlay ? source[key] != null : target[key] == null)) {
      target[key] = source[key];
    }
  }

  return target;
}

var createCanvas = function () {
  return methods.createCanvas();
};

methods.createCanvas = function () {
  return document.createElement('canvas');
}; // FIXME


var _ctx;

function getContext() {
  if (!_ctx) {
    // Use util.createCanvas instead of createCanvas
    // because createCanvas may be overwritten in different environment
    _ctx = createCanvas().getContext('2d');
  }

  return _ctx;
}
/**
 * 查询数组中元素的index
 * @memberOf module:zrender/core/util
 */


function indexOf(array, value) {
  if (array) {
    if (array.indexOf) {
      return array.indexOf(value);
    }

    for (var i = 0, len = array.length; i < len; i++) {
      if (array[i] === value) {
        return i;
      }
    }
  }

  return -1;
}
/**
 * 构造类继承关系
 *
 * @memberOf module:zrender/core/util
 * @param {Function} clazz 源类
 * @param {Function} baseClazz 基类
 */


function inherits(clazz, baseClazz) {
  var clazzPrototype = clazz.prototype;

  function F() {}

  F.prototype = baseClazz.prototype;
  clazz.prototype = new F();

  for (var prop in clazzPrototype) {
    clazz.prototype[prop] = clazzPrototype[prop];
  }

  clazz.prototype.constructor = clazz;
  clazz.superClass = baseClazz;
}
/**
 * @memberOf module:zrender/core/util
 * @param {Object|Function} target
 * @param {Object|Function} sorce
 * @param {boolean} overlay
 */


function mixin(target, source, overlay) {
  target = 'prototype' in target ? target.prototype : target;
  source = 'prototype' in source ? source.prototype : source;
  defaults(target, source, overlay);
}
/**
 * Consider typed array.
 * @param {Array|TypedArray} data
 */


function isArrayLike(data) {
  if (!data) {
    return;
  }

  if (typeof data == 'string') {
    return false;
  }

  return typeof data.length == 'number';
}
/**
 * 数组或对象遍历
 * @memberOf module:zrender/core/util
 * @param {Object|Array} obj
 * @param {Function} cb
 * @param {*} [context]
 */


function each(obj, cb, context) {
  if (!(obj && cb)) {
    return;
  }

  if (obj.forEach && obj.forEach === nativeForEach) {
    obj.forEach(cb, context);
  } else if (obj.length === +obj.length) {
    for (var i = 0, len = obj.length; i < len; i++) {
      cb.call(context, obj[i], i, obj);
    }
  } else {
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        cb.call(context, obj[key], key, obj);
      }
    }
  }
}
/**
 * 数组映射
 * @memberOf module:zrender/core/util
 * @param {Array} obj
 * @param {Function} cb
 * @param {*} [context]
 * @return {Array}
 */


function map(obj, cb, context) {
  if (!(obj && cb)) {
    return;
  }

  if (obj.map && obj.map === nativeMap) {
    return obj.map(cb, context);
  } else {
    var result = [];

    for (var i = 0, len = obj.length; i < len; i++) {
      result.push(cb.call(context, obj[i], i, obj));
    }

    return result;
  }
}
/**
 * @memberOf module:zrender/core/util
 * @param {Array} obj
 * @param {Function} cb
 * @param {Object} [memo]
 * @param {*} [context]
 * @return {Array}
 */


function reduce(obj, cb, memo, context) {
  if (!(obj && cb)) {
    return;
  }

  if (obj.reduce && obj.reduce === nativeReduce) {
    return obj.reduce(cb, memo, context);
  } else {
    for (var i = 0, len = obj.length; i < len; i++) {
      memo = cb.call(context, memo, obj[i], i, obj);
    }

    return memo;
  }
}
/**
 * 数组过滤
 * @memberOf module:zrender/core/util
 * @param {Array} obj
 * @param {Function} cb
 * @param {*} [context]
 * @return {Array}
 */


function filter(obj, cb, context) {
  if (!(obj && cb)) {
    return;
  }

  if (obj.filter && obj.filter === nativeFilter) {
    return obj.filter(cb, context);
  } else {
    var result = [];

    for (var i = 0, len = obj.length; i < len; i++) {
      if (cb.call(context, obj[i], i, obj)) {
        result.push(obj[i]);
      }
    }

    return result;
  }
}
/**
 * 数组项查找
 * @memberOf module:zrender/core/util
 * @param {Array} obj
 * @param {Function} cb
 * @param {*} [context]
 * @return {*}
 */


function find(obj, cb, context) {
  if (!(obj && cb)) {
    return;
  }

  for (var i = 0, len = obj.length; i < len; i++) {
    if (cb.call(context, obj[i], i, obj)) {
      return obj[i];
    }
  }
}
/**
 * @memberOf module:zrender/core/util
 * @param {Function} func
 * @param {*} context
 * @return {Function}
 */


function bind(func, context) {
  var args = nativeSlice.call(arguments, 2);
  return function () {
    return func.apply(context, args.concat(nativeSlice.call(arguments)));
  };
}
/**
 * @memberOf module:zrender/core/util
 * @param {Function} func
 * @return {Function}
 */


function curry(func) {
  var args = nativeSlice.call(arguments, 1);
  return function () {
    return func.apply(this, args.concat(nativeSlice.call(arguments)));
  };
}
/**
 * @memberOf module:zrender/core/util
 * @param {*} value
 * @return {boolean}
 */


function isArray(value) {
  return objToString.call(value) === '[object Array]';
}
/**
 * @memberOf module:zrender/core/util
 * @param {*} value
 * @return {boolean}
 */


function isFunction(value) {
  return typeof value === 'function';
}
/**
 * @memberOf module:zrender/core/util
 * @param {*} value
 * @return {boolean}
 */


function isString(value) {
  return objToString.call(value) === '[object String]';
}
/**
 * @memberOf module:zrender/core/util
 * @param {*} value
 * @return {boolean}
 */


function isObject(value) {
  // Avoid a V8 JIT bug in Chrome 19-20.
  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
  var type = typeof value;
  return type === 'function' || !!value && type == 'object';
}
/**
 * @memberOf module:zrender/core/util
 * @param {*} value
 * @return {boolean}
 */


function isBuiltInObject(value) {
  return !!BUILTIN_OBJECT[objToString.call(value)];
}
/**
 * @memberOf module:zrender/core/util
 * @param {*} value
 * @return {boolean}
 */


function isTypedArray(value) {
  return !!TYPED_ARRAY[objToString.call(value)];
}
/**
 * @memberOf module:zrender/core/util
 * @param {*} value
 * @return {boolean}
 */


function isDom(value) {
  return typeof value === 'object' && typeof value.nodeType === 'number' && typeof value.ownerDocument === 'object';
}
/**
 * Whether is exactly NaN. Notice isNaN('a') returns true.
 * @param {*} value
 * @return {boolean}
 */


function eqNaN(value) {
  return value !== value;
}
/**
 * If value1 is not null, then return value1, otherwise judget rest of values.
 * Low performance.
 * @memberOf module:zrender/core/util
 * @return {*} Final value
 */


function retrieve(values) {
  for (var i = 0, len = arguments.length; i < len; i++) {
    if (arguments[i] != null) {
      return arguments[i];
    }
  }
}

function retrieve2(value0, value1) {
  return value0 != null ? value0 : value1;
}

function retrieve3(value0, value1, value2) {
  return value0 != null ? value0 : value1 != null ? value1 : value2;
}
/**
 * @memberOf module:zrender/core/util
 * @param {Array} arr
 * @param {number} startIndex
 * @param {number} endIndex
 * @return {Array}
 */


function slice() {
  return Function.call.apply(nativeSlice, arguments);
}
/**
 * Normalize css liked array configuration
 * e.g.
 *  3 => [3, 3, 3, 3]
 *  [4, 2] => [4, 2, 4, 2]
 *  [4, 3, 2] => [4, 3, 2, 3]
 * @param {number|Array.<number>} val
 * @return {Array.<number>}
 */


function normalizeCssArray(val) {
  if (typeof val === 'number') {
    return [val, val, val, val];
  }

  var len = val.length;

  if (len === 2) {
    // vertical | horizontal
    return [val[0], val[1], val[0], val[1]];
  } else if (len === 3) {
    // top | horizontal | bottom
    return [val[0], val[1], val[2], val[1]];
  }

  return val;
}
/**
 * @memberOf module:zrender/core/util
 * @param {boolean} condition
 * @param {string} message
 */


function assert(condition, message) {
  if (!condition) {
    throw new Error(message);
  }
}
/**
 * @memberOf module:zrender/core/util
 * @param {string} str string to be trimed
 * @return {string} trimed string
 */


function trim(str) {
  if (str == null) {
    return null;
  } else if (typeof str.trim === 'function') {
    return str.trim();
  } else {
    return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
  }
}

var primitiveKey = '__ec_primitive__';
/**
 * Set an object as primitive to be ignored traversing children in clone or merge
 */

function setAsPrimitive(obj) {
  obj[primitiveKey] = true;
}

function isPrimitive(obj) {
  return obj[primitiveKey];
}
/**
 * @constructor
 * @param {Object} obj Only apply `ownProperty`.
 */


function HashMap(obj) {
  var isArr = isArray(obj);
  var thisMap = this;
  obj instanceof HashMap ? obj.each(visit) : obj && each(obj, visit);

  function visit(value, key) {
    isArr ? thisMap.set(value, key) : thisMap.set(key, value);
  }
} // Add prefix to avoid conflict with Object.prototype.


HashMap.prototype = {
  constructor: HashMap,
  // Do not provide `has` method to avoid defining what is `has`.
  // (We usually treat `null` and `undefined` as the same, different
  // from ES6 Map).
  get: function (key) {
    return this.hasOwnProperty(key) ? this[key] : null;
  },
  set: function (key, value) {
    // Comparing with invocation chaining, `return value` is more commonly
    // used in this case: `var someVal = map.set('a', genVal());`
    return this[key] = value;
  },
  // Although util.each can be performed on this hashMap directly, user
  // should not use the exposed keys, who are prefixed.
  each: function (cb, context) {
    context !== void 0 && (cb = bind(cb, context));

    for (var key in this) {
      this.hasOwnProperty(key) && cb(this[key], key);
    }
  },
  // Do not use this method if performance sensitive.
  removeKey: function (key) {
    delete this[key];
  }
};

function createHashMap(obj) {
  return new HashMap(obj);
}

function concatArray(a, b) {
  var newArray = new a.constructor(a.length + b.length);

  for (var i = 0; i < a.length; i++) {
    newArray[i] = a[i];
  }

  var offset = a.length;

  for (i = 0; i < b.length; i++) {
    newArray[i + offset] = b[i];
  }

  return newArray;
}

function noop() {}

exports.$override = $override;
exports.clone = clone;
exports.merge = merge;
exports.mergeAll = mergeAll;
exports.extend = extend;
exports.defaults = defaults;
exports.createCanvas = createCanvas;
exports.getContext = getContext;
exports.indexOf = indexOf;
exports.inherits = inherits;
exports.mixin = mixin;
exports.isArrayLike = isArrayLike;
exports.each = each;
exports.map = map;
exports.reduce = reduce;
exports.filter = filter;
exports.find = find;
exports.bind = bind;
exports.curry = curry;
exports.isArray = isArray;
exports.isFunction = isFunction;
exports.isString = isString;
exports.isObject = isObject;
exports.isBuiltInObject = isBuiltInObject;
exports.isTypedArray = isTypedArray;
exports.isDom = isDom;
exports.eqNaN = eqNaN;
exports.retrieve = retrieve;
exports.retrieve2 = retrieve2;
exports.retrieve3 = retrieve3;
exports.slice = slice;
exports.normalizeCssArray = normalizeCssArray;
exports.assert = assert;
exports.trim = trim;
exports.setAsPrimitive = setAsPrimitive;
exports.isPrimitive = isPrimitive;
exports.createHashMap = createHashMap;
exports.concatArray = concatArray;
exports.noop = noop;

/***/ }),
/* 14 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function(global) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__request__ = __webpack_require__(112);


var supportWebGL;

var vendor = {};

/**
 * If support WebGL
 * @return {boolean}
 */
vendor.supportWebGL = function () {
    if (supportWebGL == null) {
        try {
            var canvas = document.createElement('canvas');
            var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
            if (!gl) {
                throw new Error();
            }
        }
        catch (e) {
            supportWebGL = false;
        }

    }
    return supportWebGL;
};

vendor.Int8Array = typeof Int8Array === 'undefined' ? Array : Int8Array;

vendor.Uint8Array = typeof Uint8Array === 'undefined' ? Array : Uint8Array;

vendor.Uint16Array = typeof Uint16Array === 'undefined' ? Array : Uint16Array;

vendor.Uint32Array = typeof Uint32Array === 'undefined' ? Array : Uint32Array;

vendor.Int16Array = typeof Int16Array === 'undefined' ? Array : Int16Array;

vendor.Float32Array = typeof Float32Array === 'undefined' ? Array : Float32Array;

vendor.Float64Array = typeof Float64Array === 'undefined' ? Array : Float64Array;

var g = {};
if (typeof window !== 'undefined') {
    g = window;
}
else if (typeof global !== 'undefined') {
    g = global;
}
vendor.requestAnimationFrame = g.requestAnimationFrame
    || g.msRequestAnimationFrame
    || g.mozRequestAnimationFrame
    || g.webkitRequestAnimationFrame
    || function (func){ setTimeout(func, 16); };

vendor.createCanvas = function () {
    return document.createElement('canvas');
};

vendor.createImage = function () {
    return new g.Image();
};

vendor.request = {
    get: __WEBPACK_IMPORTED_MODULE_0__request__["a" /* default */].get
};

/* harmony default export */ __webpack_exports__["a"] = (vendor);

/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(68)))

/***/ }),
/* 15 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_vendor__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__ = __webpack_require__(12);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__glmatrix_mat4__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__GeometryBase__ = __webpack_require__(118);






var vec3Create = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create;
var vec3Add = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].add;
var vec3Set = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].set;

var Attribute = __WEBPACK_IMPORTED_MODULE_4__GeometryBase__["a" /* default */].Attribute;

/**
 * Geometry in ClayGL contains vertex attributes of mesh. These vertex attributes will be finally provided to the {@link clay.Shader}.
 * Different {@link clay.Shader} needs different attributes. Here is a list of attributes used in the builtin shaders.
 *
 * + position: `clay.basic`, `clay.lambert`, `clay.standard`
 * + texcoord0: `clay.basic`, `clay.lambert`, `clay.standard`
 * + color: `clay.basic`, `clay.lambert`, `clay.standard`
 * + weight: `clay.basic`, `clay.lambert`, `clay.standard`
 * + joint: `clay.basic`, `clay.lambert`, `clay.standard`
 * + normal: `clay.lambert`, `clay.standard`
 * + tangent: `clay.standard`
 *
 * #### Create a procedural geometry
 *
 * ClayGL provides a couple of builtin procedural geometries. Inlcuding:
 *
 *  + {@link clay.geometry.Cube}
 *  + {@link clay.geometry.Sphere}
 *  + {@link clay.geometry.Plane}
 *  + {@link clay.geometry.Cylinder}
 *  + {@link clay.geometry.Cone}
 *  + {@link clay.geometry.ParametricSurface}
 *
 * It's simple to create a basic geometry with these classes.
 *
```js
var sphere = new clay.geometry.Sphere({
    radius: 2
});
```
 *
 * #### Create the geometry data by yourself
 *
 * Usually the vertex attributes data are created by the {@link clay.loader.GLTF} or procedural geometries like {@link clay.geometry.Sphere}.
 * Besides these, you can create the data manually. Here is a simple example to create a triangle.
```js
var TRIANGLE_POSITIONS = [
    [-0.5, -0.5, 0],
    [0.5, -0.5, 0],
    [0, 0.5, 0]
];
var geometry = new clay.StaticGeometryBase();
// Add triangle vertices to position attribute.
geometry.attributes.position.fromArray(TRIANGLE_POSITIONS);
```
 * Then you can use the utility methods like `generateVertexNormals`, `generateTangents` to create the remaining necessary attributes.
 *
 *
 * #### Use with custom shaders
 *
 * If you wan't to write custom shaders. Don't forget to add SEMANTICS to these attributes. For example
 *
 ```glsl
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION;
uniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;
uniform mat4 world : WORLD;

attribute vec3 position : POSITION;
attribute vec2 texcoord : TEXCOORD_0;
attribute vec3 normal : NORMAL;
```
 * These `POSITION`, `TEXCOORD_0`, `NORMAL` are SEMANTICS which will map the attributes in shader to the attributes in the GeometryBase
 *
 * Available attributes SEMANTICS includes `POSITION`, `TEXCOORD_0`, `TEXCOORD_1` `NORMAL`, `TANGENT`, `COLOR`, `WEIGHT`, `JOINT`.
 *
 *
 * @constructor clay.Geometry
 * @extends clay.GeometryBase
 */
var Geometry = __WEBPACK_IMPORTED_MODULE_4__GeometryBase__["a" /* default */].extend(function () {
    return /** @lends clay.Geometry# */ {
        /**
         * Attributes of geometry. Including:
         *  + `position`
         *  + `texcoord0`
         *  + `texcoord1`
         *  + `normal`
         *  + `tangent`
         *  + `color`
         *  + `weight`
         *  + `joint`
         *  + `barycentric`
         *
         * @type {Object.<string, clay.Geometry.Attribute>}
         */
        attributes: {
            position: new Attribute('position', 'float', 3, 'POSITION'),
            texcoord0: new Attribute('texcoord0', 'float', 2, 'TEXCOORD_0'),
            texcoord1: new Attribute('texcoord1', 'float', 2, 'TEXCOORD_1'),
            normal: new Attribute('normal', 'float', 3, 'NORMAL'),
            tangent: new Attribute('tangent', 'float', 4, 'TANGENT'),
            color: new Attribute('color', 'float', 4, 'COLOR'),
            // Skinning attributes
            // Each vertex can be bind to 4 bones, because the
            // sum of weights is 1, so the weights is stored in vec3 and the last
            // can be calculated by 1-w.x-w.y-w.z
            weight: new Attribute('weight', 'float', 3, 'WEIGHT'),
            joint: new Attribute('joint', 'float', 4, 'JOINT'),
            // For wireframe display
            // http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/
            barycentric: new Attribute('barycentric', 'float', 3, null),
        },
        /**
         * Calculated bounding box of geometry.
         * @type {clay.BoundingBox}
         */
        boundingBox: null
    };
},
/** @lends clay.Geometry.prototype */
{

    mainAttribute: 'position',

    /**
     * Update boundingBox of Geometry
     */
    updateBoundingBox: function () {
        var bbox = this.boundingBox;
        if (!bbox) {
            bbox = this.boundingBox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
        }
        var posArr = this.attributes.position.value;
        if (posArr && posArr.length) {
            var min = bbox.min;
            var max = bbox.max;
            var minArr = min.array;
            var maxArr = max.array;
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].set(minArr, posArr[0], posArr[1], posArr[2]);
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].set(maxArr, posArr[0], posArr[1], posArr[2]);
            for (var i = 3; i < posArr.length;) {
                var x = posArr[i++];
                var y = posArr[i++];
                var z = posArr[i++];
                if (x < minArr[0]) { minArr[0] = x; }
                if (y < minArr[1]) { minArr[1] = y; }
                if (z < minArr[2]) { minArr[2] = z; }

                if (x > maxArr[0]) { maxArr[0] = x; }
                if (y > maxArr[1]) { maxArr[1] = y; }
                if (z > maxArr[2]) { maxArr[2] = z; }
            }
            min._dirty = true;
            max._dirty = true;
        }
    },

    /**
     * Generate normals per vertex.
     */
    generateVertexNormals: function () {
        if (!this.vertexCount) {
            return;
        }

        var indices = this.indices;
        var attributes = this.attributes;
        var positions = attributes.position.value;
        var normals = attributes.normal.value;

        if (!normals || normals.length !== positions.length) {
            normals = attributes.normal.value = new __WEBPACK_IMPORTED_MODULE_0__core_vendor__["a" /* default */].Float32Array(positions.length);
        }
        else {
            // Reset
            for (var i = 0; i < normals.length; i++) {
                normals[i] = 0;
            }
        }

        var p1 = vec3Create();
        var p2 = vec3Create();
        var p3 = vec3Create();

        var v21 = vec3Create();
        var v32 = vec3Create();

        var n = vec3Create();

        var len = indices ? indices.length : this.vertexCount;
        var i1, i2, i3;
        for (var f = 0; f < len;) {
            if (indices) {
                i1 = indices[f++];
                i2 = indices[f++];
                i3 = indices[f++];
            }
            else {
                i1 = f++;
                i2 = f++;
                i3 = f++;
            }

            vec3Set(p1, positions[i1*3], positions[i1*3+1], positions[i1*3+2]);
            vec3Set(p2, positions[i2*3], positions[i2*3+1], positions[i2*3+2]);
            vec3Set(p3, positions[i3*3], positions[i3*3+1], positions[i3*3+2]);

            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].sub(v21, p1, p2);
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].sub(v32, p2, p3);
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].cross(n, v21, v32);
            // Already be weighted by the triangle area
            for (var i = 0; i < 3; i++) {
                normals[i1*3+i] = normals[i1*3+i] + n[i];
                normals[i2*3+i] = normals[i2*3+i] + n[i];
                normals[i3*3+i] = normals[i3*3+i] + n[i];
            }
        }

        for (var i = 0; i < normals.length;) {
            vec3Set(n, normals[i], normals[i+1], normals[i+2]);
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].normalize(n, n);
            normals[i++] = n[0];
            normals[i++] = n[1];
            normals[i++] = n[2];
        }
        this.dirty();
    },

    /**
     * Generate normals per face.
     */
    generateFaceNormals: function () {
        if (!this.vertexCount) {
            return;
        }

        if (!this.isUniqueVertex()) {
            this.generateUniqueVertex();
        }

        var indices = this.indices;
        var attributes = this.attributes;
        var positions = attributes.position.value;
        var normals = attributes.normal.value;

        var p1 = vec3Create();
        var p2 = vec3Create();
        var p3 = vec3Create();

        var v21 = vec3Create();
        var v32 = vec3Create();
        var n = vec3Create();

        if (!normals) {
            normals = attributes.normal.value = new Float32Array(positions.length);
        }
        var len = indices ? indices.length : this.vertexCount;
        var i1, i2, i3;
        for (var f = 0; f < len;) {
            if (indices) {
                i1 = indices[f++];
                i2 = indices[f++];
                i3 = indices[f++];
            }
            else {
                i1 = f++;
                i2 = f++;
                i3 = f++;
            }

            vec3Set(p1, positions[i1*3], positions[i1*3+1], positions[i1*3+2]);
            vec3Set(p2, positions[i2*3], positions[i2*3+1], positions[i2*3+2]);
            vec3Set(p3, positions[i3*3], positions[i3*3+1], positions[i3*3+2]);

            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].sub(v21, p1, p2);
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].sub(v32, p2, p3);
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].cross(n, v21, v32);

            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].normalize(n, n);

            for (var i = 0; i < 3; i++) {
                normals[i1*3 + i] = n[i];
                normals[i2*3 + i] = n[i];
                normals[i3*3 + i] = n[i];
            }
        }
        this.dirty();
    },

    /**
     * Generate tangents attributes.
     */
    generateTangents: function () {
        if (!this.vertexCount) {
            return;
        }

        var nVertex = this.vertexCount;
        var attributes = this.attributes;
        if (!attributes.tangent.value) {
            attributes.tangent.value = new Float32Array(nVertex * 4);
        }
        var texcoords = attributes.texcoord0.value;
        var positions = attributes.position.value;
        var tangents = attributes.tangent.value;
        var normals = attributes.normal.value;

        if (!texcoords) {
            console.warn('Geometry without texcoords can\'t generate tangents.');
            return;
        }

        var tan1 = [];
        var tan2 = [];
        for (var i = 0; i < nVertex; i++) {
            tan1[i] = [0.0, 0.0, 0.0];
            tan2[i] = [0.0, 0.0, 0.0];
        }

        var sdir = [0.0, 0.0, 0.0];
        var tdir = [0.0, 0.0, 0.0];
        var indices = this.indices;

        var len = indices ? indices.length : this.vertexCount;
        var i1, i2, i3;
        for (var i = 0; i < len;) {
            if (indices) {
                i1 = indices[i++];
                i2 = indices[i++];
                i3 = indices[i++];
            }
            else {
                i1 = i++;
                i2 = i++;
                i3 = i++;
            }

            var st1s = texcoords[i1 * 2],
                st2s = texcoords[i2 * 2],
                st3s = texcoords[i3 * 2],
                st1t = texcoords[i1 * 2 + 1],
                st2t = texcoords[i2 * 2 + 1],
                st3t = texcoords[i3 * 2 + 1],

                p1x = positions[i1 * 3],
                p2x = positions[i2 * 3],
                p3x = positions[i3 * 3],
                p1y = positions[i1 * 3 + 1],
                p2y = positions[i2 * 3 + 1],
                p3y = positions[i3 * 3 + 1],
                p1z = positions[i1 * 3 + 2],
                p2z = positions[i2 * 3 + 2],
                p3z = positions[i3 * 3 + 2];

            var x1 = p2x - p1x,
                x2 = p3x - p1x,
                y1 = p2y - p1y,
                y2 = p3y - p1y,
                z1 = p2z - p1z,
                z2 = p3z - p1z;

            var s1 = st2s - st1s,
                s2 = st3s - st1s,
                t1 = st2t - st1t,
                t2 = st3t - st1t;

            var r = 1.0 / (s1 * t2 - t1 * s2);
            sdir[0] = (t2 * x1 - t1 * x2) * r;
            sdir[1] = (t2 * y1 - t1 * y2) * r;
            sdir[2] = (t2 * z1 - t1 * z2) * r;

            tdir[0] = (s1 * x2 - s2 * x1) * r;
            tdir[1] = (s1 * y2 - s2 * y1) * r;
            tdir[2] = (s1 * z2 - s2 * z1) * r;

            vec3Add(tan1[i1], tan1[i1], sdir);
            vec3Add(tan1[i2], tan1[i2], sdir);
            vec3Add(tan1[i3], tan1[i3], sdir);
            vec3Add(tan2[i1], tan2[i1], tdir);
            vec3Add(tan2[i2], tan2[i2], tdir);
            vec3Add(tan2[i3], tan2[i3], tdir);
        }
        var tmp = vec3Create();
        var nCrossT = vec3Create();
        var n = vec3Create();
        for (var i = 0; i < nVertex; i++) {
            n[0] = normals[i * 3];
            n[1] = normals[i * 3 + 1];
            n[2] = normals[i * 3 + 2];
            var t = tan1[i];

            // Gram-Schmidt orthogonalize
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].scale(tmp, n, __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].dot(n, t));
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].sub(tmp, t, tmp);
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].normalize(tmp, tmp);
            // Calculate handedness.
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].cross(nCrossT, n, t);
            tangents[i * 4] = tmp[0];
            tangents[i * 4 + 1] = tmp[1];
            tangents[i * 4 + 2] = tmp[2];
            // PENDING can config ?
            tangents[i * 4 + 3] = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].dot(nCrossT, tan2[i]) < 0.0 ? -1.0 : 1.0;
        }
        this.dirty();
    },

    /**
     * If vertices are not shared by different indices.
     */
    isUniqueVertex: function () {
        if (this.isUseIndices()) {
            return this.vertexCount === this.indices.length;
        }
        else {
            return true;
        }
    },
    /**
     * Create a unique vertex for each index.
     */
    generateUniqueVertex: function () {
        if (!this.vertexCount || !this.indices) {
            return;
        }

        if (this.indices.length > 0xffff) {
            this.indices = new __WEBPACK_IMPORTED_MODULE_0__core_vendor__["a" /* default */].Uint32Array(this.indices);
        }

        var attributes = this.attributes;
        var indices = this.indices;

        var attributeNameList = this.getEnabledAttributes();

        var oldAttrValues = {};
        for (var a = 0; a < attributeNameList.length; a++) {
            var name = attributeNameList[a];
            oldAttrValues[name] = attributes[name].value;
            attributes[name].init(this.indices.length);
        }

        var cursor = 0;
        for (var i = 0; i < indices.length; i++) {
            var ii = indices[i];
            for (var a = 0; a < attributeNameList.length; a++) {
                var name = attributeNameList[a];
                var array = attributes[name].value;
                var size = attributes[name].size;

                for (var k = 0; k < size; k++) {
                    array[cursor * size + k] = oldAttrValues[name][ii * size + k];
                }
            }
            indices[i] = cursor;
            cursor++;
        }

        this.dirty();
    },

    /**
     * Generate barycentric coordinates for wireframe draw.
     */
    generateBarycentric: function () {
        if (!this.vertexCount) {
            return;
        }

        if (!this.isUniqueVertex()) {
            this.generateUniqueVertex();
        }

        var attributes = this.attributes;
        var array = attributes.barycentric.value;
        var indices = this.indices;
        // Already existed;
        if (array && array.length === indices.length * 3) {
            return;
        }
        array = attributes.barycentric.value = new Float32Array(indices.length * 3);

        for (var i = 0; i < (indices ? indices.length : this.vertexCount / 3);) {
            for (var j = 0; j < 3; j++) {
                var ii = indices ? indices[i++] : (i * 3 + j);
                array[ii * 3 + j] = 1;
            }
        }
        this.dirty();
    },

    /**
     * Apply transform to geometry attributes.
     * @param {clay.Matrix4} matrix
     */
    applyTransform: function (matrix) {

        var attributes = this.attributes;
        var positions = attributes.position.value;
        var normals = attributes.normal.value;
        var tangents = attributes.tangent.value;

        matrix = matrix.array;
        // Normal Matrix
        var inverseTransposeMatrix = __WEBPACK_IMPORTED_MODULE_2__glmatrix_mat4__["a" /* default */].create();
        __WEBPACK_IMPORTED_MODULE_2__glmatrix_mat4__["a" /* default */].invert(inverseTransposeMatrix, matrix);
        __WEBPACK_IMPORTED_MODULE_2__glmatrix_mat4__["a" /* default */].transpose(inverseTransposeMatrix, inverseTransposeMatrix);

        var vec3TransformMat4 = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].transformMat4;
        var vec3ForEach = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].forEach;
        vec3ForEach(positions, 3, 0, null, vec3TransformMat4, matrix);
        if (normals) {
            vec3ForEach(normals, 3, 0, null, vec3TransformMat4, inverseTransposeMatrix);
        }
        if (tangents) {
            vec3ForEach(tangents, 4, 0, null, vec3TransformMat4, inverseTransposeMatrix);
        }

        if (this.boundingBox) {
            this.updateBoundingBox();
        }
    },
    /**
     * Dispose geometry data in GL context.
     * @param {clay.Renderer} renderer
     */
    dispose: function (renderer) {

        var cache = this._cache;

        cache.use(renderer.__uid__);
        var chunks = cache.get('chunks');
        if (chunks) {
            for (var c = 0; c < chunks.length; c++) {
                var chunk = chunks[c];

                for (var k = 0; k < chunk.attributeBuffers.length; k++) {
                    var attribs = chunk.attributeBuffers[k];
                    renderer.gl.deleteBuffer(attribs.buffer);
                }

                if (chunk.indicesBuffer) {
                    renderer.gl.deleteBuffer(chunk.indicesBuffer.buffer);
                }
            }
        }
        if (this.__vaoCache) {
            var vaoExt = renderer.getGLExtension('OES_vertex_array_object');
            for (var id in this.__vaoCache) {
                var vao = this.__vaoCache[id].vao;
                if (vao) {
                    vaoExt.deleteVertexArrayOES(vao);
                }
            }
        }
        this.__vaoCache = {};
        cache.deleteContext(renderer.__uid__);
    }

});

Geometry.STATIC_DRAW = __WEBPACK_IMPORTED_MODULE_4__GeometryBase__["a" /* default */].STATIC_DRAW;
Geometry.DYNAMIC_DRAW = __WEBPACK_IMPORTED_MODULE_4__GeometryBase__["a" /* default */].DYNAMIC_DRAW;
Geometry.STREAM_DRAW = __WEBPACK_IMPORTED_MODULE_4__GeometryBase__["a" /* default */].STREAM_DRAW;

Geometry.AttributeBuffer = __WEBPACK_IMPORTED_MODULE_4__GeometryBase__["a" /* default */].AttributeBuffer;
Geometry.IndicesBuffer = __WEBPACK_IMPORTED_MODULE_4__GeometryBase__["a" /* default */].IndicesBuffer;

Geometry.Attribute = Attribute;

/* harmony default export */ __webpack_exports__["a"] = (Geometry);


/***/ }),
/* 16 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__camera_Orthographic__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__geometry_Plane__ = __webpack_require__(43);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Material__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Mesh__ = __webpack_require__(40);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__shader_source_compositor_vertex_glsl_js__ = __webpack_require__(126);









__WEBPACK_IMPORTED_MODULE_3__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_7__shader_source_compositor_vertex_glsl_js__["a" /* default */]);

var planeGeo = new __WEBPACK_IMPORTED_MODULE_2__geometry_Plane__["a" /* default */]();
var mesh = new __WEBPACK_IMPORTED_MODULE_5__Mesh__["a" /* default */]({
    geometry: planeGeo,
    frustumCulling: false
});
var camera = new __WEBPACK_IMPORTED_MODULE_1__camera_Orthographic__["a" /* default */]();

/**
 * @constructor clay.compositor.Pass
 * @extends clay.core.Base
 */
var Pass = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
    return /** @lends clay.compositor.Pass# */ {
        /**
         * Fragment shader string
         * @type {string}
         */
        // PENDING shader or fragment ?
        fragment: '',

        /**
         * @type {Object}
         */
        outputs: null,

        /**
         * @type {clay.Material}
         */
        material: null,

        /**
         * @type {Boolean}
         */
        blendWithPrevious: false,

        /**
         * @type {Boolean}
         */
        clearColor: false,

        /**
         * @type {Boolean}
         */
        clearDepth: true
    };
}, function() {

    var shader = new __WEBPACK_IMPORTED_MODULE_3__Shader__["a" /* default */](__WEBPACK_IMPORTED_MODULE_3__Shader__["a" /* default */].source('clay.compositor.vertex'), this.fragment);
    var material = new __WEBPACK_IMPORTED_MODULE_4__Material__["a" /* default */]({
        shader: shader
    });
    material.enableTexturesAll();

    this.material = material;

},
/** @lends clay.compositor.Pass.prototype */
{
    /**
     * @param {string} name
     * @param {} value
     */
    setUniform: function(name, value) {
        this.material.setUniform(name, value);
    },
    /**
     * @param  {string} name
     * @return {}
     */
    getUniform: function(name) {
        var uniform = this.material.uniforms[name];
        if (uniform) {
            return uniform.value;
        }
    },
    /**
     * @param  {clay.Texture} texture
     * @param  {number} attachment
     */
    attachOutput: function(texture, attachment) {
        if (!this.outputs) {
            this.outputs = {};
        }
        attachment = attachment || __WEBPACK_IMPORTED_MODULE_6__core_glenum__["a" /* default */].COLOR_ATTACHMENT0;
        this.outputs[attachment] = texture;
    },
    /**
     * @param  {clay.Texture} texture
     */
    detachOutput: function(texture) {
        for (var attachment in this.outputs) {
            if (this.outputs[attachment] === texture) {
                this.outputs[attachment] = null;
            }
        }
    },

    bind: function(renderer, frameBuffer) {

        if (this.outputs) {
            for (var attachment in this.outputs) {
                var texture = this.outputs[attachment];
                if (texture) {
                    frameBuffer.attach(texture, attachment);
                }
            }
        }

        if (frameBuffer) {
            frameBuffer.bind(renderer);
        }
    },

    unbind: function(renderer, frameBuffer) {
        frameBuffer.unbind(renderer);
    },
    /**
     * @param  {clay.Renderer} renderer
     * @param  {clay.FrameBuffer} [frameBuffer]
     */
    render: function(renderer, frameBuffer) {

        var _gl = renderer.gl;

        if (frameBuffer) {
            this.bind(renderer, frameBuffer);
            // MRT Support in chrome
            // https://www.khronos.org/registry/webgl/sdk/tests/conformance/extensions/ext-draw-buffers.html
            var ext = renderer.getGLExtension('EXT_draw_buffers');
            if (ext && this.outputs) {
                var bufs = [];
                for (var attachment in this.outputs) {
                    attachment = +attachment;
                    if (attachment >= _gl.COLOR_ATTACHMENT0 && attachment <= _gl.COLOR_ATTACHMENT0 + 8) {
                        bufs.push(attachment);
                    }
                }
                ext.drawBuffersEXT(bufs);
            }
        }

        this.trigger('beforerender', this, renderer);

        // FIXME Don't clear in each pass in default, let the color overwrite the buffer
        // FIXME pixels may be discard
        var clearBit = this.clearDepth ? _gl.DEPTH_BUFFER_BIT : 0;
        _gl.depthMask(true);
        if (this.clearColor) {
            clearBit = clearBit | _gl.COLOR_BUFFER_BIT;
            _gl.colorMask(true, true, true, true);
            var cc = this.clearColor;
            if (Array.isArray(cc)) {
                _gl.clearColor(cc[0], cc[1], cc[2], cc[3]);
            }
        }
        _gl.clear(clearBit);

        if (this.blendWithPrevious) {
            // Blend with previous rendered scene in the final output
            // FIXME Configure blend.
            // FIXME It will cause screen blink？
            _gl.enable(_gl.BLEND);
            this.material.transparent = true;
        }
        else {
            _gl.disable(_gl.BLEND);
            this.material.transparent = false;
        }

        this.renderQuad(renderer);

        this.trigger('afterrender', this, renderer);

        if (frameBuffer) {
            this.unbind(renderer, frameBuffer);
        }
    },

    /**
     * Simply do quad rendering
     */
    renderQuad: function (renderer) {
        mesh.material = this.material;
        renderer.renderPass([mesh], camera);
    },

    /**
     * @param  {clay.Renderer} renderer
     */
    dispose: function (renderer) {}
});

/* harmony default export */ __webpack_exports__["a"] = (Pass);


/***/ }),
/* 17 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = (function (seriesType, ecModel, api) {
    return {
        seriesType: seriesType,
        reset: function (seriesModel, ecModel) {
            var data = seriesModel.getData();
            var opacityAccessPath = seriesModel.visualColorAccessPath.split('.');
            opacityAccessPath[opacityAccessPath.length - 1] ='opacity';

            var opacity = seriesModel.get(opacityAccessPath);

            data.setVisual('opacity', opacity == null ? 1 : opacity);

            function dataEach(data, idx) {
                var itemModel = data.getItemModel(idx);
                var opacity = itemModel.get(opacityAccessPath, true);
                if (opacity != null) {
                    data.setItemVisual(idx, 'opacity', opacity);
                }
            }

            return {
                dataEach: data.hasItemOption ? dataEach : null
            };
        }
    };
});

/***/ }),
/* 18 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__ = __webpack_require__(12);



var vec3Set = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].set;
var vec3Copy = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].copy;

/**
 * Axis aligned bounding box
 * @constructor
 * @alias clay.BoundingBox
 * @param {clay.Vector3} [min]
 * @param {clay.Vector3} [max]
 */
var BoundingBox = function (min, max) {

    /**
     * Minimum coords of bounding box
     * @type {clay.Vector3}
     */
    this.min = min || new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */](Infinity, Infinity, Infinity);

    /**
     * Maximum coords of bounding box
     * @type {clay.Vector3}
     */
    this.max = max || new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */](-Infinity, -Infinity, -Infinity);

    this.vertices = null;
};

BoundingBox.prototype = {

    constructor: BoundingBox,
    /**
     * Update min and max coords from a vertices array
     * @param  {array} vertices
     */
    updateFromVertices: function (vertices) {
        if (vertices.length > 0) {
            var min = this.min;
            var max = this.max;
            var minArr = min.array;
            var maxArr = max.array;
            vec3Copy(minArr, vertices[0]);
            vec3Copy(maxArr, vertices[0]);
            for (var i = 1; i < vertices.length; i++) {
                var vertex = vertices[i];

                if (vertex[0] < minArr[0]) { minArr[0] = vertex[0]; }
                if (vertex[1] < minArr[1]) { minArr[1] = vertex[1]; }
                if (vertex[2] < minArr[2]) { minArr[2] = vertex[2]; }

                if (vertex[0] > maxArr[0]) { maxArr[0] = vertex[0]; }
                if (vertex[1] > maxArr[1]) { maxArr[1] = vertex[1]; }
                if (vertex[2] > maxArr[2]) { maxArr[2] = vertex[2]; }
            }
            min._dirty = true;
            max._dirty = true;
        }
    },

    /**
     * Union operation with another bounding box
     * @param  {clay.BoundingBox} bbox
     */
    union: function (bbox) {
        var min = this.min;
        var max = this.max;
        __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].min(min.array, min.array, bbox.min.array);
        __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].max(max.array, max.array, bbox.max.array);
        min._dirty = true;
        max._dirty = true;
        return this;
    },

    /**
     * Intersection operation with another bounding box
     * @param  {clay.BoundingBox} bbox
     */
    intersection: function (bbox) {
        var min = this.min;
        var max = this.max;
        __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].max(min.array, min.array, bbox.min.array);
        __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].min(max.array, max.array, bbox.max.array);
        min._dirty = true;
        max._dirty = true;
        return this;
    },

    /**
     * If intersect with another bounding box
     * @param  {clay.BoundingBox} bbox
     * @return {boolean}
     */
    intersectBoundingBox: function (bbox) {
        var _min = this.min.array;
        var _max = this.max.array;

        var _min2 = bbox.min.array;
        var _max2 = bbox.max.array;

        return ! (_min[0] > _max2[0] || _min[1] > _max2[1] || _min[2] > _max2[2]
            || _max[0] < _min2[0] || _max[1] < _min2[1] || _max[2] < _min2[2]);
    },

    /**
     * If contain another bounding box entirely
     * @param  {clay.BoundingBox} bbox
     * @return {boolean}
     */
    containBoundingBox: function (bbox) {

        var _min = this.min.array;
        var _max = this.max.array;

        var _min2 = bbox.min.array;
        var _max2 = bbox.max.array;

        return _min[0] <= _min2[0] && _min[1] <= _min2[1] && _min[2] <= _min2[2]
            && _max[0] >= _max2[0] && _max[1] >= _max2[1] && _max[2] >= _max2[2];
    },

    /**
     * If contain point entirely
     * @param  {clay.Vector3} point
     * @return {boolean}
     */
    containPoint: function (p) {
        var _min = this.min.array;
        var _max = this.max.array;

        var _p = p.array;

        return _min[0] <= _p[0] && _min[1] <= _p[1] && _min[2] <= _p[2]
            && _max[0] >= _p[0] && _max[1] >= _p[1] && _max[2] >= _p[2];
    },

    /**
     * If bounding box is finite
     */
    isFinite: function () {
        var _min = this.min.array;
        var _max = this.max.array;
        return isFinite(_min[0]) && isFinite(_min[1]) && isFinite(_min[2])
            && isFinite(_max[0]) && isFinite(_max[1]) && isFinite(_max[2]);
    },

    /**
     * Apply an affine transform matrix to the bounding box
     * @param  {clay.Matrix4} matrix
     */
    applyTransform: function (matrix) {
        this.transformFrom(this, matrix);
    },

    /**
     * Get from another bounding box and an affine transform matrix.
     * @param {clay.BoundingBox} source
     * @param {clay.Matrix4} matrix
     */
    transformFrom: (function () {
        // http://dev.theomader.com/transform-bounding-boxes/
        var xa = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();
        var xb = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();
        var ya = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();
        var yb = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();
        var za = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();
        var zb = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();

        return function (source, matrix) {
            var min = source.min.array;
            var max = source.max.array;

            var m = matrix.array;

            xa[0] = m[0] * min[0]; xa[1] = m[1] * min[0]; xa[2] = m[2] * min[0];
            xb[0] = m[0] * max[0]; xb[1] = m[1] * max[0]; xb[2] = m[2] * max[0];

            ya[0] = m[4] * min[1]; ya[1] = m[5] * min[1]; ya[2] = m[6] * min[1];
            yb[0] = m[4] * max[1]; yb[1] = m[5] * max[1]; yb[2] = m[6] * max[1];

            za[0] = m[8] * min[2]; za[1] = m[9] * min[2]; za[2] = m[10] * min[2];
            zb[0] = m[8] * max[2]; zb[1] = m[9] * max[2]; zb[2] = m[10] * max[2];

            min = this.min.array;
            max = this.max.array;
            min[0] = Math.min(xa[0], xb[0]) + Math.min(ya[0], yb[0]) + Math.min(za[0], zb[0]) + m[12];
            min[1] = Math.min(xa[1], xb[1]) + Math.min(ya[1], yb[1]) + Math.min(za[1], zb[1]) + m[13];
            min[2] = Math.min(xa[2], xb[2]) + Math.min(ya[2], yb[2]) + Math.min(za[2], zb[2]) + m[14];

            max[0] = Math.max(xa[0], xb[0]) + Math.max(ya[0], yb[0]) + Math.max(za[0], zb[0]) + m[12];
            max[1] = Math.max(xa[1], xb[1]) + Math.max(ya[1], yb[1]) + Math.max(za[1], zb[1]) + m[13];
            max[2] = Math.max(xa[2], xb[2]) + Math.max(ya[2], yb[2]) + Math.max(za[2], zb[2]) + m[14];

            this.min._dirty = true;
            this.max._dirty = true;

            return this;
        };
    })(),

    /**
     * Apply a projection matrix to the bounding box
     * @param  {clay.Matrix4} matrix
     */
    applyProjection: function (matrix) {
        var min = this.min.array;
        var max = this.max.array;

        var m = matrix.array;
        // min in min z
        var v10 = min[0];
        var v11 = min[1];
        var v12 = min[2];
        // max in min z
        var v20 = max[0];
        var v21 = max[1];
        var v22 = min[2];
        // max in max z
        var v30 = max[0];
        var v31 = max[1];
        var v32 = max[2];

        if (m[15] === 1) {  // Orthographic projection
            min[0] = m[0] * v10 + m[12];
            min[1] = m[5] * v11 + m[13];
            max[2] = m[10] * v12 + m[14];

            max[0] = m[0] * v30 + m[12];
            max[1] = m[5] * v31 + m[13];
            min[2] = m[10] * v32 + m[14];
        }
        else {
            var w = -1 / v12;
            min[0] = m[0] * v10 * w;
            min[1] = m[5] * v11 * w;
            max[2] = (m[10] * v12 + m[14]) * w;

            w = -1 / v22;
            max[0] = m[0] * v20 * w;
            max[1] = m[5] * v21 * w;

            w = -1 / v32;
            min[2] = (m[10] * v32 + m[14]) * w;
        }
        this.min._dirty = true;
        this.max._dirty = true;

        return this;
    },

    updateVertices: function () {
        var vertices = this.vertices;
        if (!vertices) {
            // Cube vertices
            vertices = [];
            for (var i = 0; i < 8; i++) {
                vertices[i] = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].fromValues(0, 0, 0);
            }

            /**
             * Eight coords of bounding box
             * @type {Float32Array[]}
             */
            this.vertices = vertices;
        }
        var min = this.min.array;
        var max = this.max.array;
        //--- min z
        // min x
        vec3Set(vertices[0], min[0], min[1], min[2]);
        vec3Set(vertices[1], min[0], max[1], min[2]);
        // max x
        vec3Set(vertices[2], max[0], min[1], min[2]);
        vec3Set(vertices[3], max[0], max[1], min[2]);

        //-- max z
        vec3Set(vertices[4], min[0], min[1], max[2]);
        vec3Set(vertices[5], min[0], max[1], max[2]);
        vec3Set(vertices[6], max[0], min[1], max[2]);
        vec3Set(vertices[7], max[0], max[1], max[2]);

        return this;
    },
    /**
     * Copy values from another bounding box
     * @param  {clay.BoundingBox} bbox
     */
    copy: function (bbox) {
        var min = this.min;
        var max = this.max;
        vec3Copy(min.array, bbox.min.array);
        vec3Copy(max.array, bbox.max.array);
        min._dirty = true;
        max._dirty = true;
        return this;
    },

    /**
     * Clone a new bounding box
     * @return {clay.BoundingBox}
     */
    clone: function () {
        var boundingBox = new BoundingBox();
        boundingBox.copy(this);
        return boundingBox;
    }
};

/* harmony default export */ __webpack_exports__["a"] = (BoundingBox);


/***/ }),
/* 19 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_util__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_color__ = __webpack_require__(113);



var parseColor = __WEBPACK_IMPORTED_MODULE_2__core_color__["a" /* default */].parseToFloat;

var programKeyCache = {};

function getDefineCode(defines) {
    var defineKeys = Object.keys(defines);
    defineKeys.sort();
    var defineStr = [];
    // Custom Defines
    for (var i = 0; i < defineKeys.length; i++) {
        var key = defineKeys[i];
        var value = defines[key];
        if (value === null) {
            defineStr.push(key);
        }
        else{
            defineStr.push(key + ' ' + value.toString());
        }
    }
    return defineStr.join('\n');
}

function getProgramKey(vertexDefines, fragmentDefines, enabledTextures) {
    enabledTextures.sort();
    var defineStr = [];
    for (var i = 0; i < enabledTextures.length; i++) {
        var symbol = enabledTextures[i];
        defineStr.push(symbol);
    }
    var key = getDefineCode(vertexDefines) + '\n'
        + getDefineCode(fragmentDefines) + '\n'
        + defineStr.join('\n');

    if (programKeyCache[key]) {
        return programKeyCache[key];
    }

    var id = __WEBPACK_IMPORTED_MODULE_1__core_util__["a" /* default */].genGUID();
    programKeyCache[key] = id;
    return id;
}

/**
 * Material defines the appearance of mesh surface, like `color`, `roughness`, `metalness`, etc.
 * It contains a {@link clay.Shader} and corresponding uniforms.
 *
 * Here is a basic example to create a standard material
```js
var material = new clay.Material({
    shader: new clay.Shader(
        clay.Shader.source('clay.vertex'),
        clay.Shader.source('clay.fragment')
    )
});
```
 * @constructor clay.Material
 * @extends clay.core.Base
 */
var Material = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
    return /** @lends clay.Material# */ {
        /**
         * @type {string}
         */
        name: '',

        /**
         * @type {Object}
         */
        // uniforms: null,

        /**
         * @type {clay.Shader}
         */
        // shader: null,

        /**
         * @type {boolean}
         */
        depthTest: true,

        /**
         * @type {boolean}
         */
        depthMask: true,

        /**
         * @type {boolean}
         */
        transparent: false,
        /**
         * Blend func is a callback function when the material
         * have custom blending
         * The gl context will be the only argument passed in tho the
         * blend function
         * Detail of blend function in WebGL:
         * http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf
         *
         * Example :
         * function(_gl) {
         *  _gl.blendEquation(_gl.FUNC_ADD);
         *  _gl.blendFunc(_gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA);
         * }
         */
        blend: null,

        /**
         * If update texture status automatically.
         */
        autoUpdateTextureStatus: true,

        uniforms: {},
        vertexDefines: {},
        fragmentDefines: {},
        _textureStatus: {},

        // shadowTransparentMap : null

        // PENDING enable the uniform that only used in shader.
        _enabledUniforms: null,
    };
}, function () {
    if (!this.name) {
        this.name = 'MATERIAL_' + this.__uid__;
    }

    if (this.shader) {
        // Keep status, mainly preset uniforms, vertexDefines and fragmentDefines
        this.attachShader(this.shader, true);
    }
},
/** @lends clay.Material.prototype */
{
    precision: 'highp',

    /**
     * Set material uniform
     * @example
     *  mat.setUniform('color', [1, 1, 1, 1]);
     * @param {string} symbol
     * @param {number|array|clay.Texture|ArrayBufferView} value
     */
    setUniform: function (symbol, value) {
        if (value === undefined) {
            console.warn('Uniform value "' + symbol + '" is undefined');
        }
        var uniform = this.uniforms[symbol];
        if (uniform) {

            if (typeof value === 'string') {
                // Try to parse as a color. Invalid color string will return null.
                value = parseColor(value) || value;
            }

            uniform.value = value;

            if (this.autoUpdateTextureStatus && uniform.type === 't') {
                if (value) {
                    this.enableTexture(symbol);
                }
                else {
                    this.disableTexture(symbol);
                }
            }
        }
    },

    /**
     * @param {Object} obj
     */
    setUniforms: function(obj) {
        for (var key in obj) {
            var val = obj[key];
            this.setUniform(key, val);
        }
    },

    /**
     * @param  {string}  symbol
     * @return {boolean}
     */
    isUniformEnabled: function (symbol) {
        return this._enabledUniforms.indexOf(symbol) >= 0;
    },

    getEnabledUniforms: function () {
        return this._enabledUniforms;
    },
    getTextureUniforms: function () {
        return this._textureUniforms;
    },

    /**
     * Alias of setUniform and setUniforms
     * @param {object|string} symbol
     * @param {number|array|clay.Texture|ArrayBufferView} [value]
     */
    set: function (symbol, value) {
        if (typeof(symbol) === 'object') {
            for (var key in symbol) {
                var val = symbol[key];
                this.setUniform(key, val);
            }
        }
        else {
            this.setUniform(symbol, value);
        }
    },
    /**
     * Get uniform value
     * @param  {string} symbol
     * @return {number|array|clay.Texture|ArrayBufferView}
     */
    get: function (symbol) {
        var uniform = this.uniforms[symbol];
        if (uniform) {
            return uniform.value;
        }
    },
    /**
     * Attach a shader instance
     * @param  {clay.Shader} shader
     * @param  {boolean} keepStatus If try to keep uniform and texture
     */
    attachShader: function(shader, keepStatus) {
        var originalUniforms = this.uniforms;

        // Ignore if uniform can use in shader.
        this.uniforms = shader.createUniforms();
        this.shader = shader;

        var uniforms = this.uniforms;
        this._enabledUniforms = Object.keys(uniforms);
        // Make sure uniforms are set in same order to avoid texture slot wrong
        this._enabledUniforms.sort();
        this._textureUniforms = this._enabledUniforms.filter(function (uniformName) {
            var type = this.uniforms[uniformName].type;
            return type === 't' || type === 'tv';
        }, this);

        var originalVertexDefines = this.vertexDefines;
        var originalFragmentDefines = this.fragmentDefines;

        this.vertexDefines = __WEBPACK_IMPORTED_MODULE_1__core_util__["a" /* default */].clone(shader.vertexDefines);
        this.fragmentDefines = __WEBPACK_IMPORTED_MODULE_1__core_util__["a" /* default */].clone(shader.fragmentDefines);

        if (keepStatus) {
            for (var symbol in originalUniforms) {
                if (uniforms[symbol]) {
                    uniforms[symbol].value = originalUniforms[symbol].value;
                }
            }

            __WEBPACK_IMPORTED_MODULE_1__core_util__["a" /* default */].defaults(this.vertexDefines, originalVertexDefines);
            __WEBPACK_IMPORTED_MODULE_1__core_util__["a" /* default */].defaults(this.fragmentDefines, originalFragmentDefines);
        }

        var textureStatus = {};
        for (var key in shader.textures) {
            textureStatus[key] = {
                shaderType: shader.textures[key].shaderType,
                type: shader.textures[key].type,
                enabled: (keepStatus && this._textureStatus[key]) ? this._textureStatus[key].enabled : false
            };
        }

        this._textureStatus = textureStatus;

        this._programKey = '';
    },

    /**
     * Clone a new material and keep uniforms, shader will not be cloned
     * @return {clay.Material}
     */
    clone: function () {
        var material = new this.constructor({
            name: this.name,
            shader: this.shader
        });
        for (var symbol in this.uniforms) {
            material.uniforms[symbol].value = this.uniforms[symbol].value;
        }
        material.depthTest = this.depthTest;
        material.depthMask = this.depthMask;
        material.transparent = this.transparent;
        material.blend = this.blend;

        material.vertexDefines = __WEBPACK_IMPORTED_MODULE_1__core_util__["a" /* default */].clone(this.vertexDefines);
        material.fragmentDefines = __WEBPACK_IMPORTED_MODULE_1__core_util__["a" /* default */].clone(this.fragmentDefines);
        material.enableTexture(this.getEnabledTextures());
        material.precision = this.precision;

        return material;
    },

    /**
     * Add a #define macro in shader code
     * @param  {string} shaderType Can be vertex, fragment or both
     * @param  {string} symbol
     * @param  {number} [val]
     */
    define: function (shaderType, symbol, val) {
        var vertexDefines = this.vertexDefines;
        var fragmentDefines = this.fragmentDefines;
        if (shaderType !== 'vertex' && shaderType !== 'fragment' && shaderType !== 'both'
            && arguments.length < 3
        ) {
            // shaderType default to be 'both'
            val = symbol;
            symbol = shaderType;
            shaderType = 'both';
        }
        val = val != null ? val : null;
        if (shaderType === 'vertex' || shaderType === 'both') {
            if (vertexDefines[symbol] !== val) {
                vertexDefines[symbol] = val;
                // Mark as dirty
                this._programKey = '';
            }
        }
        if (shaderType === 'fragment' || shaderType === 'both') {
            if (fragmentDefines[symbol] !== val) {
                fragmentDefines[symbol] = val;
                if (shaderType !== 'both') {
                    this._programKey = '';
                }
            }
        }
    },

    /**
     * Remove a #define macro in shader code
     * @param  {string} shaderType Can be vertex, fragment or both
     * @param  {string} symbol
     */
    undefine: function (shaderType, symbol) {
        if (shaderType !== 'vertex' && shaderType !== 'fragment' && shaderType !== 'both'
            && arguments.length < 2
        ) {
            // shaderType default to be 'both'
            symbol = shaderType;
            shaderType = 'both';
        }
        if (shaderType === 'vertex' || shaderType === 'both') {
            if (this.isDefined('vertex', symbol)) {
                delete this.vertexDefines[symbol];
                // Mark as dirty
                this._programKey = '';
            }
        }
        if (shaderType === 'fragment' || shaderType === 'both') {
            if (this.isDefined('fragment', symbol)) {
                delete this.fragmentDefines[symbol];
                if (shaderType !== 'both') {
                    this._programKey = '';
                }
            }
        }
    },

    /**
     * If macro is defined in shader.
     * @param  {string} shaderType Can be vertex, fragment or both
     * @param  {string} symbol
     */
    isDefined: function (shaderType, symbol) {
        // PENDING hasOwnProperty ?
        switch (shaderType) {
            case 'vertex':
                return this.vertexDefines[symbol] !== undefined;
            case 'fragment':
                return this.fragmentDefines[symbol] !== undefined;
        }
    },
    /**
     * Get macro value defined in shader.
     * @param  {string} shaderType Can be vertex, fragment or both
     * @param  {string} symbol
     */
    getDefine: function (shaderType, symbol) {
        switch(shaderType) {
            case 'vertex':
                return this.vertexDefines[symbol];
            case 'fragment':
                return this.fragmentDefines[symbol];
        }
    },
    /**
     * Enable a texture, actually it will add a #define macro in the shader code
     * For example, if texture symbol is diffuseMap, it will add a line `#define DIFFUSEMAP_ENABLED` in the shader code
     * @param  {string} symbol
     */
    enableTexture: function (symbol) {
        if (Array.isArray(symbol)) {
            for (var i = 0; i < symbol.length; i++) {
                this.enableTexture(symbol[i]);
            }
            return;
        }

        var status = this._textureStatus[symbol];
        if (status) {
            var isEnabled = status.enabled;
            if (!isEnabled) {
                status.enabled = true;
                this._programKey = '';
            }
        }
    },
    /**
     * Enable all textures used in the shader
     */
    enableTexturesAll: function () {
        var textureStatus = this._textureStatus;
        for (var symbol in textureStatus) {
            textureStatus[symbol].enabled = true;
        }

        this._programKey = '';
    },
    /**
     * Disable a texture, it remove a #define macro in the shader
     * @param  {string} symbol
     */
    disableTexture: function (symbol) {
        if (Array.isArray(symbol)) {
            for (var i = 0; i < symbol.length; i++) {
                this.disableTexture(symbol[i]);
            }
            return;
        }

        var status = this._textureStatus[symbol];
        if (status) {
            var isDisabled = ! status.enabled;
            if (!isDisabled) {
                status.enabled = false;
                this._programKey = '';
            }
        }
    },
    /**
     * Disable all textures used in the shader
     */
    disableTexturesAll: function () {
        var textureStatus = this._textureStatus;
        for (var symbol in textureStatus) {
            textureStatus[symbol].enabled = false;
        }

        this._programKey = '';
    },
    /**
     * If texture of given type is enabled.
     * @param  {string}  symbol
     * @return {boolean}
     */
    isTextureEnabled: function (symbol) {
        var textureStatus = this._textureStatus;
        return !!textureStatus[symbol]
            && textureStatus[symbol].enabled;
    },

    /**
     * Get all enabled textures
     * @return {string[]}
     */
    getEnabledTextures: function () {
        var enabledTextures = [];
        var textureStatus = this._textureStatus;
        for (var symbol in textureStatus) {
            if (textureStatus[symbol].enabled) {
                enabledTextures.push(symbol);
            }
        }
        return enabledTextures;
    },

    /**
     * Mark defines are updated.
     */
    dirtyDefines: function () {
        this._programKey = '';
    },

    getProgramKey: function () {
        if (!this._programKey) {
            this._programKey = getProgramKey(
                this.vertexDefines, this.fragmentDefines, this.getEnabledTextures()
            );
        }
        return this._programKey;
    }
});

/* harmony default export */ __webpack_exports__["a"] = (Material);


/***/ }),
/* 20 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return GLMAT_EPSILON; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GLMAT_ARRAY_TYPE; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return GLMAT_RANDOM; });

var GLMAT_EPSILON = 0.000001;

// Use Array instead of Float32Array. It seems to be much faster and higher precision.
var GLMAT_ARRAY_TYPE = Array;
// if(!GLMAT_ARRAY_TYPE) {
//     GLMAT_ARRAY_TYPE = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
// }

var GLMAT_RANDOM = Math.random;


/***/ }),
/* 21 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common__ = __webpack_require__(20);

/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */



/**
 * @class 4x4 Matrix
 * @name mat4
 */

var mat4 = {};

/**
 * Creates a new identity mat4
 *
 * @returns {mat4} a new 4x4 matrix
 */
mat4.create = function() {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](16);
    out[0] = 1;
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
    out[4] = 0;
    out[5] = 1;
    out[6] = 0;
    out[7] = 0;
    out[8] = 0;
    out[9] = 0;
    out[10] = 1;
    out[11] = 0;
    out[12] = 0;
    out[13] = 0;
    out[14] = 0;
    out[15] = 1;
    return out;
};

/**
 * Creates a new mat4 initialized with values from an existing matrix
 *
 * @param {mat4} a matrix to clone
 * @returns {mat4} a new 4x4 matrix
 */
mat4.clone = function(a) {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](16);
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    out[4] = a[4];
    out[5] = a[5];
    out[6] = a[6];
    out[7] = a[7];
    out[8] = a[8];
    out[9] = a[9];
    out[10] = a[10];
    out[11] = a[11];
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
    return out;
};

/**
 * Copy the values from one mat4 to another
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the source matrix
 * @returns {mat4} out
 */
mat4.copy = function(out, a) {
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    out[4] = a[4];
    out[5] = a[5];
    out[6] = a[6];
    out[7] = a[7];
    out[8] = a[8];
    out[9] = a[9];
    out[10] = a[10];
    out[11] = a[11];
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
    return out;
};

/**
 * Set a mat4 to the identity matrix
 *
 * @param {mat4} out the receiving matrix
 * @returns {mat4} out
 */
mat4.identity = function(out) {
    out[0] = 1;
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
    out[4] = 0;
    out[5] = 1;
    out[6] = 0;
    out[7] = 0;
    out[8] = 0;
    out[9] = 0;
    out[10] = 1;
    out[11] = 0;
    out[12] = 0;
    out[13] = 0;
    out[14] = 0;
    out[15] = 1;
    return out;
};

/**
 * Transpose the values of a mat4
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the source matrix
 * @returns {mat4} out
 */
mat4.transpose = function(out, a) {
    // If we are transposing ourselves we can skip a few steps but have to cache some values
    if (out === a) {
        var a01 = a[1], a02 = a[2], a03 = a[3],
            a12 = a[6], a13 = a[7],
            a23 = a[11];

        out[1] = a[4];
        out[2] = a[8];
        out[3] = a[12];
        out[4] = a01;
        out[6] = a[9];
        out[7] = a[13];
        out[8] = a02;
        out[9] = a12;
        out[11] = a[14];
        out[12] = a03;
        out[13] = a13;
        out[14] = a23;
    } else {
        out[0] = a[0];
        out[1] = a[4];
        out[2] = a[8];
        out[3] = a[12];
        out[4] = a[1];
        out[5] = a[5];
        out[6] = a[9];
        out[7] = a[13];
        out[8] = a[2];
        out[9] = a[6];
        out[10] = a[10];
        out[11] = a[14];
        out[12] = a[3];
        out[13] = a[7];
        out[14] = a[11];
        out[15] = a[15];
    }

    return out;
};

/**
 * Inverts a mat4
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the source matrix
 * @returns {mat4} out
 */
mat4.invert = function(out, a) {
    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],

        b00 = a00 * a11 - a01 * a10,
        b01 = a00 * a12 - a02 * a10,
        b02 = a00 * a13 - a03 * a10,
        b03 = a01 * a12 - a02 * a11,
        b04 = a01 * a13 - a03 * a11,
        b05 = a02 * a13 - a03 * a12,
        b06 = a20 * a31 - a21 * a30,
        b07 = a20 * a32 - a22 * a30,
        b08 = a20 * a33 - a23 * a30,
        b09 = a21 * a32 - a22 * a31,
        b10 = a21 * a33 - a23 * a31,
        b11 = a22 * a33 - a23 * a32,

        // Calculate the determinant
        det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;

    if (!det) {
        return null;
    }
    det = 1.0 / det;

    out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
    out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
    out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
    out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
    out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
    out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
    out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
    out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
    out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
    out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
    out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
    out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
    out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
    out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
    out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
    out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;

    return out;
};

/**
 * Calculates the adjugate of a mat4
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the source matrix
 * @returns {mat4} out
 */
mat4.adjoint = function(out, a) {
    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];

    out[0]  =  (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22));
    out[1]  = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
    out[2]  =  (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12));
    out[3]  = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
    out[4]  = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
    out[5]  =  (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22));
    out[6]  = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
    out[7]  =  (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12));
    out[8]  =  (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21));
    out[9]  = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
    out[10] =  (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11));
    out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
    out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
    out[13] =  (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21));
    out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
    out[15] =  (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11));
    return out;
};

/**
 * Calculates the determinant of a mat4
 *
 * @param {mat4} a the source matrix
 * @returns {Number} determinant of a
 */
mat4.determinant = function (a) {
    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],

        b00 = a00 * a11 - a01 * a10,
        b01 = a00 * a12 - a02 * a10,
        b02 = a00 * a13 - a03 * a10,
        b03 = a01 * a12 - a02 * a11,
        b04 = a01 * a13 - a03 * a11,
        b05 = a02 * a13 - a03 * a12,
        b06 = a20 * a31 - a21 * a30,
        b07 = a20 * a32 - a22 * a30,
        b08 = a20 * a33 - a23 * a30,
        b09 = a21 * a32 - a22 * a31,
        b10 = a21 * a33 - a23 * a31,
        b11 = a22 * a33 - a23 * a32;

    // Calculate the determinant
    return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
};

/**
 * Multiplies two mat4's
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the first operand
 * @param {mat4} b the second operand
 * @returns {mat4} out
 */
mat4.multiply = function (out, a, b) {
    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];

    // Cache only the current line of the second matrix
    var b0  = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
    out[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
    out[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
    out[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
    out[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;

    b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7];
    out[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
    out[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
    out[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
    out[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;

    b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11];
    out[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
    out[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
    out[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
    out[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;

    b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15];
    out[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
    out[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
    out[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
    out[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
    return out;
};

/**
 * Multiplies two affine mat4's
 * Add by https://github.com/pissang
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the first operand
 * @param {mat4} b the second operand
 * @returns {mat4} out
 */
mat4.multiplyAffine = function (out, a, b) {
    var a00 = a[0], a01 = a[1], a02 = a[2],
        a10 = a[4], a11 = a[5], a12 = a[6],
        a20 = a[8], a21 = a[9], a22 = a[10],
        a30 = a[12], a31 = a[13], a32 = a[14];

    // Cache only the current line of the second matrix
    var b0  = b[0], b1 = b[1], b2 = b[2];
    out[0] = b0*a00 + b1*a10 + b2*a20;
    out[1] = b0*a01 + b1*a11 + b2*a21;
    out[2] = b0*a02 + b1*a12 + b2*a22;
    // out[3] = 0;

    b0 = b[4]; b1 = b[5]; b2 = b[6];
    out[4] = b0*a00 + b1*a10 + b2*a20;
    out[5] = b0*a01 + b1*a11 + b2*a21;
    out[6] = b0*a02 + b1*a12 + b2*a22;
    // out[7] = 0;

    b0 = b[8]; b1 = b[9]; b2 = b[10];
    out[8] = b0*a00 + b1*a10 + b2*a20;
    out[9] = b0*a01 + b1*a11 + b2*a21;
    out[10] = b0*a02 + b1*a12 + b2*a22;
    // out[11] = 0;

    b0 = b[12]; b1 = b[13]; b2 = b[14];
    out[12] = b0*a00 + b1*a10 + b2*a20 + a30;
    out[13] = b0*a01 + b1*a11 + b2*a21 + a31;
    out[14] = b0*a02 + b1*a12 + b2*a22 + a32;
    // out[15] = 1;
    return out;
};

/**
 * Alias for {@link mat4.multiply}
 * @function
 */
mat4.mul = mat4.multiply;

/**
 * Alias for {@link mat4.multiplyAffine}
 * @function
 */
mat4.mulAffine = mat4.multiplyAffine;
/**
 * Translate a mat4 by the given vector
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to translate
 * @param {vec3} v vector to translate by
 * @returns {mat4} out
 */
mat4.translate = function (out, a, v) {
    var x = v[0], y = v[1], z = v[2],
        a00, a01, a02, a03,
        a10, a11, a12, a13,
        a20, a21, a22, a23;

    if (a === out) {
        out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
        out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
        out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
        out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
    } else {
        a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
        a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
        a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];

        out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;
        out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;
        out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;

        out[12] = a00 * x + a10 * y + a20 * z + a[12];
        out[13] = a01 * x + a11 * y + a21 * z + a[13];
        out[14] = a02 * x + a12 * y + a22 * z + a[14];
        out[15] = a03 * x + a13 * y + a23 * z + a[15];
    }

    return out;
};

/**
 * Scales the mat4 by the dimensions in the given vec3
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to scale
 * @param {vec3} v the vec3 to scale the matrix by
 * @returns {mat4} out
 **/
mat4.scale = function(out, a, v) {
    var x = v[0], y = v[1], z = v[2];

    out[0] = a[0] * x;
    out[1] = a[1] * x;
    out[2] = a[2] * x;
    out[3] = a[3] * x;
    out[4] = a[4] * y;
    out[5] = a[5] * y;
    out[6] = a[6] * y;
    out[7] = a[7] * y;
    out[8] = a[8] * z;
    out[9] = a[9] * z;
    out[10] = a[10] * z;
    out[11] = a[11] * z;
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
    return out;
};

/**
 * Rotates a mat4 by the given angle
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @param {vec3} axis the axis to rotate around
 * @returns {mat4} out
 */
mat4.rotate = function (out, a, rad, axis) {
    var x = axis[0], y = axis[1], z = axis[2],
        len = Math.sqrt(x * x + y * y + z * z),
        s, c, t,
        a00, a01, a02, a03,
        a10, a11, a12, a13,
        a20, a21, a22, a23,
        b00, b01, b02,
        b10, b11, b12,
        b20, b21, b22;

    if (Math.abs(len) < __WEBPACK_IMPORTED_MODULE_0__common__["b" /* GLMAT_EPSILON */]) { return null; }

    len = 1 / len;
    x *= len;
    y *= len;
    z *= len;

    s = Math.sin(rad);
    c = Math.cos(rad);
    t = 1 - c;

    a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
    a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
    a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];

    // Construct the elements of the rotation matrix
    b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s;
    b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s;
    b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c;

    // Perform rotation-specific matrix multiplication
    out[0] = a00 * b00 + a10 * b01 + a20 * b02;
    out[1] = a01 * b00 + a11 * b01 + a21 * b02;
    out[2] = a02 * b00 + a12 * b01 + a22 * b02;
    out[3] = a03 * b00 + a13 * b01 + a23 * b02;
    out[4] = a00 * b10 + a10 * b11 + a20 * b12;
    out[5] = a01 * b10 + a11 * b11 + a21 * b12;
    out[6] = a02 * b10 + a12 * b11 + a22 * b12;
    out[7] = a03 * b10 + a13 * b11 + a23 * b12;
    out[8] = a00 * b20 + a10 * b21 + a20 * b22;
    out[9] = a01 * b20 + a11 * b21 + a21 * b22;
    out[10] = a02 * b20 + a12 * b21 + a22 * b22;
    out[11] = a03 * b20 + a13 * b21 + a23 * b22;

    if (a !== out) { // If the source and destination differ, copy the unchanged last row
        out[12] = a[12];
        out[13] = a[13];
        out[14] = a[14];
        out[15] = a[15];
    }
    return out;
};

/**
 * Rotates a matrix by the given angle around the X axis
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */
mat4.rotateX = function (out, a, rad) {
    var s = Math.sin(rad),
        c = Math.cos(rad),
        a10 = a[4],
        a11 = a[5],
        a12 = a[6],
        a13 = a[7],
        a20 = a[8],
        a21 = a[9],
        a22 = a[10],
        a23 = a[11];

    if (a !== out) { // If the source and destination differ, copy the unchanged rows
        out[0]  = a[0];
        out[1]  = a[1];
        out[2]  = a[2];
        out[3]  = a[3];
        out[12] = a[12];
        out[13] = a[13];
        out[14] = a[14];
        out[15] = a[15];
    }

    // Perform axis-specific matrix multiplication
    out[4] = a10 * c + a20 * s;
    out[5] = a11 * c + a21 * s;
    out[6] = a12 * c + a22 * s;
    out[7] = a13 * c + a23 * s;
    out[8] = a20 * c - a10 * s;
    out[9] = a21 * c - a11 * s;
    out[10] = a22 * c - a12 * s;
    out[11] = a23 * c - a13 * s;
    return out;
};

/**
 * Rotates a matrix by the given angle around the Y axis
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */
mat4.rotateY = function (out, a, rad) {
    var s = Math.sin(rad),
        c = Math.cos(rad),
        a00 = a[0],
        a01 = a[1],
        a02 = a[2],
        a03 = a[3],
        a20 = a[8],
        a21 = a[9],
        a22 = a[10],
        a23 = a[11];

    if (a !== out) { // If the source and destination differ, copy the unchanged rows
        out[4]  = a[4];
        out[5]  = a[5];
        out[6]  = a[6];
        out[7]  = a[7];
        out[12] = a[12];
        out[13] = a[13];
        out[14] = a[14];
        out[15] = a[15];
    }

    // Perform axis-specific matrix multiplication
    out[0] = a00 * c - a20 * s;
    out[1] = a01 * c - a21 * s;
    out[2] = a02 * c - a22 * s;
    out[3] = a03 * c - a23 * s;
    out[8] = a00 * s + a20 * c;
    out[9] = a01 * s + a21 * c;
    out[10] = a02 * s + a22 * c;
    out[11] = a03 * s + a23 * c;
    return out;
};

/**
 * Rotates a matrix by the given angle around the Z axis
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */
mat4.rotateZ = function (out, a, rad) {
    var s = Math.sin(rad),
        c = Math.cos(rad),
        a00 = a[0],
        a01 = a[1],
        a02 = a[2],
        a03 = a[3],
        a10 = a[4],
        a11 = a[5],
        a12 = a[6],
        a13 = a[7];

    if (a !== out) { // If the source and destination differ, copy the unchanged last row
        out[8]  = a[8];
        out[9]  = a[9];
        out[10] = a[10];
        out[11] = a[11];
        out[12] = a[12];
        out[13] = a[13];
        out[14] = a[14];
        out[15] = a[15];
    }

    // Perform axis-specific matrix multiplication
    out[0] = a00 * c + a10 * s;
    out[1] = a01 * c + a11 * s;
    out[2] = a02 * c + a12 * s;
    out[3] = a03 * c + a13 * s;
    out[4] = a10 * c - a00 * s;
    out[5] = a11 * c - a01 * s;
    out[6] = a12 * c - a02 * s;
    out[7] = a13 * c - a03 * s;
    return out;
};

/**
 * Creates a matrix from a quaternion rotation and vector translation
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.translate(dest, vec);
 *     var quatMat = mat4.create();
 *     quat4.toMat4(quat, quatMat);
 *     mat4.multiply(dest, quatMat);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {quat4} q Rotation quaternion
 * @param {vec3} v Translation vector
 * @returns {mat4} out
 */
mat4.fromRotationTranslation = function (out, q, v) {
    // Quaternion math
    var x = q[0], y = q[1], z = q[2], w = q[3],
        x2 = x + x,
        y2 = y + y,
        z2 = z + z,

        xx = x * x2,
        xy = x * y2,
        xz = x * z2,
        yy = y * y2,
        yz = y * z2,
        zz = z * z2,
        wx = w * x2,
        wy = w * y2,
        wz = w * z2;

    out[0] = 1 - (yy + zz);
    out[1] = xy + wz;
    out[2] = xz - wy;
    out[3] = 0;
    out[4] = xy - wz;
    out[5] = 1 - (xx + zz);
    out[6] = yz + wx;
    out[7] = 0;
    out[8] = xz + wy;
    out[9] = yz - wx;
    out[10] = 1 - (xx + yy);
    out[11] = 0;
    out[12] = v[0];
    out[13] = v[1];
    out[14] = v[2];
    out[15] = 1;

    return out;
};

mat4.fromQuat = function (out, q) {
    var x = q[0], y = q[1], z = q[2], w = q[3],
        x2 = x + x,
        y2 = y + y,
        z2 = z + z,

        xx = x * x2,
        yx = y * x2,
        yy = y * y2,
        zx = z * x2,
        zy = z * y2,
        zz = z * z2,
        wx = w * x2,
        wy = w * y2,
        wz = w * z2;

    out[0] = 1 - yy - zz;
    out[1] = yx + wz;
    out[2] = zx - wy;
    out[3] = 0;

    out[4] = yx - wz;
    out[5] = 1 - xx - zz;
    out[6] = zy + wx;
    out[7] = 0;

    out[8] = zx + wy;
    out[9] = zy - wx;
    out[10] = 1 - xx - yy;
    out[11] = 0;

    out[12] = 0;
    out[13] = 0;
    out[14] = 0;
    out[15] = 1;

    return out;
};

/**
 * Generates a frustum matrix with the given bounds
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {Number} left Left bound of the frustum
 * @param {Number} right Right bound of the frustum
 * @param {Number} bottom Bottom bound of the frustum
 * @param {Number} top Top bound of the frustum
 * @param {Number} near Near bound of the frustum
 * @param {Number} far Far bound of the frustum
 * @returns {mat4} out
 */
mat4.frustum = function (out, left, right, bottom, top, near, far) {
    var rl = 1 / (right - left),
        tb = 1 / (top - bottom),
        nf = 1 / (near - far);
    out[0] = (near * 2) * rl;
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
    out[4] = 0;
    out[5] = (near * 2) * tb;
    out[6] = 0;
    out[7] = 0;
    out[8] = (right + left) * rl;
    out[9] = (top + bottom) * tb;
    out[10] = (far + near) * nf;
    out[11] = -1;
    out[12] = 0;
    out[13] = 0;
    out[14] = (far * near * 2) * nf;
    out[15] = 0;
    return out;
};

/**
 * Generates a perspective projection matrix with the given bounds
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {number} fovy Vertical field of view in radians
 * @param {number} aspect Aspect ratio. typically viewport width/height
 * @param {number} near Near bound of the frustum
 * @param {number} far Far bound of the frustum
 * @returns {mat4} out
 */
mat4.perspective = function (out, fovy, aspect, near, far) {
    var f = 1.0 / Math.tan(fovy / 2),
        nf = 1 / (near - far);
    out[0] = f / aspect;
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
    out[4] = 0;
    out[5] = f;
    out[6] = 0;
    out[7] = 0;
    out[8] = 0;
    out[9] = 0;
    out[10] = (far + near) * nf;
    out[11] = -1;
    out[12] = 0;
    out[13] = 0;
    out[14] = (2 * far * near) * nf;
    out[15] = 0;
    return out;
};

/**
 * Generates a orthogonal projection matrix with the given bounds
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {number} left Left bound of the frustum
 * @param {number} right Right bound of the frustum
 * @param {number} bottom Bottom bound of the frustum
 * @param {number} top Top bound of the frustum
 * @param {number} near Near bound of the frustum
 * @param {number} far Far bound of the frustum
 * @returns {mat4} out
 */
mat4.ortho = function (out, left, right, bottom, top, near, far) {
    var lr = 1 / (left - right),
        bt = 1 / (bottom - top),
        nf = 1 / (near - far);
    out[0] = -2 * lr;
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
    out[4] = 0;
    out[5] = -2 * bt;
    out[6] = 0;
    out[7] = 0;
    out[8] = 0;
    out[9] = 0;
    out[10] = 2 * nf;
    out[11] = 0;
    out[12] = (left + right) * lr;
    out[13] = (top + bottom) * bt;
    out[14] = (far + near) * nf;
    out[15] = 1;
    return out;
};

/**
 * Generates a look-at matrix with the given eye position, focal point, and up axis
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {vec3} eye Position of the viewer
 * @param {vec3} center Point the viewer is looking at
 * @param {vec3} up vec3 pointing up
 * @returns {mat4} out
 */
mat4.lookAt = function (out, eye, center, up) {
    var x0, x1, x2, y0, y1, y2, z0, z1, z2, len,
        eyex = eye[0],
        eyey = eye[1],
        eyez = eye[2],
        upx = up[0],
        upy = up[1],
        upz = up[2],
        centerx = center[0],
        centery = center[1],
        centerz = center[2];

    if (Math.abs(eyex - centerx) < __WEBPACK_IMPORTED_MODULE_0__common__["b" /* GLMAT_EPSILON */] &&
        Math.abs(eyey - centery) < __WEBPACK_IMPORTED_MODULE_0__common__["b" /* GLMAT_EPSILON */] &&
        Math.abs(eyez - centerz) < __WEBPACK_IMPORTED_MODULE_0__common__["b" /* GLMAT_EPSILON */]) {
        return mat4.identity(out);
    }

    z0 = eyex - centerx;
    z1 = eyey - centery;
    z2 = eyez - centerz;

    len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
    z0 *= len;
    z1 *= len;
    z2 *= len;

    x0 = upy * z2 - upz * z1;
    x1 = upz * z0 - upx * z2;
    x2 = upx * z1 - upy * z0;
    len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
    if (!len) {
        x0 = 0;
        x1 = 0;
        x2 = 0;
    } else {
        len = 1 / len;
        x0 *= len;
        x1 *= len;
        x2 *= len;
    }

    y0 = z1 * x2 - z2 * x1;
    y1 = z2 * x0 - z0 * x2;
    y2 = z0 * x1 - z1 * x0;

    len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
    if (!len) {
        y0 = 0;
        y1 = 0;
        y2 = 0;
    } else {
        len = 1 / len;
        y0 *= len;
        y1 *= len;
        y2 *= len;
    }

    out[0] = x0;
    out[1] = y0;
    out[2] = z0;
    out[3] = 0;
    out[4] = x1;
    out[5] = y1;
    out[6] = z1;
    out[7] = 0;
    out[8] = x2;
    out[9] = y2;
    out[10] = z2;
    out[11] = 0;
    out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
    out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
    out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
    out[15] = 1;

    return out;
};

/**
 * Returns Frobenius norm of a mat4
 *
 * @param {mat4} a the matrix to calculate Frobenius norm of
 * @returns {Number} Frobenius norm
 */
mat4.frob = function (a) {
    return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2) + Math.pow(a[9], 2) + Math.pow(a[10], 2) + Math.pow(a[11], 2) + Math.pow(a[12], 2) + Math.pow(a[13], 2) + Math.pow(a[14], 2) + Math.pow(a[15], 2) ))
};

/* harmony default export */ __webpack_exports__["a"] = (mat4);

/***/ }),
/* 22 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Scene__ = __webpack_require__(36);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_prePass_ShadowMap__ = __webpack_require__(174);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_camera_Perspective__ = __webpack_require__(41);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_camera_Orthographic__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_claygl_src_math_Vector2__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_claygl_src_core_mixin_notifier__ = __webpack_require__(53);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__effect_EffectCompositor__ = __webpack_require__(176);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__effect_TemporalSuperSampling__ = __webpack_require__(200);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__effect_halton__ = __webpack_require__(49);
/*
 * @module echarts-gl/core/ViewGL
 * @author Yi Shen(http://github.com/pissang)
 */

















/**
 * @constructor
 * @alias module:echarts-gl/core/ViewGL
 * @param {string} [projection='perspective']
 */
function ViewGL(projection) {

    projection = projection || 'perspective';

    /**
     * @type {module:echarts-gl/core/LayerGL}
     */
    this.layer = null;
    /**
     * @type {clay.Scene}
     */
    this.scene = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Scene__["a" /* default */]();

    /**
     * @type {clay.Node}
     */
    this.rootNode = this.scene;

    this.viewport = {
        x: 0, y: 0, width: 0, height: 0
    };

    this.setProjection(projection);

    this._compositor = new __WEBPACK_IMPORTED_MODULE_9__effect_EffectCompositor__["a" /* default */]();

    this._temporalSS = new __WEBPACK_IMPORTED_MODULE_10__effect_TemporalSuperSampling__["a" /* default */]();

    this._shadowMapPass = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_prePass_ShadowMap__["a" /* default */]();

    var pcfKernels = [];
    var off = 0;
    for (var i = 0; i < 30; i++) {
        var pcfKernel = [];
        for (var k = 0; k < 6; k++) {
            pcfKernel.push(Object(__WEBPACK_IMPORTED_MODULE_11__effect_halton__["a" /* default */])(off, 2) * 4.0 - 2.0);
            pcfKernel.push(Object(__WEBPACK_IMPORTED_MODULE_11__effect_halton__["a" /* default */])(off, 3) * 4.0 - 2.0);
            off++;
        }
        pcfKernels.push(pcfKernel);
    }
    this._pcfKernels = pcfKernels;

    this.scene.on('beforerender', function (renderer, scene, camera) {
        if (this.needsTemporalSS()) {
            this._temporalSS.jitterProjection(renderer, camera);
        }
    }, this);
}

/**
 * Set camera type of group
 * @param {string} cameraType 'perspective' | 'orthographic'
 */
ViewGL.prototype.setProjection = function (projection) {
    var oldCamera = this.camera;
    oldCamera && oldCamera.update();
    if (projection === 'perspective') {
        if (!(this.camera instanceof __WEBPACK_IMPORTED_MODULE_3_claygl_src_camera_Perspective__["a" /* default */])) {
            this.camera = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_camera_Perspective__["a" /* default */]();
            if (oldCamera) {
                this.camera.setLocalTransform(oldCamera.localTransform);
            }
        }
    }
    else {
        if (!(this.camera instanceof __WEBPACK_IMPORTED_MODULE_4_claygl_src_camera_Orthographic__["a" /* default */])) {
            this.camera = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_camera_Orthographic__["a" /* default */]();
            if (oldCamera) {
                this.camera.setLocalTransform(oldCamera.localTransform);
            }
        }
    }
    // PENDING
    this.camera.near = 0.1;
    this.camera.far = 2000;
};

/**
 * Set viewport of group
 * @param {number} x Viewport left bottom x
 * @param {number} y Viewport left bottom y
 * @param {number} width Viewport height
 * @param {number} height Viewport height
 * @param {number} [dpr=1]
 */
ViewGL.prototype.setViewport = function (x, y, width, height, dpr) {
    if (this.camera instanceof __WEBPACK_IMPORTED_MODULE_3_claygl_src_camera_Perspective__["a" /* default */]) {
        this.camera.aspect = width / height;
    }
    dpr = dpr || 1;

    this.viewport.x = x;
    this.viewport.y = y;
    this.viewport.width = width;
    this.viewport.height = height;
    this.viewport.devicePixelRatio = dpr;

    // Source and output of compositor use high dpr texture.
    // But the intermediate texture of bloom, dof effects use fixed 1.0 dpr
    this._compositor.resize(width * dpr, height * dpr);
    this._temporalSS.resize(width * dpr, height * dpr);
};

/**
 * If contain screen point x, y
 * @param {number} x offsetX
 * @param {number} y offsetY
 * @return {boolean}
 */
ViewGL.prototype.containPoint = function (x, y) {
    var viewport = this.viewport;
    var height = this.layer.renderer.getHeight();
    // Flip y;
    y = height - y;
    return x >= viewport.x && y >= viewport.y
        && x <= viewport.x + viewport.width && y <= viewport.y + viewport.height;
};

/**
 * Cast a ray
 * @param {number} x offsetX
 * @param {number} y offsetY
 * @param {clay.math.Ray} out
 * @return {clay.math.Ray}
 */
var ndc = new __WEBPACK_IMPORTED_MODULE_7_claygl_src_math_Vector2__["a" /* default */]();
ViewGL.prototype.castRay = function (x, y, out) {
    var renderer = this.layer.renderer;

    var oldViewport = renderer.viewport;
    renderer.viewport = this.viewport;
    renderer.screenToNDC(x, y, ndc);
    this.camera.castRay(ndc, out);
    renderer.viewport = oldViewport;

    return out;
};

/**
 * Prepare and update scene before render
 */
ViewGL.prototype.prepareRender = function () {
    this.scene.update();
    this.camera.update();
    this.scene.updateLights();
    var renderList = this.scene.updateRenderList(this.camera);

    this._needsSortProgressively = false;
    // If has any transparent mesh needs sort triangles progressively.
    for (var i = 0; i < renderList.transparent.length; i++) {
        var renderable = renderList.transparent[i];
        var geometry = renderable.geometry;
        if (geometry.needsSortVerticesProgressively && geometry.needsSortVerticesProgressively()) {
            this._needsSortProgressively = true;
        }
        if (geometry.needsSortTrianglesProgressively && geometry.needsSortTrianglesProgressively()) {
            this._needsSortProgressively = true;
        }
    }

    this._frame = 0;
    this._temporalSS.resetFrame();

    // var lights = this.scene.getLights();
    // for (var i = 0; i < lights.length; i++) {
    //     if (lights[i].cubemap) {
    //         if (this._compositor && this._compositor.isSSREnabled()) {
    //             lights[i].invisible = true;
    //         }
    //         else {
    //             lights[i].invisible = false;
    //         }
    //     }
    // }
};

ViewGL.prototype.render = function (renderer, accumulating) {
    this._doRender(renderer, accumulating, this._frame);
    this._frame++;
};

ViewGL.prototype.needsAccumulate = function () {
    return this.needsTemporalSS() || this._needsSortProgressively;
};

ViewGL.prototype.needsTemporalSS = function () {
    var enableTemporalSS = this._enableTemporalSS;
    if (enableTemporalSS === 'auto') {
        enableTemporalSS = this._enablePostEffect;
    }
    return enableTemporalSS;
};

ViewGL.prototype.hasDOF = function () {
    return this._enableDOF;
};

ViewGL.prototype.isAccumulateFinished = function () {
    return this.needsTemporalSS() ? this._temporalSS.isFinished()
        : (this._frame > 30);
};

ViewGL.prototype._doRender = function (renderer, accumulating, accumFrame) {

    var scene = this.scene;
    var camera = this.camera;

    accumFrame = accumFrame || 0;

    this._updateTransparent(renderer, scene, camera, accumFrame);

    if (!accumulating) {
        this._shadowMapPass.kernelPCF = this._pcfKernels[0];
        // Not render shadowmap pass in accumulating frame.
        this._shadowMapPass.render(renderer, scene, camera, true);
    }

    this._updateShadowPCFKernel(accumFrame);

    // Shadowmap will set clear color.
    var bgColor = renderer.clearColor;
    renderer.gl.clearColor(bgColor[0], bgColor[1], bgColor[2], bgColor[3]);

    if (this._enablePostEffect) {
        // normal render also needs to be jittered when have edge pass.
        if (this.needsTemporalSS()) {
            this._temporalSS.jitterProjection(renderer, camera);
        }
        this._compositor.updateNormal(renderer, scene, camera, this._temporalSS.getFrame());
    }

    // Always update SSAO to make sure have correct ssaoMap status
    this._updateSSAO(renderer, scene, camera, this._temporalSS.getFrame());

    if (this._enablePostEffect) {

        var frameBuffer = this._compositor.getSourceFrameBuffer();
        frameBuffer.bind(renderer);
        renderer.gl.clear(renderer.gl.DEPTH_BUFFER_BIT | renderer.gl.COLOR_BUFFER_BIT);
        renderer.render(scene, camera, true, true);
        frameBuffer.unbind(renderer);

        if (this.needsTemporalSS() && accumulating) {
            this._compositor.composite(renderer, scene, camera, this._temporalSS.getSourceFrameBuffer(), this._temporalSS.getFrame());
            renderer.setViewport(this.viewport);
            this._temporalSS.render(renderer);
        }
        else {
            renderer.setViewport(this.viewport);
            this._compositor.composite(renderer, scene, camera, null, 0);
        }
    }
    else {
        if (this.needsTemporalSS() && accumulating) {
            var frameBuffer = this._temporalSS.getSourceFrameBuffer();
            frameBuffer.bind(renderer);
            renderer.saveClear();
            renderer.clearBit = renderer.gl.DEPTH_BUFFER_BIT | renderer.gl.COLOR_BUFFER_BIT;
            renderer.render(scene, camera, true, true);
            renderer.restoreClear();
            frameBuffer.unbind(renderer);

            renderer.setViewport(this.viewport);
            this._temporalSS.render(renderer);
        }
        else {
            renderer.setViewport(this.viewport);
            renderer.render(scene, camera, true, true);
        }
    }

    // this._shadowMapPass.renderDebug(renderer);
    // this._compositor._normalPass.renderDebug(renderer);
};

ViewGL.prototype._updateTransparent = function (renderer, scene, camera, frame) {

    var v3 = new __WEBPACK_IMPORTED_MODULE_6_claygl_src_math_Vector3__["a" /* default */]();
    var invWorldTransform = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */]();
    var cameraWorldPosition = camera.getWorldPosition();
    var transparentList = scene.getRenderList(camera).transparent;

    // Sort transparent object.
    for (var i = 0; i < transparentList.length; i++) {
        var renderable = transparentList[i];
        var geometry = renderable.geometry;
        __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */].invert(invWorldTransform, renderable.worldTransform);
        __WEBPACK_IMPORTED_MODULE_6_claygl_src_math_Vector3__["a" /* default */].transformMat4(v3, cameraWorldPosition, invWorldTransform);
        if (geometry.needsSortTriangles && geometry.needsSortTriangles()) {
            geometry.doSortTriangles(v3, frame);
        }
        if (geometry.needsSortVertices && geometry.needsSortVertices()) {
            geometry.doSortVertices(v3, frame);
        }
    }
};

ViewGL.prototype._updateSSAO = function (renderer, scene, camera) {
    var ifEnableSSAO = this._enableSSAO && this._enablePostEffect;
    if (ifEnableSSAO) {
        this._compositor.updateSSAO(renderer, scene, camera, this._temporalSS.getFrame());
    }
    var renderList = scene.getRenderList(camera);

    for (var i = 0; i < renderList.opaque.length; i++) {
        var renderable = renderList.opaque[i];
        // PENDING
        if (renderable.renderNormal) {
            renderable.material[ifEnableSSAO ? 'enableTexture' : 'disableTexture']('ssaoMap');
        }
        if (ifEnableSSAO) {
            renderable.material.set('ssaoMap', this._compositor.getSSAOTexture());
        }
    }
};

ViewGL.prototype._updateShadowPCFKernel = function (frame) {
    var pcfKernel = this._pcfKernels[frame % this._pcfKernels.length];
    var renderList = this.scene.getRenderList(this.camera);
    var opaqueList = renderList.opaque;
    for (var i = 0; i < opaqueList.length; i++) {
        if (opaqueList[i].receiveShadow) {
            opaqueList[i].material.set('pcfKernel', pcfKernel);
            opaqueList[i].material.define('fragment', 'PCF_KERNEL_SIZE', pcfKernel.length / 2);
        }
    }
};

ViewGL.prototype.dispose = function (renderer) {
    this._compositor.dispose(renderer.gl);
    this._temporalSS.dispose(renderer.gl);
    this._shadowMapPass.dispose(renderer);
};
/**
 * @param {module:echarts/Model} Post effect model
 */
ViewGL.prototype.setPostEffect = function (postEffectModel, api) {
    var compositor = this._compositor;
    this._enablePostEffect = postEffectModel.get('enable');
    var bloomModel = postEffectModel.getModel('bloom');
    var edgeModel = postEffectModel.getModel('edge');
    var dofModel = postEffectModel.getModel('DOF', postEffectModel.getModel('depthOfField'));
    var ssaoModel = postEffectModel.getModel('SSAO', postEffectModel.getModel('screenSpaceAmbientOcclusion'));
    var ssrModel = postEffectModel.getModel('SSR', postEffectModel.getModel('screenSpaceReflection'));
    var fxaaModel = postEffectModel.getModel('FXAA');
    var colorCorrModel = postEffectModel.getModel('colorCorrection');
    bloomModel.get('enable') ? compositor.enableBloom() : compositor.disableBloom();
    dofModel.get('enable') ? compositor.enableDOF() : compositor.disableDOF();
    ssrModel.get('enable') ? compositor.enableSSR() : compositor.disableSSR();
    colorCorrModel.get('enable') ? compositor.enableColorCorrection() : compositor.disableColorCorrection();
    edgeModel.get('enable') ? compositor.enableEdge() : compositor.disableEdge();
    fxaaModel.get('enable') ? compositor.enableFXAA() : compositor.disableFXAA();

    this._enableDOF = dofModel.get('enable');
    this._enableSSAO = ssaoModel.get('enable');

    this._enableSSAO ? compositor.enableSSAO() : compositor.disableSSAO();

    compositor.setBloomIntensity(bloomModel.get('intensity'));
    compositor.setEdgeColor(edgeModel.get('color'));
    compositor.setColorLookupTexture(colorCorrModel.get('lookupTexture'), api);
    compositor.setExposure(colorCorrModel.get('exposure'));

    ['radius', 'quality', 'intensity'].forEach(function (name) {
        compositor.setSSAOParameter(name, ssaoModel.get(name));
    });
    ['quality', 'maxRoughness', 'physical'].forEach(function (name) {
        compositor.setSSRParameter(name, ssrModel.get(name));
    });
    ['quality', 'focalDistance', 'focalRange', 'blurRadius', 'fstop'].forEach(function (name) {
        compositor.setDOFParameter(name, dofModel.get(name));
    });
    ['brightness', 'contrast', 'saturation'].forEach(function (name) {
        compositor.setColorCorrection(name, colorCorrModel.get(name));
    });

};

ViewGL.prototype.setDOFFocusOnPoint = function (depth) {
    if (this._enablePostEffect) {

        if (depth > this.camera.far || depth < this.camera.near) {
            return;
        }

        this._compositor.setDOFParameter('focalDistance', depth);
        return true;
    }
};

ViewGL.prototype.setTemporalSuperSampling = function (temporalSuperSamplingModel) {
    this._enableTemporalSS = temporalSuperSamplingModel.get('enable');
};

ViewGL.prototype.isLinearSpace = function () {
    return this._enablePostEffect;
};

ViewGL.prototype.setRootNode = function (rootNode) {
    if (this.rootNode === rootNode) {
        return;
    }
    var children = this.rootNode.children();
    for (var i = 0; i < children.length; i++) {
        rootNode.add(children[i]);
    }
    if (rootNode !== this.scene) {
        this.scene.add(rootNode);
    }

    this.rootNode = rootNode;
};
// Proxies
ViewGL.prototype.add = function (node3D) {
    this.rootNode.add(node3D);
};
ViewGL.prototype.remove = function (node3D) {
    this.rootNode.remove(node3D);
};
ViewGL.prototype.removeAll = function (node3D) {
    this.rootNode.removeAll(node3D);
};

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.extend(ViewGL.prototype, __WEBPACK_IMPORTED_MODULE_8_claygl_src_core_mixin_notifier__["a" /* default */]);

/* harmony default export */ __webpack_exports__["a"] = (ViewGL);

/***/ }),
/* 23 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
var guid = 0;

var ArrayProto = Array.prototype;
var nativeForEach = ArrayProto.forEach;

/**
 * Util functions
 * @namespace clay.core.util
 */
var util = {

    /**
     * Generate GUID
     * @return {number}
     * @memberOf clay.core.util
     */
    genGUID: function () {
        return ++guid;
    },
    /**
     * Relative path to absolute path
     * @param  {string} path
     * @param  {string} basePath
     * @return {string}
     * @memberOf clay.core.util
     */
    relative2absolute: function (path, basePath) {
        if (!basePath || path.match(/^\//)) {
            return path;
        }
        var pathParts = path.split('/');
        var basePathParts = basePath.split('/');

        var item = pathParts[0];
        while(item === '.' || item === '..') {
            if (item === '..') {
                basePathParts.pop();
            }
            pathParts.shift();
            item = pathParts[0];
        }
        return basePathParts.join('/') + '/' + pathParts.join('/');
    },

    /**
     * Extend target with source
     * @param  {Object} target
     * @param  {Object} source
     * @return {Object}
     * @memberOf clay.core.util
     */
    extend: function (target, source) {
        if (source) {
            for (var name in source) {
                if (source.hasOwnProperty(name)) {
                    target[name] = source[name];
                }
            }
        }
        return target;
    },

    /**
     * Extend properties to target if not exist.
     * @param  {Object} target
     * @param  {Object} source
     * @return {Object}
     * @memberOf clay.core.util
     */
    defaults: function (target, source) {
        if (source) {
            for (var propName in source) {
                if (target[propName] === undefined) {
                    target[propName] = source[propName];
                }
            }
        }
        return target;
    },
    /**
     * Extend properties with a given property list to avoid for..in.. iteration.
     * @param  {Object} target
     * @param  {Object} source
     * @param  {Array.<string>} propList
     * @return {Object}
     * @memberOf clay.core.util
     */
    extendWithPropList: function (target, source, propList) {
        if (source) {
            for (var i = 0; i < propList.length; i++) {
                var propName = propList[i];
                target[propName] = source[propName];
            }
        }
        return target;
    },
    /**
     * Extend properties to target if not exist. With a given property list avoid for..in.. iteration.
     * @param  {Object} target
     * @param  {Object} source
     * @param  {Array.<string>} propList
     * @return {Object}
     * @memberOf clay.core.util
     */
    defaultsWithPropList: function (target, source, propList) {
        if (source) {
            for (var i = 0; i < propList.length; i++) {
                var propName = propList[i];
                if (target[propName] == null) {
                    target[propName] = source[propName];
                }
            }
        }
        return target;
    },
    /**
     * @param  {Object|Array} obj
     * @param  {Function} iterator
     * @param  {Object} [context]
     * @memberOf clay.core.util
     */
    each: function (obj, iterator, context) {
        if (!(obj && iterator)) {
            return;
        }
        if (obj.forEach && obj.forEach === nativeForEach) {
            obj.forEach(iterator, context);
        }
        else if (obj.length === + obj.length) {
            for (var i = 0, len = obj.length; i < len; i++) {
                iterator.call(context, obj[i], i, obj);
            }
        }
        else {
            for (var key in obj) {
                if (obj.hasOwnProperty(key)) {
                    iterator.call(context, obj[key], key, obj);
                }
            }
        }
    },

    /**
     * Is object
     * @param  {}  obj
     * @return {boolean}
     * @memberOf clay.core.util
     */
    isObject: function (obj) {
        return obj === Object(obj);
    },

    /**
     * Is array ?
     * @param  {}  obj
     * @return {boolean}
     * @memberOf clay.core.util
     */
    isArray: function (obj) {
        return Array.isArray(obj);
    },

    /**
     * Is array like, which have a length property
     * @param  {}  obj
     * @return {boolean}
     * @memberOf clay.core.util
     */
    isArrayLike: function (obj) {
        if (!obj) {
            return false;
        }
        else {
            return obj.length === + obj.length;
        }
    },

    /**
     * @param  {} obj
     * @return {}
     * @memberOf clay.core.util
     */
    clone: function (obj) {
        if (!util.isObject(obj)) {
            return obj;
        }
        else if (util.isArray(obj)) {
            return obj.slice();
        }
        else if (util.isArrayLike(obj)) { // is typed array
            var ret = new obj.constructor(obj.length);
            for (var i = 0; i < obj.length; i++) {
                ret[i] = obj[i];
            }
            return ret;
        }
        else {
            return util.extend({}, obj);
        }
    }
};

/* harmony default export */ __webpack_exports__["a"] = (util);


/***/ }),
/* 24 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Node__ = __webpack_require__(35);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__shader_source_header_light__ = __webpack_require__(119);




__WEBPACK_IMPORTED_MODULE_1__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_2__shader_source_header_light__["a" /* default */]);

/**
 * @constructor clay.Light
 * @extends clay.Node
 */
var Light = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].extend(function(){
    return /** @lends clay.Light# */ {
        /**
         * Light RGB color
         * @type {number[]}
         */
        color: [1, 1, 1],

        /**
         * Light intensity
         * @type {number}
         */
        intensity: 1.0,

        // Config for shadow map
        /**
         * If light cast shadow
         * @type {boolean}
         */
        castShadow: true,

        /**
         * Shadow map size
         * @type {number}
         */
        shadowResolution: 512,

        /**
         * Light group, shader with same `lightGroup` will be affected
         *
         * Only useful in forward rendering
         * @type {number}
         */
        group: 0
    };
},
/** @lends clay.Light.prototype. */
{
    /**
     * Light type
     * @type {string}
     * @memberOf clay.Light#
     */
    type: '',

    /**
     * @return {clay.Light}
     * @memberOf clay.Light.prototype
     */
    clone: function() {
        var light = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].prototype.clone.call(this);
        light.color = Array.prototype.slice.call(this.color);
        light.intensity = this.intensity;
        light.castShadow = this.castShadow;
        light.shadowResolution = this.shadowResolution;

        return light;
    }
});

/* harmony default export */ __webpack_exports__["a"] = (Light);


/***/ }),
/* 25 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__ = __webpack_require__(38);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__ = __webpack_require__(6);
/**
 * Lines geometry
 * Use screen space projected lines lineWidth > MAX_LINE_WIDTH
 * https://mattdesl.svbtle.com/drawing-lines-is-hard
 * @module echarts-gl/util/geometry/LinesGeometry
 * @author Yi Shen(http://github.com/pissang)
 */





var vec3 = __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__["a" /* default */].vec3;

// var CURVE_RECURSION_LIMIT = 8;
// var CURVE_COLLINEAR_EPSILON = 40;

var sampleLinePoints = [[0, 0], [1, 1]];
/**
 * @constructor
 * @alias module:echarts-gl/util/geometry/LinesGeometry
 * @extends clay.Geometry
 */

var LinesGeometry = __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].extend(function () {
    return {

        segmentScale: 1,

        dynamic: true,
        /**
         * Need to use mesh to expand lines if lineWidth > MAX_LINE_WIDTH
         */
        useNativeLine: true,

        attributes: {
            position: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('position', 'float', 3, 'POSITION'),
            positionPrev: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('positionPrev', 'float', 3),
            positionNext: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('positionNext', 'float', 3),
            prevPositionPrev: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('prevPositionPrev', 'float', 3),
            prevPosition: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('prevPosition', 'float', 3),
            prevPositionNext: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('prevPositionNext', 'float', 3),
            offset: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('offset', 'float', 1),
            color: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('color', 'float', 4, 'COLOR')
        }
    };
},
/** @lends module: echarts-gl/util/geometry/LinesGeometry.prototype */
{

    /**
     * Reset offset
     */
    resetOffset: function () {
        this._vertexOffset = 0;
        this._triangleOffset = 0;

        this._itemVertexOffsets = [];
    },

    /**
     * @param {number} nVertex
     */
    setVertexCount: function (nVertex) {
        var attributes = this.attributes;
        if (this.vertexCount !== nVertex) {
            attributes.position.init(nVertex);
            attributes.color.init(nVertex);

            if (!this.useNativeLine) {
                attributes.positionPrev.init(nVertex);
                attributes.positionNext.init(nVertex);
                attributes.offset.init(nVertex);
            }

            if (nVertex > 0xffff) {
                if (this.indices instanceof Uint16Array) {
                    this.indices = new Uint32Array(this.indices);
                }
            }
            else {
                if (this.indices instanceof Uint32Array) {
                    this.indices = new Uint16Array(this.indices);
                }
            }
        }
    },

    /**
     * @param {number} nTriangle
     */
    setTriangleCount: function (nTriangle) {
        if (this.triangleCount !== nTriangle) {
            if (nTriangle === 0) {
                this.indices = null;
            }
            else {
                this.indices = this.vertexCount > 0xffff ? new Uint32Array(nTriangle * 3) : new Uint16Array(nTriangle * 3);
            }
        }
    },

    _getCubicCurveApproxStep: function (p0, p1, p2, p3) {
        var len = vec3.dist(p0, p1) + vec3.dist(p2, p1) + vec3.dist(p3, p2);
        var step = 1 / (len + 1) * this.segmentScale;
        return step;
    },

    /**
     * Get vertex count of cubic curve
     * @param {Array.<number>} p0
     * @param {Array.<number>} p1
     * @param {Array.<number>} p2
     * @param {Array.<number>} p3
     * @return number
     */
    getCubicCurveVertexCount: function (p0, p1, p2, p3) {
        var step = this._getCubicCurveApproxStep(p0, p1, p2, p3);
        var segCount = Math.ceil(1 / step);
        if (!this.useNativeLine) {
            return segCount * 2 + 2;
        }
        else {
            return segCount * 2;
        }
    },

    /**
     * Get face count of cubic curve
     * @param {Array.<number>} p0
     * @param {Array.<number>} p1
     * @param {Array.<number>} p2
     * @param {Array.<number>} p3
     * @return number
     */
    getCubicCurveTriangleCount: function (p0, p1, p2, p3) {
        var step = this._getCubicCurveApproxStep(p0, p1, p2, p3);
        var segCount = Math.ceil(1 / step);
        if (!this.useNativeLine) {
            return segCount * 2;
        }
        else {
            return 0;
        }
    },

    /**
     * Get vertex count of line
     * @return {number}
     */
    getLineVertexCount: function () {
        return this.getPolylineVertexCount(sampleLinePoints);
    },

    /**
     * Get face count of line
     * @return {number}
     */
    getLineTriangleCount: function () {
        return this.getPolylineTriangleCount(sampleLinePoints);
    },

    /**
     * Get how many vertices will polyline take.
     * @type {number|Array} points Can be a 1d/2d list of points, or a number of points amount.
     * @return {number}
     */
    getPolylineVertexCount: function (points) {
        var pointsLen;
        if (typeof points === 'number') {
            pointsLen = points;
        }
        else {
            var is2DArray = typeof points[0] !== 'number';
            pointsLen = is2DArray ? points.length : (points.length / 3);
        }
        return !this.useNativeLine ? ((pointsLen - 1) * 2 + 2) : (pointsLen - 1) * 2;
    },

    /**
     * Get how many triangles will polyline take.
     * @type {number|Array} points Can be a 1d/2d list of points, or a number of points amount.
     * @return {number}
     */
    getPolylineTriangleCount: function (points) {
        var pointsLen;
        if (typeof points === 'number') {
            pointsLen = points;
        }
        else {
            var is2DArray = typeof points[0] !== 'number';
            pointsLen = is2DArray ? points.length : (points.length / 3);
        }
        return !this.useNativeLine ? Math.max(pointsLen - 1, 0) * 2 : 0;
    },

    /**
     * Add a cubic curve
     * @param {Array.<number>} p0
     * @param {Array.<number>} p1
     * @param {Array.<number>} p2
     * @param {Array.<number>} p3
     * @param {Array.<number>} color
     * @param {number} [lineWidth=1]
     */
    addCubicCurve: function (p0, p1, p2, p3, color, lineWidth) {
        if (lineWidth == null) {
            lineWidth = 1;
        }
        // incremental interpolation
        // http://antigrain.com/research/bezier_interpolation/index.html#PAGE_BEZIER_INTERPOLATION
        var x0 = p0[0], y0 = p0[1], z0 = p0[2];
        var x1 = p1[0], y1 = p1[1], z1 = p1[2];
        var x2 = p2[0], y2 = p2[1], z2 = p2[2];
        var x3 = p3[0], y3 = p3[1], z3 = p3[2];

        var step = this._getCubicCurveApproxStep(p0, p1, p2, p3);

        var step2 = step * step;
        var step3 = step2 * step;

        var pre1 = 3.0 * step;
        var pre2 = 3.0 * step2;
        var pre4 = 6.0 * step2;
        var pre5 = 6.0 * step3;

        var tmp1x = x0 - x1 * 2.0 + x2;
        var tmp1y = y0 - y1 * 2.0 + y2;
        var tmp1z = z0 - z1 * 2.0 + z2;

        var tmp2x = (x1 - x2) * 3.0 - x0 + x3;
        var tmp2y = (y1 - y2) * 3.0 - y0 + y3;
        var tmp2z = (z1 - z2) * 3.0 - z0 + z3;

        var fx = x0;
        var fy = y0;
        var fz = z0;

        var dfx = (x1 - x0) * pre1 + tmp1x * pre2 + tmp2x * step3;
        var dfy = (y1 - y0) * pre1 + tmp1y * pre2 + tmp2y * step3;
        var dfz = (z1 - z0) * pre1 + tmp1z * pre2 + tmp2z * step3;

        var ddfx = tmp1x * pre4 + tmp2x * pre5;
        var ddfy = tmp1y * pre4 + tmp2y * pre5;
        var ddfz = tmp1z * pre4 + tmp2z * pre5;

        var dddfx = tmp2x * pre5;
        var dddfy = tmp2y * pre5;
        var dddfz = tmp2z * pre5;

        var t = 0;

        var k = 0;
        var segCount = Math.ceil(1 / step);

        var points = new Float32Array((segCount + 1) * 3);
        var points = [];
        var offset = 0;
        for (var k = 0; k < segCount + 1; k++) {
            points[offset++] = fx;
            points[offset++] = fy;
            points[offset++] = fz;

            fx += dfx; fy += dfy; fz += dfz;
            dfx += ddfx; dfy += ddfy; dfz += ddfz;
            ddfx += dddfx; ddfy += dddfy; ddfz += dddfz;
            t += step;

            if (t > 1) {
                fx = dfx > 0 ? Math.min(fx, x3) : Math.max(fx, x3);
                fy = dfy > 0 ? Math.min(fy, y3) : Math.max(fy, y3);
                fz = dfz > 0 ? Math.min(fz, z3) : Math.max(fz, z3);
            }
        }

        return this.addPolyline(points, color, lineWidth);
    },

    /**
     * Add a straight line
     * @param {Array.<number>} p0
     * @param {Array.<number>} p1
     * @param {Array.<number>} color
     * @param {number} [lineWidth=1]
     */
    addLine: function (p0, p1, color, lineWidth) {
        return this.addPolyline([p0, p1], color, lineWidth);
    },

    /**
     * Add a straight line
     * @param {Array.<Array> | Array.<number>} points
     * @param {Array.<number> | Array.<Array>} color
     * @param {number} [lineWidth=1]
     * @param {number} [startOffset=0]
     * @param {number} [pointsCount] Default to be amount of points in the first argument
     */
    addPolyline: function (points, color, lineWidth, startOffset, pointsCount) {
        if (!points.length) {
            return;
        }
        var is2DArray = typeof points[0] !== 'number';
        if (pointsCount == null) {
            pointsCount = is2DArray ? points.length : points.length / 3;
        }
        if (pointsCount < 2) {
            return;
        }
        if (startOffset == null) {
            startOffset = 0;
        }
        if (lineWidth == null) {
            lineWidth = 1;
        }

        this._itemVertexOffsets.push(this._vertexOffset);

        var is2DArray = typeof points[0] !== 'number';
        var notSharingColor = is2DArray
            ? typeof color[0] !== 'number'
            : color.length / 4 === pointsCount;

        var positionAttr = this.attributes.position;
        var positionPrevAttr = this.attributes.positionPrev;
        var positionNextAttr = this.attributes.positionNext;
        var colorAttr = this.attributes.color;
        var offsetAttr = this.attributes.offset;
        var indices = this.indices;

        var vertexOffset = this._vertexOffset;
        var point;
        var pointColor;

        lineWidth = Math.max(lineWidth, 0.01);

        for (var k = startOffset; k < pointsCount; k++) {
            if (is2DArray) {
                point = points[k];
                if (notSharingColor) {
                    pointColor = color[k];
                }
                else {
                    pointColor = color;
                }
            }
            else {
                var k3 = k * 3;
                point = point || [];
                point[0] = points[k3];
                point[1] = points[k3 + 1];
                point[2] = points[k3 + 2];

                if (notSharingColor) {
                    var k4 = k * 4;
                    pointColor = pointColor || [];
                    pointColor[0] = color[k4];
                    pointColor[1] = color[k4 + 1];
                    pointColor[2] = color[k4 + 2];
                    pointColor[3] = color[k4 + 3];
                }
                else {
                    pointColor = color;
                }
            }
            if (!this.useNativeLine) {
                if (k < pointsCount - 1) {
                    // Set to next two points
                    positionPrevAttr.set(vertexOffset + 2, point);
                    positionPrevAttr.set(vertexOffset + 3, point);
                }
                if (k > 0) {
                    // Set to previous two points
                    positionNextAttr.set(vertexOffset - 2, point);
                    positionNextAttr.set(vertexOffset - 1, point);
                }

                positionAttr.set(vertexOffset, point);
                positionAttr.set(vertexOffset + 1, point);

                colorAttr.set(vertexOffset, pointColor);
                colorAttr.set(vertexOffset + 1, pointColor);

                offsetAttr.set(vertexOffset, lineWidth / 2);
                offsetAttr.set(vertexOffset + 1, -lineWidth / 2);

                vertexOffset += 2;
            }
            else {
                if (k > 1) {
                    positionAttr.copy(vertexOffset, vertexOffset - 1);
                    colorAttr.copy(vertexOffset, vertexOffset - 1);
                    vertexOffset++;
                }
            }

            if (!this.useNativeLine) {
                if (k > 0) {
                    var idx3 = this._triangleOffset * 3;
                    var indices = this.indices;
                    // 0-----2
                    // 1-----3
                    // 0->1->2, 1->3->2
                    indices[idx3] = vertexOffset - 4;
                    indices[idx3 + 1] = vertexOffset - 3;
                    indices[idx3 + 2] = vertexOffset - 2;

                    indices[idx3 + 3] = vertexOffset - 3;
                    indices[idx3 + 4] = vertexOffset - 1;
                    indices[idx3 + 5] = vertexOffset - 2;

                    this._triangleOffset += 2;
                }
            }
            else {
                colorAttr.set(vertexOffset, pointColor);
                positionAttr.set(vertexOffset, point);
                vertexOffset++;
            }
        }
        if (!this.useNativeLine) {
            var start = this._vertexOffset;
            var end = this._vertexOffset + pointsCount * 2;
            positionPrevAttr.copy(start, start + 2);
            positionPrevAttr.copy(start + 1, start + 3);
            positionNextAttr.copy(end - 1, end - 3);
            positionNextAttr.copy(end - 2, end - 4);
        }

        this._vertexOffset = vertexOffset;

        return this._vertexOffset;
    },

    /**
     * Set color of single line.
     */
    setItemColor: function (idx, color) {
        var startOffset = this._itemVertexOffsets[idx];
        var endOffset = idx < this._itemVertexOffsets.length - 1 ? this._itemVertexOffsets[idx + 1] : this._vertexOffset;

        for (var i = startOffset; i < endOffset; i++) {
            this.attributes.color.set(i, color);
        }
        this.dirty('color');
    },

    /**
     * @return {number}
     */
    currentTriangleOffset: function () {
        return this._triangleOffset;
    },

    /**
     * @return {number}
     */
    currentVertexOffset: function () {
        return this._vertexOffset;
    }
});

__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.util.defaults(LinesGeometry.prototype, __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__["a" /* default */]);

/* harmony default export */ __webpack_exports__["a"] = (LinesGeometry);

/***/ }),
/* 26 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__ = __webpack_require__(70);


/**
 * @constructor
 * @alias clay.Vector2
 * @param {number} x
 * @param {number} y
 */
var Vector2 = function(x, y) {

    x = x || 0;
    y = y || 0;

    /**
     * Storage of Vector2, read and write of x, y will change the values in array
     * All methods also operate on the array instead of x, y components
     * @name array
     * @type {Float32Array}
     * @memberOf clay.Vector2#
     */
    this.array = __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].fromValues(x, y);

    /**
     * Dirty flag is used by the Node to determine
     * if the matrix is updated to latest
     * @name _dirty
     * @type {boolean}
     * @memberOf clay.Vector2#
     */
    this._dirty = true;
};

Vector2.prototype = {

    constructor: Vector2,

    /**
     * Add b to self
     * @param  {clay.Vector2} b
     * @return {clay.Vector2}
     */
    add: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].add(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Set x and y components
     * @param  {number}  x
     * @param  {number}  y
     * @return {clay.Vector2}
     */
    set: function(x, y) {
        this.array[0] = x;
        this.array[1] = y;
        this._dirty = true;
        return this;
    },

    /**
     * Set x and y components from array
     * @param  {Float32Array|number[]} arr
     * @return {clay.Vector2}
     */
    setArray: function(arr) {
        this.array[0] = arr[0];
        this.array[1] = arr[1];

        this._dirty = true;
        return this;
    },

    /**
     * Clone a new Vector2
     * @return {clay.Vector2}
     */
    clone: function() {
        return new Vector2(this.x, this.y);
    },

    /**
     * Copy x, y from b
     * @param  {clay.Vector2} b
     * @return {clay.Vector2}
     */
    copy: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].copy(this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Cross product of self and b, written to a Vector3 out
     * @param  {clay.Vector3} out
     * @param  {clay.Vector2} b
     * @return {clay.Vector2}
     */
    cross: function(out, b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].cross(out.array, this.array, b.array);
        out._dirty = true;
        return this;
    },

    /**
     * Alias for distance
     * @param  {clay.Vector2} b
     * @return {number}
     */
    dist: function(b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].dist(this.array, b.array);
    },

    /**
     * Distance between self and b
     * @param  {clay.Vector2} b
     * @return {number}
     */
    distance: function(b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].distance(this.array, b.array);
    },

    /**
     * Alias for divide
     * @param  {clay.Vector2} b
     * @return {clay.Vector2}
     */
    div: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].div(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Divide self by b
     * @param  {clay.Vector2} b
     * @return {clay.Vector2}
     */
    divide: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].divide(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Dot product of self and b
     * @param  {clay.Vector2} b
     * @return {number}
     */
    dot: function(b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].dot(this.array, b.array);
    },

    /**
     * Alias of length
     * @return {number}
     */
    len: function() {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].len(this.array);
    },

    /**
     * Calculate the length
     * @return {number}
     */
    length: function() {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].length(this.array);
    },

    /**
     * Linear interpolation between a and b
     * @param  {clay.Vector2} a
     * @param  {clay.Vector2} b
     * @param  {number}  t
     * @return {clay.Vector2}
     */
    lerp: function(a, b, t) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].lerp(this.array, a.array, b.array, t);
        this._dirty = true;
        return this;
    },

    /**
     * Minimum of self and b
     * @param  {clay.Vector2} b
     * @return {clay.Vector2}
     */
    min: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].min(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Maximum of self and b
     * @param  {clay.Vector2} b
     * @return {clay.Vector2}
     */
    max: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].max(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for multiply
     * @param  {clay.Vector2} b
     * @return {clay.Vector2}
     */
    mul: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].mul(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Mutiply self and b
     * @param  {clay.Vector2} b
     * @return {clay.Vector2}
     */
    multiply: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].multiply(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Negate self
     * @return {clay.Vector2}
     */
    negate: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].negate(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Normalize self
     * @return {clay.Vector2}
     */
    normalize: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].normalize(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Generate random x, y components with a given scale
     * @param  {number} scale
     * @return {clay.Vector2}
     */
    random: function(scale) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].random(this.array, scale);
        this._dirty = true;
        return this;
    },

    /**
     * Scale self
     * @param  {number}  scale
     * @return {clay.Vector2}
     */
    scale: function(s) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].scale(this.array, this.array, s);
        this._dirty = true;
        return this;
    },

    /**
     * Scale b and add to self
     * @param  {clay.Vector2} b
     * @param  {number}  scale
     * @return {clay.Vector2}
     */
    scaleAndAdd: function(b, s) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].scaleAndAdd(this.array, this.array, b.array, s);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for squaredDistance
     * @param  {clay.Vector2} b
     * @return {number}
     */
    sqrDist: function(b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].sqrDist(this.array, b.array);
    },

    /**
     * Squared distance between self and b
     * @param  {clay.Vector2} b
     * @return {number}
     */
    squaredDistance: function(b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].squaredDistance(this.array, b.array);
    },

    /**
     * Alias for squaredLength
     * @return {number}
     */
    sqrLen: function() {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].sqrLen(this.array);
    },

    /**
     * Squared length of self
     * @return {number}
     */
    squaredLength: function() {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].squaredLength(this.array);
    },

    /**
     * Alias for subtract
     * @param  {clay.Vector2} b
     * @return {clay.Vector2}
     */
    sub: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].sub(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Subtract b from self
     * @param  {clay.Vector2} b
     * @return {clay.Vector2}
     */
    subtract: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].subtract(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Transform self with a Matrix2 m
     * @param  {clay.Matrix2} m
     * @return {clay.Vector2}
     */
    transformMat2: function(m) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].transformMat2(this.array, this.array, m.array);
        this._dirty = true;
        return this;
    },

    /**
     * Transform self with a Matrix2d m
     * @param  {clay.Matrix2d} m
     * @return {clay.Vector2}
     */
    transformMat2d: function(m) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].transformMat2d(this.array, this.array, m.array);
        this._dirty = true;
        return this;
    },

    /**
     * Transform self with a Matrix3 m
     * @param  {clay.Matrix3} m
     * @return {clay.Vector2}
     */
    transformMat3: function(m) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].transformMat3(this.array, this.array, m.array);
        this._dirty = true;
        return this;
    },

    /**
     * Transform self with a Matrix4 m
     * @param  {clay.Matrix4} m
     * @return {clay.Vector2}
     */
    transformMat4: function(m) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].transformMat4(this.array, this.array, m.array);
        this._dirty = true;
        return this;
    },

    toString: function() {
        return '[' + Array.prototype.join.call(this.array, ',') + ']';
    },

    toArray: function () {
        return Array.prototype.slice.call(this.array);
    }
};

// Getter and Setter
if (Object.defineProperty) {

    var proto = Vector2.prototype;
    /**
     * @name x
     * @type {number}
     * @memberOf clay.Vector2
     * @instance
     */
    Object.defineProperty(proto, 'x', {
        get: function () {
            return this.array[0];
        },
        set: function (value) {
            this.array[0] = value;
            this._dirty = true;
        }
    });

    /**
     * @name y
     * @type {number}
     * @memberOf clay.Vector2
     * @instance
     */
    Object.defineProperty(proto, 'y', {
        get: function () {
            return this.array[1];
        },
        set: function (value) {
            this.array[1] = value;
            this._dirty = true;
        }
    });
}

// Supply methods that are not in place

/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {clay.Vector2}
 */
Vector2.add = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].add(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector2} out
 * @param  {number}  x
 * @param  {number}  y
 * @return {clay.Vector2}
 */
Vector2.set = function(out, x, y) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].set(out.array, x, y);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} b
 * @return {clay.Vector2}
 */
Vector2.copy = function(out, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].copy(out.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector3} out
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {clay.Vector2}
 */
Vector2.cross = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].cross(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {number}
 */
Vector2.dist = function(a, b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].distance(a.array, b.array);
};
/**
 * @function
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {number}
 */
Vector2.distance = Vector2.dist;
/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {clay.Vector2}
 */
Vector2.div = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].divide(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};
/**
 * @function
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {clay.Vector2}
 */
Vector2.divide = Vector2.div;
/**
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {number}
 */
Vector2.dot = function(a, b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].dot(a.array, b.array);
};

/**
 * @param  {clay.Vector2} a
 * @return {number}
 */
Vector2.len = function(b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].length(b.array);
};

// Vector2.length = Vector2.len;

/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @param  {number}  t
 * @return {clay.Vector2}
 */
Vector2.lerp = function(out, a, b, t) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].lerp(out.array, a.array, b.array, t);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {clay.Vector2}
 */
Vector2.min = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].min(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {clay.Vector2}
 */
Vector2.max = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].max(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {clay.Vector2}
 */
Vector2.mul = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].multiply(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};
/**
 * @function
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {clay.Vector2}
 */
Vector2.multiply = Vector2.mul;
/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @return {clay.Vector2}
 */
Vector2.negate = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].negate(out.array, a.array);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @return {clay.Vector2}
 */
Vector2.normalize = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].normalize(out.array, a.array);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector2} out
 * @param  {number}  scale
 * @return {clay.Vector2}
 */
Vector2.random = function(out, scale) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].random(out.array, scale);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {number}  scale
 * @return {clay.Vector2}
 */
Vector2.scale = function(out, a, scale) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].scale(out.array, a.array, scale);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @param  {number}  scale
 * @return {clay.Vector2}
 */
Vector2.scaleAndAdd = function(out, a, b, scale) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].scaleAndAdd(out.array, a.array, b.array, scale);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {number}
 */
Vector2.sqrDist = function(a, b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].sqrDist(a.array, b.array);
};
/**
 * @function
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {number}
 */
Vector2.squaredDistance = Vector2.sqrDist;

/**
 * @param  {clay.Vector2} a
 * @return {number}
 */
Vector2.sqrLen = function(a) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].sqrLen(a.array);
};
/**
 * @function
 * @param  {clay.Vector2} a
 * @return {number}
 */
Vector2.squaredLength = Vector2.sqrLen;

/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {clay.Vector2}
 */
Vector2.sub = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].subtract(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};
/**
 * @function
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Vector2} b
 * @return {clay.Vector2}
 */
Vector2.subtract = Vector2.sub;
/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Matrix2} m
 * @return {clay.Vector2}
 */
Vector2.transformMat2 = function(out, a, m) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].transformMat2(out.array, a.array, m.array);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector2}  out
 * @param  {clay.Vector2}  a
 * @param  {clay.Matrix2d} m
 * @return {clay.Vector2}
 */
Vector2.transformMat2d = function(out, a, m) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].transformMat2d(out.array, a.array, m.array);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {Matrix3} m
 * @return {clay.Vector2}
 */
Vector2.transformMat3 = function(out, a, m) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].transformMat3(out.array, a.array, m.array);
    out._dirty = true;
    return out;
};
/**
 * @param  {clay.Vector2} out
 * @param  {clay.Vector2} a
 * @param  {clay.Matrix4} m
 * @return {clay.Vector2}
 */
Vector2.transformMat4 = function(out, a, m) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec2__["a" /* default */].transformMat4(out.array, a.array, m.array);
    out._dirty = true;
    return out;
};

/* harmony default export */ __webpack_exports__["a"] = (Vector2);


/***/ }),
/* 27 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_util__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_util__ = __webpack_require__(73);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__core_vendor__ = __webpack_require__(14);





var isPowerOfTwo = __WEBPACK_IMPORTED_MODULE_3__math_util__["a" /* default */].isPowerOfTwo;

var targetList = ['px', 'nx', 'py', 'ny', 'pz', 'nz'];

/**
 * @constructor clay.TextureCube
 * @extends clay.Texture
 *
 * @example
 *     ...
 *     var mat = new clay.Material({
 *         shader: clay.shader.library.get('clay.phong', 'environmentMap')
 *     });
 *     var envMap = new clay.TextureCube();
 *     envMap.load({
 *         'px': 'assets/textures/sky/px.jpg',
 *         'nx': 'assets/textures/sky/nx.jpg'
 *         'py': 'assets/textures/sky/py.jpg'
 *         'ny': 'assets/textures/sky/ny.jpg'
 *         'pz': 'assets/textures/sky/pz.jpg'
 *         'nz': 'assets/textures/sky/nz.jpg'
 *     });
 *     mat.set('environmentMap', envMap);
 *     ...
 *     envMap.success(function () {
 *         // Wait for the sky texture loaded
 *         animation.on('frame', function (frameTime) {
 *             renderer.render(scene, camera);
 *         });
 *     });
 */
var TextureCube = __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].extend(function () {
    return /** @lends clay.TextureCube# */{

        /**
         * @type {boolean}
         * @default false
         */
        // PENDING cubemap should not flipY in default.
        // flipY: false,

        /**
         * @type {Object}
         * @property {?HTMLImageElement|HTMLCanvasElemnet} px
         * @property {?HTMLImageElement|HTMLCanvasElemnet} nx
         * @property {?HTMLImageElement|HTMLCanvasElemnet} py
         * @property {?HTMLImageElement|HTMLCanvasElemnet} ny
         * @property {?HTMLImageElement|HTMLCanvasElemnet} pz
         * @property {?HTMLImageElement|HTMLCanvasElemnet} nz
         */
        image: {
            px: null,
            nx: null,
            py: null,
            ny: null,
            pz: null,
            nz: null
        },
        /**
         * Pixels data of each side. Will be ignored if images are set.
         * @type {Object}
         * @property {?Uint8Array} px
         * @property {?Uint8Array} nx
         * @property {?Uint8Array} py
         * @property {?Uint8Array} ny
         * @property {?Uint8Array} pz
         * @property {?Uint8Array} nz
         */
        pixels: {
            px: null,
            nx: null,
            py: null,
            ny: null,
            pz: null,
            nz: null
        },

        /**
         * @type {Array.<Object>}
         */
        mipmaps: []
    };
}, {

    textureType: 'textureCube',

    update: function (renderer) {
        var _gl = renderer.gl;
        _gl.bindTexture(_gl.TEXTURE_CUBE_MAP, this._cache.get('webgl_texture'));

        this.updateCommon(renderer);

        var glFormat = this.format;
        var glType = this.type;

        _gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_WRAP_S, this.getAvailableWrapS());
        _gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_WRAP_T, this.getAvailableWrapT());

        _gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MAG_FILTER, this.getAvailableMagFilter());
        _gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MIN_FILTER, this.getAvailableMinFilter());

        var anisotropicExt = renderer.getGLExtension('EXT_texture_filter_anisotropic');
        if (anisotropicExt && this.anisotropic > 1) {
            _gl.texParameterf(_gl.TEXTURE_CUBE_MAP, anisotropicExt.TEXTURE_MAX_ANISOTROPY_EXT, this.anisotropic);
        }

        // Fallback to float type if browser don't have half float extension
        if (glType === 36193) {
            var halfFloatExt = renderer.getGLExtension('OES_texture_half_float');
            if (!halfFloatExt) {
                glType = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FLOAT;
            }
        }

        if (this.mipmaps.length) {
            var width = this.width;
            var height = this.height;
            for (var i = 0; i < this.mipmaps.length; i++) {
                var mipmap = this.mipmaps[i];
                this._updateTextureData(_gl, mipmap, i, width, height, glFormat, glType);
                width /= 2;
                height /= 2;
            }
        }
        else {
            this._updateTextureData(_gl, this, 0, this.width, this.height, glFormat, glType);

            if (!this.NPOT && this.useMipmap) {
                _gl.generateMipmap(_gl.TEXTURE_CUBE_MAP);
            }
        }

        _gl.bindTexture(_gl.TEXTURE_CUBE_MAP, null);
    },

    _updateTextureData: function (_gl, data, level, width, height, glFormat, glType) {
        for (var i = 0; i < 6; i++) {
            var target = targetList[i];
            var img = data.image && data.image[target];
            if (img) {
                _gl.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level, glFormat, glFormat, glType, img);
            }
            else {
                _gl.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level, glFormat, width, height, 0, glFormat, glType, data.pixels && data.pixels[target]);
            }
        }
    },

    /**
     * @param  {clay.Renderer} renderer
     * @memberOf clay.TextureCube.prototype
     */
    generateMipmap: function (renderer) {
        var _gl = renderer.gl;
        if (this.useMipmap && !this.NPOT) {
            _gl.bindTexture(_gl.TEXTURE_CUBE_MAP, this._cache.get('webgl_texture'));
            _gl.generateMipmap(_gl.TEXTURE_CUBE_MAP);
        }
    },

    bind: function (renderer) {
        renderer.gl.bindTexture(renderer.gl.TEXTURE_CUBE_MAP, this.getWebGLTexture(renderer));
    },

    unbind: function (renderer) {
        renderer.gl.bindTexture(renderer.gl.TEXTURE_CUBE_MAP, null);
    },

    // Overwrite the isPowerOfTwo method
    isPowerOfTwo: function () {
        if (this.image.px) {
            return isPowerOfTwo(this.image.px.width)
                && isPowerOfTwo(this.image.px.height);
        }
        else {
            return isPowerOfTwo(this.width)
                && isPowerOfTwo(this.height);
        }
    },

    isRenderable: function () {
        if (this.image.px) {
            return isImageRenderable(this.image.px)
                && isImageRenderable(this.image.nx)
                && isImageRenderable(this.image.py)
                && isImageRenderable(this.image.ny)
                && isImageRenderable(this.image.pz)
                && isImageRenderable(this.image.nz);
        }
        else {
            return !!(this.width && this.height);
        }
    },

    load: function (imageList, crossOrigin) {
        var loading = 0;
        var self = this;
        __WEBPACK_IMPORTED_MODULE_2__core_util__["a" /* default */].each(imageList, function (src, target){
            var image = __WEBPACK_IMPORTED_MODULE_4__core_vendor__["a" /* default */].createImage();
            if (crossOrigin) {
                image.crossOrigin = crossOrigin;
            }
            image.onload = function () {
                loading --;
                if (loading === 0){
                    self.dirty();
                    self.trigger('success', self);
                }
                image.onload = null;
            };
            image.onerror = function () {
                loading --;
                image.onerror = null;
            };

            loading++;
            image.src = src;
            self.image[target] = image;
        });

        return this;
    }
});

Object.defineProperty(TextureCube.prototype, 'width', {
    get: function () {
        if (this.image && this.image.px) {
            return this.image.px.width;
        }
        return this._width;
    },
    set: function (value) {
        if (this.image && this.image.px) {
            console.warn('Texture from image can\'t set width');
        }
        else {
            if (this._width !== value) {
                this.dirty();
            }
            this._width = value;
        }
    }
});
Object.defineProperty(TextureCube.prototype, 'height', {
    get: function () {
        if (this.image && this.image.px) {
            return this.image.px.height;
        }
        return this._height;
    },
    set: function (value) {
        if (this.image && this.image.px) {
            console.warn('Texture from image can\'t set height');
        }
        else {
            if (this._height !== value) {
                this.dirty();
            }
            this._height = value;
        }
    }
});
function isImageRenderable(image) {
    return image.nodeName === 'CANVAS' ||
            image.nodeName === 'VIDEO' ||
            image.complete;
}

/* harmony default export */ __webpack_exports__["a"] = (TextureCube);


/***/ }),
/* 28 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ({
    defaultOption: {
        // Post effect
        postEffect: {
            enable: false,

            bloom: {
                enable: true,
                intensity: 0.1
            },
            depthOfField: {
                enable: false,
                focalRange: 20,
                focalDistance: 50,
                blurRadius: 10,
                fstop: 2.8,
                quality: 'medium'
            },

            screenSpaceAmbientOcclusion: {
                enable: false,
                radius: 2,
                // low, medium, high, ultra
                quality: 'medium',
                intensity: 1
            },

            screenSpaceReflection: {
                enable: false,
                quality: 'medium',
                maxRoughness: 0.8
            },

            colorCorrection: {
                enable: true,

                exposure: 0,

                brightness: 0,

                contrast: 1,

                saturation: 1,

                lookupTexture: ''
            },

            edge: {
                enable: false
            },

            FXAA: {
                enable: false
            }
        },

        // Temporal super sampling when the picture is still.
        temporalSuperSampling: {
            // Only enabled when postEffect is enabled
            enable: 'auto'
        }
    }
});

/***/ }),
/* 29 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ({
    defaultOption: {
        // Light is available when material.shading is not color
        light: {
            // Main light
            main: {
                shadow: false,
                // low, medium, high, ultra
                shadowQuality: 'high',

                color: '#fff',
                intensity: 1,

                alpha: 0,
                beta: 0
            },
            ambient: {
                color: '#fff',
                intensity: 0.2
            },
            ambientCubemap: {
                // Panorama environment texture,
                // Support .hdr and commmon web formats.
                texture: null,
                // Available when texture is hdr.
                exposure: 1,
                // Intensity for diffuse term
                diffuseIntensity: 0.5,
                // Intensity for specular term, only available when shading is realastic
                specularIntensity: 0.5
            }
        }
    }
});

/***/ }),
/* 30 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_plugin_Skybox__ = __webpack_require__(42);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts__);




function SceneHelper() {
}

SceneHelper.prototype = {
    constructor: SceneHelper,

    setScene: function (scene) {
        this._scene = scene;

        if (this._skybox) {
            this._skybox.attachScene(this._scene);
        }
    },

    initLight: function (rootNode) {
        this._lightRoot = rootNode;
        /**
         * @type {clay.light.Directional}
         */
        this.mainLight = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].DirectionalLight({
            shadowBias: 0.005
        });

        /**
         * @type {clay.light.Ambient}
         */
        this.ambientLight = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].AmbientLight();

        rootNode.add(this.mainLight);
        rootNode.add(this.ambientLight);
    },

    dispose: function () {
        if (this._lightRoot) {
            this._lightRoot.remove(this.mainLight);
            this._lightRoot.remove(this.ambientLight);
        }
    },

    updateLight: function (componentModel) {

        var mainLight = this.mainLight;
        var ambientLight = this.ambientLight;

        var lightModel = componentModel.getModel('light');
        var mainLightModel = lightModel.getModel('main');
        var ambientLightModel = lightModel.getModel('ambient');

        mainLight.intensity = mainLightModel.get('intensity');
        ambientLight.intensity = ambientLightModel.get('intensity');
        mainLight.color = __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].parseColor(mainLightModel.get('color')).slice(0, 3);
        ambientLight.color = __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].parseColor(ambientLightModel.get('color')).slice(0, 3);

        var alpha = mainLightModel.get('alpha') || 0;
        var beta = mainLightModel.get('beta') || 0;
        mainLight.position.setArray(__WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].directionFromAlphaBeta(alpha, beta));
        mainLight.lookAt(__WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Vector3.ZERO);

        mainLight.castShadow = mainLightModel.get('shadow');
        mainLight.shadowResolution = __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].getShadowResolution(mainLightModel.get('shadowQuality'));
    },

    updateAmbientCubemap: function (renderer, componentModel, api) {
        var ambientCubemapModel = componentModel.getModel('light.ambientCubemap');

        var textureUrl = ambientCubemapModel.get('texture');
        if (textureUrl) {
            this._cubemapLightsCache = this._cubemapLightsCache || {};
            var lights = this._cubemapLightsCache[textureUrl];
            if (!lights) {
                var self = this;
                lights = this._cubemapLightsCache[textureUrl]
                    = __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].createAmbientCubemap(ambientCubemapModel.option, renderer, api, function () {
                        // Use prefitered cubemap
                        if (self._isSkyboxFromAmbientCubemap) {
                            self._skybox.setEnvironmentMap(lights.specular.cubemap);
                        }

                        api.getZr().refresh();
                    });
            }
            this._lightRoot.add(lights.diffuse);
            this._lightRoot.add(lights.specular);

            this._currentCubemapLights = lights;
        }
        else if (this._currentCubemapLights) {
            this._lightRoot.remove(this._currentCubemapLights.diffuse);
            this._lightRoot.remove(this._currentCubemapLights.specular);
            this._currentCubemapLights = null;
        }
    },

    updateSkybox: function (renderer, componentModel, api) {
        var environmentUrl = componentModel.get('environment');

        var self = this;
        function getSkybox() {
            self._skybox = self._skybox || new __WEBPACK_IMPORTED_MODULE_1_claygl_src_plugin_Skybox__["a" /* default */]();
            return self._skybox;
        }

        var skybox = getSkybox();
        if (environmentUrl && environmentUrl !== 'none') {
            if (environmentUrl === 'auto') {
                this._isSkyboxFromAmbientCubemap = true;
                // Use environment in ambient cubemap
                if (this._currentCubemapLights) {
                    var cubemap = this._currentCubemapLights.specular.cubemap;
                    skybox.setEnvironmentMap(cubemap);
                    if (this._scene) {
                        skybox.attachScene(this._scene);
                    }
                    skybox.material.set('lod', 3);
                }
                else if (this._skybox) {
                    this._skybox.detachScene();
                }
            }
            // Is gradient or color string
            else if ((typeof environmentUrl === 'object' && environmentUrl.colorStops)
                || (typeof environmentUrl === 'string' && __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default.a.color.parse(environmentUrl))
            ) {
                this._isSkyboxFromAmbientCubemap = false;
                var texture = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Texture2D({
                    anisotropic: 8,
                    flipY: false
                });
                skybox.setEnvironmentMap(texture);
                var canvas = texture.image = document.createElement('canvas');
                canvas.width = canvas.height = 16;
                var ctx = canvas.getContext('2d');
                var rect = new __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default.a.graphic.Rect({
                    shape: { x: 0, y: 0, width: 16, height: 16 },
                    style: { fill: environmentUrl }
                });
                rect.brush(ctx);

                skybox.attachScene(this._scene);
            }
            else {
                this._isSkyboxFromAmbientCubemap = false;
                // Panorama
                var texture = __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].loadTexture(environmentUrl, api, {
                    anisotropic: 8,
                    flipY: false
                });
                skybox.setEnvironmentMap(texture);

                skybox.attachScene(this._scene);
            }
        }
        else {
            if (this._skybox) {
                this._skybox.detachScene(this._scene);
            }
            this._skybox = null;
        }

        var coordSys = componentModel.coordinateSystem;
        if (this._skybox) {
            if (coordSys && coordSys.viewGL
                && environmentUrl !== 'auto'
                && !(environmentUrl.match && environmentUrl.match(/.hdr$/))
            ) {
                var srgbDefineMethod = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
                this._skybox.material[srgbDefineMethod]('fragment', 'SRGB_DECODE');
            }
            else {
                this._skybox.material.undefine('fragment', 'SRGB_DECODE');
            }
            // var ambientCubemapUrl = environmentUrl === 'auto'
            //     ? componentModel.get('light.ambientCubemap.texture')
            //     : environmentUrl;
        }
    }
};

/* harmony default export */ __webpack_exports__["a"] = (SceneHelper);

/***/ }),
/* 31 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ({
    defaultOption: {
        shading: null,

        realisticMaterial: {
            textureTiling: 1,
            textureOffset: 0,

            detailTexture: null
        },

        lambertMaterial: {
            textureTiling: 1,
            textureOffset: 0,

            detailTexture: null
        },

        colorMaterial: {
            textureTiling: 1,
            textureOffset: 0,

            detailTexture: null
        },

        hatchingMaterial: {
            textureTiling: 1,
            textureOffset: 0,

            paperColor: '#fff'
        }
    }
});

/***/ }),
/* 32 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


var formatUtil = {};
formatUtil.getFormattedLabel = function (seriesModel, dataIndex, status, dataType, dimIndex) {
    status = status || 'normal';
    var data = seriesModel.getData(dataType);
    var itemModel = data.getItemModel(dataIndex);

    var params = seriesModel.getDataParams(dataIndex, dataType);
    if (dimIndex != null && (params.value instanceof Array)) {
        params.value = params.value[dimIndex];
    }

    var formatter = itemModel.get(status === 'normal' ? ['label', 'formatter'] : ['emphasis', 'label', 'formatter']);
    if (formatter == null) {
        formatter = itemModel.get(['label', 'formatter']);
    }
    var text;
    if (typeof formatter === 'function') {
        params.status = status;
        text = formatter(params);
    }
    else if (typeof formatter === 'string') {
        text = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.formatTpl(formatter, params);
    }
    return text;
};

/**
 * If value is not array, then convert it to array.
 * @param  {*} value
 * @return {Array} [value] or value
 */
formatUtil.normalizeToArray = function (value) {
    return value instanceof Array
        ? value
        : value == null
        ? []
        : [value];
};

/* harmony default export */ __webpack_exports__["a"] = (formatUtil);

/***/ }),
/* 33 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* unused harmony export vec4 */
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common__ = __webpack_require__(20);

/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */



/**
 * @class 4 Dimensional Vector
 * @name vec4
 */

var vec4 = {};

/**
 * Creates a new, empty vec4
 *
 * @returns {vec4} a new 4D vector
 */
vec4.create = function() {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](4);
    out[0] = 0;
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
    return out;
};

/**
 * Creates a new vec4 initialized with values from an existing vector
 *
 * @param {vec4} a vector to clone
 * @returns {vec4} a new 4D vector
 */
vec4.clone = function(a) {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](4);
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    return out;
};

/**
 * Creates a new vec4 initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {vec4} a new 4D vector
 */
vec4.fromValues = function(x, y, z, w) {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](4);
    out[0] = x;
    out[1] = y;
    out[2] = z;
    out[3] = w;
    return out;
};

/**
 * Copy the values from one vec4 to another
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the source vector
 * @returns {vec4} out
 */
vec4.copy = function(out, a) {
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    return out;
};

/**
 * Set the components of a vec4 to the given values
 *
 * @param {vec4} out the receiving vector
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {vec4} out
 */
vec4.set = function(out, x, y, z, w) {
    out[0] = x;
    out[1] = y;
    out[2] = z;
    out[3] = w;
    return out;
};

/**
 * Adds two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */
vec4.add = function(out, a, b) {
    out[0] = a[0] + b[0];
    out[1] = a[1] + b[1];
    out[2] = a[2] + b[2];
    out[3] = a[3] + b[3];
    return out;
};

/**
 * Subtracts vector b from vector a
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */
vec4.subtract = function(out, a, b) {
    out[0] = a[0] - b[0];
    out[1] = a[1] - b[1];
    out[2] = a[2] - b[2];
    out[3] = a[3] - b[3];
    return out;
};

/**
 * Alias for {@link vec4.subtract}
 * @function
 */
vec4.sub = vec4.subtract;

/**
 * Multiplies two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */
vec4.multiply = function(out, a, b) {
    out[0] = a[0] * b[0];
    out[1] = a[1] * b[1];
    out[2] = a[2] * b[2];
    out[3] = a[3] * b[3];
    return out;
};

/**
 * Alias for {@link vec4.multiply}
 * @function
 */
vec4.mul = vec4.multiply;

/**
 * Divides two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */
vec4.divide = function(out, a, b) {
    out[0] = a[0] / b[0];
    out[1] = a[1] / b[1];
    out[2] = a[2] / b[2];
    out[3] = a[3] / b[3];
    return out;
};

/**
 * Alias for {@link vec4.divide}
 * @function
 */
vec4.div = vec4.divide;

/**
 * Returns the minimum of two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */
vec4.min = function(out, a, b) {
    out[0] = Math.min(a[0], b[0]);
    out[1] = Math.min(a[1], b[1]);
    out[2] = Math.min(a[2], b[2]);
    out[3] = Math.min(a[3], b[3]);
    return out;
};

/**
 * Returns the maximum of two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */
vec4.max = function(out, a, b) {
    out[0] = Math.max(a[0], b[0]);
    out[1] = Math.max(a[1], b[1]);
    out[2] = Math.max(a[2], b[2]);
    out[3] = Math.max(a[3], b[3]);
    return out;
};

/**
 * Scales a vec4 by a scalar number
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {vec4} out
 */
vec4.scale = function(out, a, b) {
    out[0] = a[0] * b;
    out[1] = a[1] * b;
    out[2] = a[2] * b;
    out[3] = a[3] * b;
    return out;
};

/**
 * Adds two vec4's after scaling the second operand by a scalar value
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @param {Number} scale the amount to scale b by before adding
 * @returns {vec4} out
 */
vec4.scaleAndAdd = function(out, a, b, scale) {
    out[0] = a[0] + (b[0] * scale);
    out[1] = a[1] + (b[1] * scale);
    out[2] = a[2] + (b[2] * scale);
    out[3] = a[3] + (b[3] * scale);
    return out;
};

/**
 * Calculates the euclidian distance between two vec4's
 *
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {Number} distance between a and b
 */
vec4.distance = function(a, b) {
    var x = b[0] - a[0],
        y = b[1] - a[1],
        z = b[2] - a[2],
        w = b[3] - a[3];
    return Math.sqrt(x*x + y*y + z*z + w*w);
};

/**
 * Alias for {@link vec4.distance}
 * @function
 */
vec4.dist = vec4.distance;

/**
 * Calculates the squared euclidian distance between two vec4's
 *
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {Number} squared distance between a and b
 */
vec4.squaredDistance = function(a, b) {
    var x = b[0] - a[0],
        y = b[1] - a[1],
        z = b[2] - a[2],
        w = b[3] - a[3];
    return x*x + y*y + z*z + w*w;
};

/**
 * Alias for {@link vec4.squaredDistance}
 * @function
 */
vec4.sqrDist = vec4.squaredDistance;

/**
 * Calculates the length of a vec4
 *
 * @param {vec4} a vector to calculate length of
 * @returns {Number} length of a
 */
vec4.length = function (a) {
    var x = a[0],
        y = a[1],
        z = a[2],
        w = a[3];
    return Math.sqrt(x*x + y*y + z*z + w*w);
};

/**
 * Alias for {@link vec4.length}
 * @function
 */
vec4.len = vec4.length;

/**
 * Calculates the squared length of a vec4
 *
 * @param {vec4} a vector to calculate squared length of
 * @returns {Number} squared length of a
 */
vec4.squaredLength = function (a) {
    var x = a[0],
        y = a[1],
        z = a[2],
        w = a[3];
    return x*x + y*y + z*z + w*w;
};

/**
 * Alias for {@link vec4.squaredLength}
 * @function
 */
vec4.sqrLen = vec4.squaredLength;

/**
 * Negates the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a vector to negate
 * @returns {vec4} out
 */
vec4.negate = function(out, a) {
    out[0] = -a[0];
    out[1] = -a[1];
    out[2] = -a[2];
    out[3] = -a[3];
    return out;
};

/**
 * Returns the inverse of the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a vector to invert
 * @returns {vec4} out
 */
vec4.inverse = function(out, a) {
  out[0] = 1.0 / a[0];
  out[1] = 1.0 / a[1];
  out[2] = 1.0 / a[2];
  out[3] = 1.0 / a[3];
  return out;
};

/**
 * Normalize a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a vector to normalize
 * @returns {vec4} out
 */
vec4.normalize = function(out, a) {
    var x = a[0],
        y = a[1],
        z = a[2],
        w = a[3];
    var len = x*x + y*y + z*z + w*w;
    if (len > 0) {
        len = 1 / Math.sqrt(len);
        out[0] = a[0] * len;
        out[1] = a[1] * len;
        out[2] = a[2] * len;
        out[3] = a[3] * len;
    }
    return out;
};

/**
 * Calculates the dot product of two vec4's
 *
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {Number} dot product of a and b
 */
vec4.dot = function (a, b) {
    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
};

/**
 * Performs a linear interpolation between two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @param {Number} t interpolation amount between the two inputs
 * @returns {vec4} out
 */
vec4.lerp = function (out, a, b, t) {
    var ax = a[0],
        ay = a[1],
        az = a[2],
        aw = a[3];
    out[0] = ax + t * (b[0] - ax);
    out[1] = ay + t * (b[1] - ay);
    out[2] = az + t * (b[2] - az);
    out[3] = aw + t * (b[3] - aw);
    return out;
};

/**
 * Generates a random vector with the given scale
 *
 * @param {vec4} out the receiving vector
 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
 * @returns {vec4} out
 */
vec4.random = function (out, scale) {
    scale = scale || 1.0;

    //TODO: This is a pretty awful way of doing this. Find something better.
    out[0] = Object(__WEBPACK_IMPORTED_MODULE_0__common__["c" /* GLMAT_RANDOM */])();
    out[1] = Object(__WEBPACK_IMPORTED_MODULE_0__common__["c" /* GLMAT_RANDOM */])();
    out[2] = Object(__WEBPACK_IMPORTED_MODULE_0__common__["c" /* GLMAT_RANDOM */])();
    out[3] = Object(__WEBPACK_IMPORTED_MODULE_0__common__["c" /* GLMAT_RANDOM */])();
    vec4.normalize(out, out);
    vec4.scale(out, out, scale);
    return out;
};

/**
 * Transforms the vec4 with a mat4.
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the vector to transform
 * @param {mat4} m matrix to transform with
 * @returns {vec4} out
 */
vec4.transformMat4 = function(out, a, m) {
    var x = a[0], y = a[1], z = a[2], w = a[3];
    out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
    out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
    out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
    out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
    return out;
};

/**
 * Transforms the vec4 with a quat
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the vector to transform
 * @param {quat} q quaternion to transform with
 * @returns {vec4} out
 */
vec4.transformQuat = function(out, a, q) {
    var x = a[0], y = a[1], z = a[2],
        qx = q[0], qy = q[1], qz = q[2], qw = q[3],

        // calculate quat * vec
        ix = qw * x + qy * z - qz * y,
        iy = qw * y + qz * x - qx * z,
        iz = qw * z + qx * y - qy * x,
        iw = -qx * x - qy * y - qz * z;

    // calculate result * inverse quat
    out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
    out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
    out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
    return out;
};

/**
 * Perform some operation over an array of vec4s.
 *
 * @param {Array} a the array of vectors to iterate over
 * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed
 * @param {Number} offset Number of elements to skip at the beginning of the array
 * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array
 * @param {Function} fn Function to call for each vector in the array
 * @param {Object} [arg] additional argument to pass to fn
 * @returns {Array} a
 * @function
 */
vec4.forEach = (function() {
    var vec = vec4.create();

    return function(a, stride, offset, count, fn, arg) {
        var i, l;
        if(!stride) {
            stride = 4;
        }

        if(!offset) {
            offset = 0;
        }

        if(count) {
            l = Math.min((count * stride) + offset, a.length);
        } else {
            l = a.length;
        }

        for(i = offset; i < l; i += stride) {
            vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2]; vec[3] = a[i+3];
            fn(vec, vec, arg);
            a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2]; a[i+3] = vec[3];
        }

        return a;
    };
})();

/* harmony default export */ __webpack_exports__["a"] = (vec4);

/***/ }),
/* 34 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common__ = __webpack_require__(20);

/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */



/**
 * @class 3x3 Matrix
 * @name mat3
 */

var mat3 = {};

/**
 * Creates a new identity mat3
 *
 * @returns {mat3} a new 3x3 matrix
 */
mat3.create = function() {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](9);
    out[0] = 1;
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
    out[4] = 1;
    out[5] = 0;
    out[6] = 0;
    out[7] = 0;
    out[8] = 1;
    return out;
};

/**
 * Copies the upper-left 3x3 values into the given mat3.
 *
 * @param {mat3} out the receiving 3x3 matrix
 * @param {mat4} a   the source 4x4 matrix
 * @returns {mat3} out
 */
mat3.fromMat4 = function(out, a) {
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[4];
    out[4] = a[5];
    out[5] = a[6];
    out[6] = a[8];
    out[7] = a[9];
    out[8] = a[10];
    return out;
};

/**
 * Creates a new mat3 initialized with values from an existing matrix
 *
 * @param {mat3} a matrix to clone
 * @returns {mat3} a new 3x3 matrix
 */
mat3.clone = function(a) {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](9);
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    out[4] = a[4];
    out[5] = a[5];
    out[6] = a[6];
    out[7] = a[7];
    out[8] = a[8];
    return out;
};

/**
 * Copy the values from one mat3 to another
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the source matrix
 * @returns {mat3} out
 */
mat3.copy = function(out, a) {
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    out[4] = a[4];
    out[5] = a[5];
    out[6] = a[6];
    out[7] = a[7];
    out[8] = a[8];
    return out;
};

/**
 * Set a mat3 to the identity matrix
 *
 * @param {mat3} out the receiving matrix
 * @returns {mat3} out
 */
mat3.identity = function(out) {
    out[0] = 1;
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
    out[4] = 1;
    out[5] = 0;
    out[6] = 0;
    out[7] = 0;
    out[8] = 1;
    return out;
};

/**
 * Transpose the values of a mat3
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the source matrix
 * @returns {mat3} out
 */
mat3.transpose = function(out, a) {
    // If we are transposing ourselves we can skip a few steps but have to cache some values
    if (out === a) {
        var a01 = a[1], a02 = a[2], a12 = a[5];
        out[1] = a[3];
        out[2] = a[6];
        out[3] = a01;
        out[5] = a[7];
        out[6] = a02;
        out[7] = a12;
    } else {
        out[0] = a[0];
        out[1] = a[3];
        out[2] = a[6];
        out[3] = a[1];
        out[4] = a[4];
        out[5] = a[7];
        out[6] = a[2];
        out[7] = a[5];
        out[8] = a[8];
    }

    return out;
};

/**
 * Inverts a mat3
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the source matrix
 * @returns {mat3} out
 */
mat3.invert = function(out, a) {
    var a00 = a[0], a01 = a[1], a02 = a[2],
        a10 = a[3], a11 = a[4], a12 = a[5],
        a20 = a[6], a21 = a[7], a22 = a[8],

        b01 = a22 * a11 - a12 * a21,
        b11 = -a22 * a10 + a12 * a20,
        b21 = a21 * a10 - a11 * a20,

        // Calculate the determinant
        det = a00 * b01 + a01 * b11 + a02 * b21;

    if (!det) {
        return null;
    }
    det = 1.0 / det;

    out[0] = b01 * det;
    out[1] = (-a22 * a01 + a02 * a21) * det;
    out[2] = (a12 * a01 - a02 * a11) * det;
    out[3] = b11 * det;
    out[4] = (a22 * a00 - a02 * a20) * det;
    out[5] = (-a12 * a00 + a02 * a10) * det;
    out[6] = b21 * det;
    out[7] = (-a21 * a00 + a01 * a20) * det;
    out[8] = (a11 * a00 - a01 * a10) * det;
    return out;
};

/**
 * Calculates the adjugate of a mat3
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the source matrix
 * @returns {mat3} out
 */
mat3.adjoint = function(out, a) {
    var a00 = a[0], a01 = a[1], a02 = a[2],
        a10 = a[3], a11 = a[4], a12 = a[5],
        a20 = a[6], a21 = a[7], a22 = a[8];

    out[0] = (a11 * a22 - a12 * a21);
    out[1] = (a02 * a21 - a01 * a22);
    out[2] = (a01 * a12 - a02 * a11);
    out[3] = (a12 * a20 - a10 * a22);
    out[4] = (a00 * a22 - a02 * a20);
    out[5] = (a02 * a10 - a00 * a12);
    out[6] = (a10 * a21 - a11 * a20);
    out[7] = (a01 * a20 - a00 * a21);
    out[8] = (a00 * a11 - a01 * a10);
    return out;
};

/**
 * Calculates the determinant of a mat3
 *
 * @param {mat3} a the source matrix
 * @returns {Number} determinant of a
 */
mat3.determinant = function (a) {
    var a00 = a[0], a01 = a[1], a02 = a[2],
        a10 = a[3], a11 = a[4], a12 = a[5],
        a20 = a[6], a21 = a[7], a22 = a[8];

    return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);
};

/**
 * Multiplies two mat3's
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the first operand
 * @param {mat3} b the second operand
 * @returns {mat3} out
 */
mat3.multiply = function (out, a, b) {
    var a00 = a[0], a01 = a[1], a02 = a[2],
        a10 = a[3], a11 = a[4], a12 = a[5],
        a20 = a[6], a21 = a[7], a22 = a[8],

        b00 = b[0], b01 = b[1], b02 = b[2],
        b10 = b[3], b11 = b[4], b12 = b[5],
        b20 = b[6], b21 = b[7], b22 = b[8];

    out[0] = b00 * a00 + b01 * a10 + b02 * a20;
    out[1] = b00 * a01 + b01 * a11 + b02 * a21;
    out[2] = b00 * a02 + b01 * a12 + b02 * a22;

    out[3] = b10 * a00 + b11 * a10 + b12 * a20;
    out[4] = b10 * a01 + b11 * a11 + b12 * a21;
    out[5] = b10 * a02 + b11 * a12 + b12 * a22;

    out[6] = b20 * a00 + b21 * a10 + b22 * a20;
    out[7] = b20 * a01 + b21 * a11 + b22 * a21;
    out[8] = b20 * a02 + b21 * a12 + b22 * a22;
    return out;
};

/**
 * Alias for {@link mat3.multiply}
 * @function
 */
mat3.mul = mat3.multiply;

/**
 * Translate a mat3 by the given vector
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the matrix to translate
 * @param {vec2} v vector to translate by
 * @returns {mat3} out
 */
mat3.translate = function(out, a, v) {
    var a00 = a[0], a01 = a[1], a02 = a[2],
        a10 = a[3], a11 = a[4], a12 = a[5],
        a20 = a[6], a21 = a[7], a22 = a[8],
        x = v[0], y = v[1];

    out[0] = a00;
    out[1] = a01;
    out[2] = a02;

    out[3] = a10;
    out[4] = a11;
    out[5] = a12;

    out[6] = x * a00 + y * a10 + a20;
    out[7] = x * a01 + y * a11 + a21;
    out[8] = x * a02 + y * a12 + a22;
    return out;
};

/**
 * Rotates a mat3 by the given angle
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat3} out
 */
mat3.rotate = function (out, a, rad) {
    var a00 = a[0], a01 = a[1], a02 = a[2],
        a10 = a[3], a11 = a[4], a12 = a[5],
        a20 = a[6], a21 = a[7], a22 = a[8],

        s = Math.sin(rad),
        c = Math.cos(rad);

    out[0] = c * a00 + s * a10;
    out[1] = c * a01 + s * a11;
    out[2] = c * a02 + s * a12;

    out[3] = c * a10 - s * a00;
    out[4] = c * a11 - s * a01;
    out[5] = c * a12 - s * a02;

    out[6] = a20;
    out[7] = a21;
    out[8] = a22;
    return out;
};

/**
 * Scales the mat3 by the dimensions in the given vec2
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the matrix to rotate
 * @param {vec2} v the vec2 to scale the matrix by
 * @returns {mat3} out
 **/
mat3.scale = function(out, a, v) {
    var x = v[0], y = v[1];

    out[0] = x * a[0];
    out[1] = x * a[1];
    out[2] = x * a[2];

    out[3] = y * a[3];
    out[4] = y * a[4];
    out[5] = y * a[5];

    out[6] = a[6];
    out[7] = a[7];
    out[8] = a[8];
    return out;
};

/**
 * Copies the values from a mat2d into a mat3
 *
 * @param {mat3} out the receiving matrix
 * @param {mat2d} a the matrix to copy
 * @returns {mat3} out
 **/
mat3.fromMat2d = function(out, a) {
    out[0] = a[0];
    out[1] = a[1];
    out[2] = 0;

    out[3] = a[2];
    out[4] = a[3];
    out[5] = 0;

    out[6] = a[4];
    out[7] = a[5];
    out[8] = 1;
    return out;
};

/**
* Calculates a 3x3 matrix from the given quaternion
*
* @param {mat3} out mat3 receiving operation result
* @param {quat} q Quaternion to create matrix from
*
* @returns {mat3} out
*/
mat3.fromQuat = function (out, q) {
    var x = q[0], y = q[1], z = q[2], w = q[3],
        x2 = x + x,
        y2 = y + y,
        z2 = z + z,

        xx = x * x2,
        yx = y * x2,
        yy = y * y2,
        zx = z * x2,
        zy = z * y2,
        zz = z * z2,
        wx = w * x2,
        wy = w * y2,
        wz = w * z2;

    out[0] = 1 - yy - zz;
    out[3] = yx - wz;
    out[6] = zx + wy;

    out[1] = yx + wz;
    out[4] = 1 - xx - zz;
    out[7] = zy - wx;

    out[2] = zx - wy;
    out[5] = zy + wx;
    out[8] = 1 - xx - yy;

    return out;
};

/**
* Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
*
* @param {mat3} out mat3 receiving operation result
* @param {mat4} a Mat4 to derive the normal matrix from
*
* @returns {mat3} out
*/
mat3.normalFromMat4 = function (out, a) {
    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],

        b00 = a00 * a11 - a01 * a10,
        b01 = a00 * a12 - a02 * a10,
        b02 = a00 * a13 - a03 * a10,
        b03 = a01 * a12 - a02 * a11,
        b04 = a01 * a13 - a03 * a11,
        b05 = a02 * a13 - a03 * a12,
        b06 = a20 * a31 - a21 * a30,
        b07 = a20 * a32 - a22 * a30,
        b08 = a20 * a33 - a23 * a30,
        b09 = a21 * a32 - a22 * a31,
        b10 = a21 * a33 - a23 * a31,
        b11 = a22 * a33 - a23 * a32,

        // Calculate the determinant
        det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;

    if (!det) {
        return null;
    }
    det = 1.0 / det;

    out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
    out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
    out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;

    out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
    out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
    out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;

    out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
    out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
    out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;

    return out;
};

/**
 * Returns Frobenius norm of a mat3
 *
 * @param {mat3} a the matrix to calculate Frobenius norm of
 * @returns {Number} Frobenius norm
 */
mat3.frob = function (a) {
    return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2)))
};


/* harmony default export */ __webpack_exports__["a"] = (mat3);

/***/ }),
/* 35 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__math_Quaternion__ = __webpack_require__(56);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__glmatrix_mat4__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__math_BoundingBox__ = __webpack_require__(18);







var nameId = 0;

/**
 * @constructor clay.Node
 * @extends clay.core.Base
 */
var Node = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(/** @lends clay.Node# */{
    /**
     * Scene node name
     * @type {string}
     */
    name: '',

    /**
     * Position relative to its parent node. aka translation.
     * @type {clay.Vector3}
     */
    position: null,

    /**
     * Rotation relative to its parent node. Represented by a quaternion
     * @type {clay.Quaternion}
     */
    rotation: null,

    /**
     * Scale relative to its parent node
     * @type {clay.Vector3}
     */
    scale: null,

    /**
     * Affine transform matrix relative to its root scene.
     * @type {clay.Matrix4}
     */
    worldTransform: null,

    /**
     * Affine transform matrix relative to its parent node.
     * Composited with position, rotation and scale.
     * @type {clay.Matrix4}
     */
    localTransform: null,

    /**
     * If the local transform is update from SRT(scale, rotation, translation, which is position here) each frame
     * @type {boolean}
     */
    autoUpdateLocalTransform: true,

    /**
     * Parent of current scene node
     * @type {?clay.Node}
     * @private
     */
    _parent: null,
    /**
     * The root scene mounted. Null if it is a isolated node
     * @type {?clay.Scene}
     * @private
     */
    _scene: null,
    /**
     * @type {boolean}
     * @private
     */
    _needsUpdateWorldTransform: true,
    /**
     * @type {boolean}
     * @private
     */
    _inIterating: false,

    // Depth for transparent list sorting
    __depth: 0

}, function () {

    if (!this.name) {
        this.name = (this.type || 'NODE') + '_' + (nameId++);
    }

    if (!this.position) {
        this.position = new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */]();
    }
    if (!this.rotation) {
        this.rotation = new __WEBPACK_IMPORTED_MODULE_2__math_Quaternion__["a" /* default */]();
    }
    if (!this.scale) {
        this.scale = new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */](1, 1, 1);
    }

    this.worldTransform = new __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */]();
    this.localTransform = new __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */]();

    this._children = [];

},
/**@lends clay.Node.prototype. */
{

    /**
     * @type {?clay.Vector3}
     * @instance
     */
    target: null,
    /**
     * If node and its chilren invisible
     * @type {boolean}
     * @instance
     */
    invisible: false,

    /**
     * If Node is a skinned mesh
     * @return {boolean}
     */
    isSkinnedMesh: function () {
        return false;
    },
    /**
     * Return true if it is a renderable scene node, like Mesh and ParticleSystem
     * @return {boolean}
     */
    isRenderable: function () {
        return false;
    },

    /**
     * Set the name of the scene node
     * @param {string} name
     */
    setName: function (name) {
        var scene = this._scene;
        if (scene) {
            var nodeRepository = scene._nodeRepository;
            delete nodeRepository[this.name];
            nodeRepository[name] = this;
        }
        this.name = name;
    },

    /**
     * Add a child node
     * @param {clay.Node} node
     */
    add: function (node) {
        var originalParent = node._parent;
        if (originalParent === this) {
            return;
        }
        if (originalParent) {
            originalParent.remove(node);
        }
        node._parent = this;
        this._children.push(node);

        var scene = this._scene;
        if (scene && scene !== node.scene) {
            node.traverse(this._addSelfToScene, this);
        }
        // Mark children needs update transform
        // In case child are remove and added again after parent moved
        node._needsUpdateWorldTransform = true;
    },

    /**
     * Remove the given child scene node
     * @param {clay.Node} node
     */
    remove: function (node) {
        var children = this._children;
        var idx = children.indexOf(node);
        if (idx < 0) {
            return;
        }

        children.splice(idx, 1);
        node._parent = null;

        if (this._scene) {
            node.traverse(this._removeSelfFromScene, this);
        }
    },

    /**
     * Remove all children
     */
    removeAll: function () {
        var children = this._children;

        for (var idx = 0; idx < children.length; idx++) {
            children[idx]._parent = null;

            if (this._scene) {
                children[idx].traverse(this._removeSelfFromScene, this);
            }
        }

        this._children = [];
    },

    /**
     * Get the scene mounted
     * @return {clay.Scene}
     */
    getScene: function () {
        return this._scene;
    },

    /**
     * Get parent node
     * @return {clay.Scene}
     */
    getParent: function () {
        return this._parent;
    },

    _removeSelfFromScene: function (descendant) {
        descendant._scene.removeFromScene(descendant);
        descendant._scene = null;
    },

    _addSelfToScene: function (descendant) {
        this._scene.addToScene(descendant);
        descendant._scene = this._scene;
    },

    /**
     * Return true if it is ancestor of the given scene node
     * @param {clay.Node} node
     */
    isAncestor: function (node) {
        var parent = node._parent;
        while(parent) {
            if (parent === this) {
                return true;
            }
            parent = parent._parent;
        }
        return false;
    },

    /**
     * Get a new created array of all children nodes
     * @return {clay.Node[]}
     */
    children: function () {
        return this._children.slice();
    },

    /**
     * Get child scene node at given index.
     * @param {number} idx
     * @return {clay.Node}
     */
    childAt: function (idx) {
        return this._children[idx];
    },

    /**
     * Get first child with the given name
     * @param {string} name
     * @return {clay.Node}
     */
    getChildByName: function (name) {
        var children = this._children;
        for (var i = 0; i < children.length; i++) {
            if (children[i].name === name) {
                return children[i];
            }
        }
    },

    /**
     * Get first descendant have the given name
     * @param {string} name
     * @return {clay.Node}
     */
    getDescendantByName: function (name) {
        var children = this._children;
        for (var i = 0; i < children.length; i++) {
            var child = children[i];
            if (child.name === name) {
                return child;
            } else {
                var res = child.getDescendantByName(name);
                if (res) {
                    return res;
                }
            }
        }
    },

    /**
     * Query descendant node by path
     * @param {string} path
     * @return {clay.Node}
     * @example
     *  node.queryNode('root/parent/child');
     */
    queryNode: function (path) {
        if (!path) {
            return;
        }
        // TODO Name have slash ?
        var pathArr = path.split('/');
        var current = this;
        for (var i = 0; i < pathArr.length; i++) {
            var name = pathArr[i];
            // Skip empty
            if (!name) {
                continue;
            }
            var found = false;
            var children = current._children;
            for (var j = 0; j < children.length; j++) {
                var child = children[j];
                if (child.name === name) {
                    current = child;
                    found = true;
                    break;
                }
            }
            // Early return if not found
            if (!found) {
                return;
            }
        }

        return current;
    },

    /**
     * Get query path, relative to rootNode(default is scene)
     * @param {clay.Node} [rootNode]
     * @return {string}
     */
    getPath: function (rootNode) {
        if (!this._parent) {
            return '/';
        }

        var current = this._parent;
        var path = this.name;
        while (current._parent) {
            path = current.name + '/' + path;
            if (current._parent == rootNode) {
                break;
            }
            current = current._parent;
        }
        if (!current._parent && rootNode) {
            return null;
        }
        return path;
    },

    /**
     * Depth first traverse all its descendant scene nodes.
     *
     * **WARN** Don't do `add`, `remove` operation in the callback during traverse.
     * @param {Function} callback
     * @param {Node} [context]
     */
    traverse: function (callback, context) {
        callback.call(context, this);
        var _children = this._children;
        for(var i = 0, len = _children.length; i < len; i++) {
            _children[i].traverse(callback, context);
        }
    },

    /**
     * Traverse all children nodes.
     *
     * **WARN** DON'T do `add`, `remove` operation in the callback during iteration.
     *
     * @param {Function} callback
     * @param {Node} [context]
     */
    eachChild: function (callback, context) {
        var _children = this._children;
        for(var i = 0, len = _children.length; i < len; i++) {
            var child = _children[i];
            callback.call(context, child, i);
        }
    },

    /**
     * Set the local transform and decompose to SRT
     * @param {clay.Matrix4} matrix
     */
    setLocalTransform: function (matrix) {
        __WEBPACK_IMPORTED_MODULE_4__glmatrix_mat4__["a" /* default */].copy(this.localTransform.array, matrix.array);
        this.decomposeLocalTransform();
    },

    /**
     * Decompose the local transform to SRT
     */
    decomposeLocalTransform: function (keepScale) {
        var scale = !keepScale ? this.scale: null;
        this.localTransform.decomposeMatrix(scale, this.rotation, this.position);
    },

    /**
     * Set the world transform and decompose to SRT
     * @param {clay.Matrix4} matrix
     */
    setWorldTransform: function (matrix) {
        __WEBPACK_IMPORTED_MODULE_4__glmatrix_mat4__["a" /* default */].copy(this.worldTransform.array, matrix.array);
        this.decomposeWorldTransform();
    },

    /**
     * Decompose the world transform to SRT
     * @function
     */
    decomposeWorldTransform: (function () {

        var tmp = __WEBPACK_IMPORTED_MODULE_4__glmatrix_mat4__["a" /* default */].create();

        return function (keepScale) {
            var localTransform = this.localTransform;
            var worldTransform = this.worldTransform;
            // Assume world transform is updated
            if (this._parent) {
                __WEBPACK_IMPORTED_MODULE_4__glmatrix_mat4__["a" /* default */].invert(tmp, this._parent.worldTransform.array);
                __WEBPACK_IMPORTED_MODULE_4__glmatrix_mat4__["a" /* default */].multiply(localTransform.array, tmp, worldTransform.array);
            } else {
                __WEBPACK_IMPORTED_MODULE_4__glmatrix_mat4__["a" /* default */].copy(localTransform.array, worldTransform.array);
            }
            var scale = !keepScale ? this.scale: null;
            localTransform.decomposeMatrix(scale, this.rotation, this.position);
        };
    })(),

    transformNeedsUpdate: function () {
        return this.position._dirty
            || this.rotation._dirty
            || this.scale._dirty;
    },

    /**
     * Update local transform from SRT
     * Notice that local transform will not be updated if _dirty mark of position, rotation, scale is all false
     */
    updateLocalTransform: function () {
        var position = this.position;
        var rotation = this.rotation;
        var scale = this.scale;

        if (this.transformNeedsUpdate()) {
            var m = this.localTransform.array;

            // Transform order, scale->rotation->position
            __WEBPACK_IMPORTED_MODULE_4__glmatrix_mat4__["a" /* default */].fromRotationTranslation(m, rotation.array, position.array);

            __WEBPACK_IMPORTED_MODULE_4__glmatrix_mat4__["a" /* default */].scale(m, m, scale.array);

            rotation._dirty = false;
            scale._dirty = false;
            position._dirty = false;

            this._needsUpdateWorldTransform = true;
        }
    },

    /**
     * Update world transform, assume its parent world transform have been updated
     * @private
     */
    _updateWorldTransformTopDown: function () {
        var localTransform = this.localTransform.array;
        var worldTransform = this.worldTransform.array;
        if (this._parent) {
            __WEBPACK_IMPORTED_MODULE_4__glmatrix_mat4__["a" /* default */].multiplyAffine(
                worldTransform,
                this._parent.worldTransform.array,
                localTransform
            );
        }
        else {
            __WEBPACK_IMPORTED_MODULE_4__glmatrix_mat4__["a" /* default */].copy(worldTransform, localTransform);
        }
    },

    /**
     * Update world transform before whole scene is updated.
     */
    updateWorldTransform: function () {
        // Find the root node which transform needs update;
        var rootNodeIsDirty = this;
        while (rootNodeIsDirty && rootNodeIsDirty.getParent()
            && rootNodeIsDirty.getParent().transformNeedsUpdate()
        ) {
            rootNodeIsDirty = rootNodeIsDirty.getParent();
        }
        rootNodeIsDirty.update();
    },

    /**
     * Update local transform and world transform recursively
     * @param {boolean} forceUpdateWorld
     */
    update: function (forceUpdateWorld) {
        if (this.autoUpdateLocalTransform) {
            this.updateLocalTransform();
        }
        else {
            // Transform is manually setted
            forceUpdateWorld = true;
        }

        if (forceUpdateWorld || this._needsUpdateWorldTransform) {
            this._updateWorldTransformTopDown();
            forceUpdateWorld = true;
            this._needsUpdateWorldTransform = false;
        }

        var children = this._children;
        for(var i = 0, len = children.length; i < len; i++) {
            children[i].update(forceUpdateWorld);
        }
    },

    /**
     * Get bounding box of node
     * @param  {Function} [filter]
     * @param  {clay.BoundingBox} [out]
     * @return {clay.BoundingBox}
     */
    // TODO Skinning
    getBoundingBox: (function () {
        function defaultFilter (el) {
            return !el.invisible && el.geometry;
        }
        var tmpBBox = new __WEBPACK_IMPORTED_MODULE_5__math_BoundingBox__["a" /* default */]();
        var tmpMat4 = new __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */]();
        var invWorldTransform = new __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */]();
        return function (filter, out) {
            out = out || new __WEBPACK_IMPORTED_MODULE_5__math_BoundingBox__["a" /* default */]();
            filter = filter || defaultFilter;

            if (this._parent) {
                __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */].invert(invWorldTransform, this._parent.worldTransform);
            }
            else {
                __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */].identity(invWorldTransform);
            }

            this.traverse(function (mesh) {
                if (mesh.geometry && mesh.geometry.boundingBox) {
                    tmpBBox.copy(mesh.geometry.boundingBox);
                    __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */].multiply(tmpMat4, invWorldTransform, mesh.worldTransform);
                    tmpBBox.applyTransform(tmpMat4);
                    out.union(tmpBBox);
                }
            }, this, defaultFilter);

            return out;
        };
    })(),

    /**
     * Get world position, extracted from world transform
     * @param  {clay.Vector3} [out]
     * @return {clay.Vector3}
     */
    getWorldPosition: function (out) {
        // PENDING
        if (this.transformNeedsUpdate()) {
            this.updateWorldTransform();
        }
        var m = this.worldTransform.array;
        if (out) {
            var arr = out.array;
            arr[0] = m[12];
            arr[1] = m[13];
            arr[2] = m[14];
            return out;
        }
        else {
            return new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */](m[12], m[13], m[14]);
        }
    },

    /**
     * Clone a new node
     * @return {Node}
     */
    clone: function () {
        var node = new this.constructor();

        var children = this._children;

        node.setName(this.name);
        node.position.copy(this.position);
        node.rotation.copy(this.rotation);
        node.scale.copy(this.scale);

        for (var i = 0; i < children.length; i++) {
            node.add(children[i].clone());
        }

        return node;
    },

    /**
     * Rotate the node around a axis by angle degrees, axis passes through point
     * @param {clay.Vector3} point Center point
     * @param {clay.Vector3} axis  Center axis
     * @param {number}       angle Rotation angle
     * @see http://docs.unity3d.com/Documentation/ScriptReference/Transform.RotateAround.html
     * @function
     */
    rotateAround: (function () {
        var v = new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */]();
        var RTMatrix = new __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */]();

        // TODO improve performance
        return function (point, axis, angle) {

            v.copy(this.position).subtract(point);

            var localTransform = this.localTransform;
            localTransform.identity();
            // parent node
            localTransform.translate(point);
            localTransform.rotate(angle, axis);

            RTMatrix.fromRotationTranslation(this.rotation, v);
            localTransform.multiply(RTMatrix);
            localTransform.scale(this.scale);

            this.decomposeLocalTransform();
            this._needsUpdateWorldTransform = true;
        };
    })(),

    /**
     * @param {clay.Vector3} target
     * @param {clay.Vector3} [up]
     * @see http://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml
     * @function
     */
    lookAt: (function () {
        var m = new __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */]();
        return function (target, up) {
            m.lookAt(this.position, target, up || this.localTransform.y).invert();
            this.setLocalTransform(m);

            this.target = target;
        };
    })()
});

/* harmony default export */ __webpack_exports__["a"] = (Node);


/***/ }),
/* 36 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Node__ = __webpack_require__(35);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Light__ = __webpack_require__(24);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Camera__ = __webpack_require__(58);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__core_util__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__glmatrix_mat4__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__core_LRU__ = __webpack_require__(69);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__math_Matrix4__ = __webpack_require__(9);









var IDENTITY = __WEBPACK_IMPORTED_MODULE_5__glmatrix_mat4__["a" /* default */].create();
var WORLDVIEW = __WEBPACK_IMPORTED_MODULE_5__glmatrix_mat4__["a" /* default */].create();

var programKeyCache = {};

function getProgramKey(lightNumbers) {
    var defineStr = [];
    var lightTypes = Object.keys(lightNumbers);
    lightTypes.sort();
    for (var i = 0; i < lightTypes.length; i++) {
        var lightType = lightTypes[i];
        defineStr.push(lightType + ' ' + lightNumbers[lightType]);
    }
    var key = defineStr.join('\n');

    if (programKeyCache[key]) {
        return programKeyCache[key];
    }

    var id = __WEBPACK_IMPORTED_MODULE_4__core_util__["a" /* default */].genGUID();
    programKeyCache[key] = id;
    return id;
}

function RenderList() {

    this.opaque = [];
    this.transparent = [];

    this._opaqueCount = 0;
    this._transparentCount = 0;
}

RenderList.prototype.startCount = function () {
    this._opaqueCount = 0;
    this._transparentCount = 0;
};

RenderList.prototype.add = function (object, isTransparent) {
    if (isTransparent) {
        this.transparent[this._transparentCount++] = object;
    }
    else {
        this.opaque[this._opaqueCount++] = object;
    }
};

RenderList.prototype.endCount = function () {
    this.transparent.length = this._transparentCount;
    this.opaque.length = this._opaqueCount;
};

/**
 * @typedef {Object} clay.Scene.RenderList
 * @property {Array.<clay.Renderable>} opaque
 * @property {Array.<clay.Renderable>} transparent
 */

/**
 * @constructor clay.Scene
 * @extends clay.Node
 */
var Scene = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].extend(function () {
    return /** @lends clay.Scene# */ {
        /**
         * Global material of scene
         * @type {clay.Material}
         */
        material: null,

        lights: [],

        /**
         * Scene bounding box in view space.
         * Used when camera needs to adujst the near and far plane automatically
         * so that the view frustum contains the visible objects as tightly as possible.
         * Notice:
         *  It is updated after rendering (in the step of frustum culling passingly). So may be not so accurate, but saves a lot of calculation
         *
         * @type {clay.BoundingBox}
         */
        viewBoundingBoxLastFrame: new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */](),

        // Uniforms for shadow map.
        shadowUniforms: {},

        _cameraList: [],

        // Properties to save the light information in the scene
        // Will be set in the render function
        _lightUniforms: {},

        _previousLightNumber: {},

        _lightNumber: {
            // groupId: {
                // POINT_LIGHT: 0,
                // DIRECTIONAL_LIGHT: 0,
                // SPOT_LIGHT: 0,
                // AMBIENT_LIGHT: 0,
                // AMBIENT_SH_LIGHT: 0
            // }
        },

        _lightProgramKeys: {},

        _nodeRepository: {},

        _renderLists: new __WEBPACK_IMPORTED_MODULE_6__core_LRU__["a" /* default */](20)

    };
}, function () {
    this._scene = this;
},
/** @lends clay.Scene.prototype. */
{

    // Add node to scene
    addToScene: function (node) {
        if (node instanceof __WEBPACK_IMPORTED_MODULE_2__Camera__["a" /* default */]) {
            if (this._cameraList.length > 0) {
                console.warn('Found multiple camera in one scene. Use the fist one.');
            }
            this._cameraList.push(node);
        }
        else if (node instanceof __WEBPACK_IMPORTED_MODULE_1__Light__["a" /* default */]) {
            this.lights.push(node);
        }
        if (node.name) {
            this._nodeRepository[node.name] = node;
        }
    },

    // Remove node from scene
    removeFromScene: function (node) {
        var idx;
        if (node instanceof __WEBPACK_IMPORTED_MODULE_2__Camera__["a" /* default */]) {
            idx = this._cameraList.indexOf(node);
            if (idx >= 0) {
                this._cameraList.splice(idx, 1);
            }
        }
        else if (node instanceof __WEBPACK_IMPORTED_MODULE_1__Light__["a" /* default */]) {
            idx = this.lights.indexOf(node);
            if (idx >= 0) {
                this.lights.splice(idx, 1);
            }
        }
        if (node.name) {
            delete this._nodeRepository[node.name];
        }
    },

    /**
     * Get node by name
     * @param  {string} name
     * @return {Node}
     * @DEPRECATED
     */
    getNode: function (name) {
        return this._nodeRepository[name];
    },

    /**
     * Set main camera of the scene.
     * @param {claygl.Camera} camera
     */
    setMainCamera: function (camera) {
        var idx = this._cameraList.indexOf(camera);
        if (idx >= 0) {
            this._cameraList.splice(idx, 1);
        }
        this._cameraList.unshift(camera);
    },
    /**
     * Get main camera of the scene.
     */
    getMainCamera: function () {
        return this._cameraList[0];
    },

    getLights: function () {
        return this.lights;
    },

    updateLights: function () {
        var lights = this.lights;
        this._previousLightNumber = this._lightNumber;

        var lightNumber = {};
        for (var i = 0; i < lights.length; i++) {
            var light = lights[i];
            if (light.invisible) {
                continue;
            }
            var group = light.group;
            if (!lightNumber[group]) {
                lightNumber[group] = {};
            }
            // User can use any type of light
            lightNumber[group][light.type] = lightNumber[group][light.type] || 0;
            lightNumber[group][light.type]++;
        }
        this._lightNumber = lightNumber;

        for (var groupId in lightNumber) {
            this._lightProgramKeys[groupId] = getProgramKey(lightNumber[groupId]);
        }

        this._updateLightUniforms();
    },

    /**
     * Clone a node and it's children, including mesh, camera, light, etc.
     * Unlike using `Node#clone`. It will clone skeleton and remap the joints. Material will also be cloned.
     *
     * @param {clay.Node} node
     * @return {clay.Node}
     */
    cloneNode: function (node) {
        var newNode = node.clone();
        var clonedNodesMap = {};
        function buildNodesMap(sNode, tNode) {
            clonedNodesMap[sNode.__uid__] = tNode;

            for (var i = 0; i < sNode._children.length; i++) {
                var sChild = sNode._children[i];
                var tChild = tNode._children[i];
                buildNodesMap(sChild, tChild);
            }
        }
        buildNodesMap(node, newNode);

        newNode.traverse(function (newChild) {
            if (newChild.skeleton) {
                newChild.skeleton = newChild.skeleton.clone(clonedNodesMap);
            }
            if (newChild.material) {
                newChild.material = newChild.material.clone();
            }
        });

        return newNode;
    },

    /**
     * Traverse the scene and add the renderable object to the render list.
     * It needs camera for the frustum culling.
     *
     * @param {clay.Camera} camera
     * @param {boolean} updateSceneBoundingBox
     * @return {clay.Scene.RenderList}
     */
    updateRenderList: function (camera, updateSceneBoundingBox) {
        var id = camera.__uid__;
        var renderList = this._renderLists.get(id);
        if (!renderList) {
            renderList = new RenderList();
            this._renderLists.put(id, renderList);
        }
        renderList.startCount();

        if (updateSceneBoundingBox) {
            this.viewBoundingBoxLastFrame.min.set(Infinity, Infinity, Infinity);
            this.viewBoundingBoxLastFrame.max.set(-Infinity, -Infinity, -Infinity);
        }

        var sceneMaterialTransparent = this.material && this.material.transparent || false;
        this._doUpdateRenderList(this, camera, sceneMaterialTransparent, renderList, updateSceneBoundingBox);

        renderList.endCount();

        return renderList;
    },

    /**
     * Get render list. Used after {@link clay.Scene#updateRenderList}
     * @param {clay.Camera} camera
     * @return {clay.Scene.RenderList}
     */
    getRenderList: function (camera) {
        return this._renderLists.get(camera.__uid__);
    },

    _doUpdateRenderList: function (parent, camera, sceneMaterialTransparent, renderList, updateSceneBoundingBox) {
        if (parent.invisible) {
            return;
        }
        // TODO Optimize
        for (var i = 0; i < parent._children.length; i++) {
            var child = parent._children[i];

            if (child.isRenderable()) {
                // Frustum culling
                var worldM = child.isSkinnedMesh() ? IDENTITY : child.worldTransform.array;
                var geometry = child.geometry;

                __WEBPACK_IMPORTED_MODULE_5__glmatrix_mat4__["a" /* default */].multiplyAffine(WORLDVIEW, camera.viewMatrix.array, worldM);
                if (updateSceneBoundingBox && !geometry.boundingBox || !this.isFrustumCulled(child, camera, WORLDVIEW)) {
                    renderList.add(child, child.material.transparent || sceneMaterialTransparent);
                }
            }
            if (child._children.length > 0) {
                this._doUpdateRenderList(child, camera, sceneMaterialTransparent, renderList, updateSceneBoundingBox);
            }
        }
    },

    /**
     * If an scene object is culled by camera frustum
     *
     * Object can be a renderable or a light
     *
     * @param {clay.Node} object
     * @param {clay.Camera} camera
     * @param {Array.<number>} worldViewMat represented with array
     * @param {Array.<number>} projectionMat represented with array
     */
    isFrustumCulled: (function () {
        // Frustum culling
        // http://www.cse.chalmers.se/~uffe/vfc_bbox.pdf
        var cullingBoundingBox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
        var cullingMatrix = new __WEBPACK_IMPORTED_MODULE_7__math_Matrix4__["a" /* default */]();
        return function(object, camera, worldViewMat) {
            // Bounding box can be a property of object(like light) or renderable.geometry
            // PENDING
            var geoBBox = object.boundingBox;
            if (!geoBBox) {
                if (object.skeleton && object.skeleton.boundingBox) {
                    geoBBox = object.skeleton.boundingBox;
                }
                else {
                    geoBBox = object.geometry.boundingBox;
                }
            }

            if (!geoBBox) {
                return false;
            }

            cullingMatrix.array = worldViewMat;
            cullingBoundingBox.transformFrom(geoBBox, cullingMatrix);

            // Passingly update the scene bounding box
            // FIXME exclude very large mesh like ground plane or terrain ?
            // FIXME Only rendererable which cast shadow ?

            // FIXME boundingBox becomes much larger after transformd.
            if (object.castShadow) {
                this.viewBoundingBoxLastFrame.union(cullingBoundingBox);
            }
            // Ignore frustum culling if object is skinned mesh.
            if (object.frustumCulling)  {
                if (!cullingBoundingBox.intersectBoundingBox(camera.frustum.boundingBox)) {
                    return true;
                }

                cullingMatrix.array = camera.projectionMatrix.array;
                if (
                    cullingBoundingBox.max.array[2] > 0 &&
                    cullingBoundingBox.min.array[2] < 0
                ) {
                    // Clip in the near plane
                    cullingBoundingBox.max.array[2] = -1e-20;
                }

                cullingBoundingBox.applyProjection(cullingMatrix);

                var min = cullingBoundingBox.min.array;
                var max = cullingBoundingBox.max.array;

                if (
                    max[0] < -1 || min[0] > 1
                    || max[1] < -1 || min[1] > 1
                    || max[2] < -1 || min[2] > 1
                ) {
                    return true;
                }
            }

            return false;
        };
    })(),

    _updateLightUniforms: function () {
        var lights = this.lights;
        // Put the light cast shadow before the light not cast shadow
        lights.sort(lightSortFunc);

        var lightUniforms = this._lightUniforms;
        for (var group in lightUniforms) {
            for (var symbol in lightUniforms[group]) {
                lightUniforms[group][symbol].value.length = 0;
            }
        }
        for (var i = 0; i < lights.length; i++) {

            var light = lights[i];

            if (light.invisible) {
                continue;
            }

            var group = light.group;

            for (var symbol in light.uniformTemplates) {
                var uniformTpl = light.uniformTemplates[symbol];
                var value = uniformTpl.value(light);
                if (value == null) {
                    continue;
                }
                if (!lightUniforms[group]) {
                    lightUniforms[group] = {};
                }
                if (!lightUniforms[group][symbol]) {
                    lightUniforms[group][symbol] = {
                        type: '',
                        value: []
                    };
                }
                var lu = lightUniforms[group][symbol];
                lu.type = uniformTpl.type + 'v';
                switch (uniformTpl.type) {
                    case '1i':
                    case '1f':
                    case 't':
                        lu.value.push(value);
                        break;
                    case '2f':
                    case '3f':
                    case '4f':
                        for (var j = 0; j < value.length; j++) {
                            lu.value.push(value[j]);
                        }
                        break;
                    default:
                        console.error('Unkown light uniform type ' + uniformTpl.type);
                }
            }
        }
    },

    getLightGroups: function () {
        var lightGroups = [];
        for (var groupId in this._lightNumber) {
            lightGroups.push(groupId);
        }
        return lightGroups;
    },

    getNumberChangedLightGroups: function () {
        var lightGroups = [];
        for (var groupId in this._lightNumber) {
            if (this.isLightNumberChanged(groupId)) {
                lightGroups.push(groupId);
            }
        }
        return lightGroups;
    },

    // Determine if light group is different with since last frame
    // Used to determine whether to update shader and scene's uniforms in Renderer.render
    isLightNumberChanged: function (lightGroup) {
        var prevLightNumber = this._previousLightNumber;
        var currentLightNumber = this._lightNumber;
        // PENDING Performance
        for (var type in currentLightNumber[lightGroup]) {
            if (!prevLightNumber[lightGroup]) {
                return true;
            }
            if (currentLightNumber[lightGroup][type] !== prevLightNumber[lightGroup][type]) {
                return true;
            }
        }
        for (var type in prevLightNumber[lightGroup]) {
            if (!currentLightNumber[lightGroup]) {
                return true;
            }
            if (currentLightNumber[lightGroup][type] !== prevLightNumber[lightGroup][type]) {
                return true;
            }
        }
        return false;
    },

    getLightsNumbers: function (lightGroup) {
        return this._lightNumber[lightGroup];
    },

    getProgramKey: function (lightGroup) {
        return this._lightProgramKeys[lightGroup];
    },

    setLightUniforms: (function () {
        function setUniforms(uniforms, program, renderer) {
            for (var symbol in uniforms) {
                var lu = uniforms[symbol];
                if (lu.type === 'tv') {
                    if (!program.hasUniform(symbol)) {
                        continue;
                    }
                    var texSlots = [];
                    for (var i = 0; i < lu.value.length; i++) {
                        var texture = lu.value[i];
                        var slot = program.takeCurrentTextureSlot(renderer, texture);
                        texSlots.push(slot);
                    }
                    program.setUniform(renderer.gl, '1iv', symbol, texSlots);
                }
                else {
                    program.setUniform(renderer.gl, lu.type, symbol, lu.value);
                }
            }
        }

        return function (program, lightGroup, renderer) {
            setUniforms(this._lightUniforms[lightGroup], program, renderer);
            // Set shadows
            setUniforms(this.shadowUniforms, program, renderer);
        };
    })(),

    /**
     * Dispose self, clear all the scene objects
     * But resources of gl like texuture, shader will not be disposed.
     * Mostly you should use disposeScene method in Renderer to do dispose.
     */
    dispose: function () {
        this.material = null;
        this._opaqueList = [];
        this._transparentList = [];

        this.lights = [];

        this._lightUniforms = {};

        this._lightNumber = {};
        this._nodeRepository = {};
    }
});

function lightSortFunc(a, b) {
    if (b.castShadow && !a.castShadow) {
        return true;
    }
}

/* harmony default export */ __webpack_exports__["a"] = (Scene);


/***/ }),
/* 37 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Camera__ = __webpack_require__(58);

/**
 * @constructor clay.camera.Orthographic
 * @extends clay.Camera
 */
var Orthographic = __WEBPACK_IMPORTED_MODULE_0__Camera__["a" /* default */].extend(
/** @lends clay.camera.Orthographic# */
{
    /**
     * @type {number}
     */
    left: -1,
    /**
     * @type {number}
     */
    right: 1,
    /**
     * @type {number}
     */
    near: -1,
    /**
     * @type {number}
     */
    far: 1,
    /**
     * @type {number}
     */
    top: 1,
    /**
     * @type {number}
     */
    bottom: -1
},
/** @lends clay.camera.Orthographic.prototype */
{

    updateProjectionMatrix: function() {
        this.projectionMatrix.ortho(this.left, this.right, this.bottom, this.top, this.near, this.far);
    },

    decomposeProjectionMatrix: function () {
        var m = this.projectionMatrix.array;
        this.left = (-1 - m[12]) / m[0];
        this.right = (1 - m[12]) / m[0];
        this.top = (1 - m[13]) / m[5];
        this.bottom = (-1 - m[13]) / m[5];
        this.near = -(-1 - m[14]) / m[10];
        this.far = -(1 - m[14]) / m[10];
    },
    /**
     * @return {clay.camera.Orthographic}
     */
    clone: function() {
        var camera = __WEBPACK_IMPORTED_MODULE_0__Camera__["a" /* default */].prototype.clone.call(this);
        camera.left = this.left;
        camera.right = this.right;
        camera.near = this.near;
        camera.far = this.far;
        camera.top = this.top;
        camera.bottom = this.bottom;

        return camera;
    }
});

/* harmony default export */ __webpack_exports__["a"] = (Orthographic);


/***/ }),
/* 38 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ({
    convertToDynamicArray: function (clear) {
        if (clear) {
            this.resetOffset();
        }
        var attributes = this.attributes;
        for (var name in attributes) {
            if (clear || !attributes[name].value) {
                attributes[name].value = [];
            }
            else {
                attributes[name].value = Array.prototype.slice.call(attributes[name].value);
            }
        }
        if (clear || !this.indices) {
            this.indices = [];
        }
        else {
            this.indices = Array.prototype.slice.call(this.indices);
        }
    },

    convertToTypedArray: function () {
        var attributes = this.attributes;
        for (var name in attributes) {
            if (attributes[name].value && attributes[name].value.length > 0) {
                attributes[name].value = new Float32Array(attributes[name].value);
            }
            else {
                attributes[name].value = null;
            }
        }
        if (this.indices && this.indices.length > 0) {
            this.indices = this.vertexCount > 0xffff ? new Uint32Array(this.indices) : new Uint16Array(this.indices);
        }

        this.dirty();
    }
});

/***/ }),
/* 39 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


function otherDimToDataDim (data, otherDim) {
    var dataDim = [];
    __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(data.dimensions, function (dimName) {
        var dimItem = data.getDimensionInfo(dimName);
        var otherDims = dimItem.otherDims;
        var dimIndex = otherDims[otherDim];
        if (dimIndex != null && dimIndex !== false) {
            dataDim[dimIndex] = dimItem.name;
        }
    });
    return dataDim;
}

/* harmony default export */ __webpack_exports__["a"] = (function (seriesModel, dataIndex, multipleSeries) {
    function formatArrayValue(value) {
        var vertially = true;

        var result = [];
        var tooltipDims = otherDimToDataDim(data, 'tooltip');

        tooltipDims.length
            ? __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(tooltipDims, function (dimIdx) {
                setEachItem(data.get(dimIdx, dataIndex), dimIdx);
            })
            // By default, all dims is used on tooltip.
            : __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(value, setEachItem);

        function setEachItem(val, dimIdx) {
            var dimInfo = data.getDimensionInfo(dimIdx);
            // If `dimInfo.tooltip` is not set, show tooltip.
            if (!dimInfo || dimInfo.otherDims.tooltip === false) {
                return;
            }
            var dimType = dimInfo.type;
            var valStr = (vertially ? '- ' + (dimInfo.tooltipName || dimInfo.name) + ': ' : '')
                + (dimType === 'ordinal'
                    ? val + ''
                    : dimType === 'time'
                    ? (multipleSeries ? '' : __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.formatTime('yyyy/MM/dd hh:mm:ss', val))
                    : __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.addCommas(val)
                );
            valStr && result.push(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.encodeHTML(valStr));
        }

        return (vertially ? '<br/>' : '') + result.join(vertially ? '<br/>' : ', ');
    }

    var data = seriesModel.getData();

    var value = seriesModel.getRawValue(dataIndex);
    var formattedValue = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(value)
        ? formatArrayValue(value) : __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.encodeHTML(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.addCommas(value));
    var name = data.getName(dataIndex);

    var color = data.getItemVisual(dataIndex, 'color');
    if (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isObject(color) && color.colorStops) {
        color = (color.colorStops[0] || {}).color;
    }
    color = color || 'transparent';

    var colorEl = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.getTooltipMarker(color);

    var seriesName = seriesModel.name;
    // FIXME
    if (seriesName === '\0-') {
        // Not show '-'
        seriesName = '';
    }
    seriesName = seriesName
        ? __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.encodeHTML(seriesName) + (!multipleSeries ? '<br/>' : ': ')
        : '';
    return !multipleSeries
        ? seriesName + colorEl
            + (name
                ? __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.encodeHTML(name) + ': ' + formattedValue
                : formattedValue
            )
        : colorEl + seriesName + formattedValue;
});;

/***/ }),
/* 40 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Renderable__ = __webpack_require__(72);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);



/**
 * @constructor clay.Mesh
 * @extends clay.Renderable
 */
var Mesh = __WEBPACK_IMPORTED_MODULE_0__Renderable__["a" /* default */].extend(/** @lends clay.Mesh# */ {
    /**
     * Used when it is a skinned mesh
     * @type {clay.Skeleton}
     */
    skeleton: null,
    /**
     * Joints indices Meshes can share the one skeleton instance and each mesh can use one part of joints. Joints indices indicate the index of joint in the skeleton instance
     * @type {number[]}
     */
    joints: null,

    /**
     * If store the skin matrices in vertex texture
     * @type {bool}
     */
    useSkinMatricesTexture: false

}, function () {
    if (!this.joints) {
        this.joints = [];
    }
}, {

    isSkinnedMesh: function () {
        return !!(this.skeleton && this.joints && this.joints.length > 0);
    },

    clone: function () {
        var mesh = __WEBPACK_IMPORTED_MODULE_0__Renderable__["a" /* default */].prototype.clone.call(this);
        mesh.skeleton = this.skeleton;
        if (this.joints) {
            mesh.joints = this.joints.slice();
        }
        return mesh;
    }
});

// Enums
Mesh.POINTS = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].POINTS;
Mesh.LINES = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINES;
Mesh.LINE_LOOP = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINE_LOOP;
Mesh.LINE_STRIP = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINE_STRIP;
Mesh.TRIANGLES = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLES;
Mesh.TRIANGLE_STRIP = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLE_STRIP;
Mesh.TRIANGLE_FAN = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLE_FAN;

Mesh.BACK = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].BACK;
Mesh.FRONT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FRONT;
Mesh.FRONT_AND_BACK = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FRONT_AND_BACK;
Mesh.CW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CW;
Mesh.CCW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CCW;

/* harmony default export */ __webpack_exports__["a"] = (Mesh);


/***/ }),
/* 41 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Camera__ = __webpack_require__(58);


/**
 * @constructor clay.camera.Perspective
 * @extends clay.Camera
 */
var Perspective = __WEBPACK_IMPORTED_MODULE_0__Camera__["a" /* default */].extend(/** @lends clay.camera.Perspective# */{
    /**
     * Vertical field of view in degrees
     * @type {number}
     */
    fov: 50,
    /**
     * Aspect ratio, typically viewport width / height
     * @type {number}
     */
    aspect: 1,
    /**
     * Near bound of the frustum
     * @type {number}
     */
    near: 0.1,
    /**
     * Far bound of the frustum
     * @type {number}
     */
    far: 2000
},
/** @lends clay.camera.Perspective.prototype */
{

    updateProjectionMatrix: function() {
        var rad = this.fov / 180 * Math.PI;
        this.projectionMatrix.perspective(rad, this.aspect, this.near, this.far);
    },
    decomposeProjectionMatrix: function () {
        var m = this.projectionMatrix.array;
        var rad = Math.atan(1 / m[5]) * 2;
        this.fov = rad / Math.PI * 180;
        this.aspect = m[5] / m[0];
        this.near = m[14] / (m[10] - 1);
        this.far = m[14] / (m[10] + 1);
    },
    /**
     * @return {clay.camera.Perspective}
     */
    clone: function() {
        var camera = __WEBPACK_IMPORTED_MODULE_0__Camera__["a" /* default */].prototype.clone.call(this);
        camera.fov = this.fov;
        camera.aspect = this.aspect;
        camera.near = this.near;
        camera.far = this.far;

        return camera;
    }
});

/* harmony default export */ __webpack_exports__["a"] = (Perspective);


/***/ }),
/* 42 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Mesh__ = __webpack_require__(40);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__geometry_Cube__ = __webpack_require__(76);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Material__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__shader_source_skybox_glsl_js__ = __webpack_require__(121);
// TODO Should not derived from mesh?







__WEBPACK_IMPORTED_MODULE_2__Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_5__shader_source_skybox_glsl_js__["a" /* default */]);
/**
 * @constructor clay.plugin.Skybox
 *
 * @example
 *     var skyTex = new clay.TextureCube();
 *     skyTex.load({
 *         'px': 'assets/textures/sky/px.jpg',
 *         'nx': 'assets/textures/sky/nx.jpg'
 *         'py': 'assets/textures/sky/py.jpg'
 *         'ny': 'assets/textures/sky/ny.jpg'
 *         'pz': 'assets/textures/sky/pz.jpg'
 *         'nz': 'assets/textures/sky/nz.jpg'
 *     });
 *     var skybox = new clay.plugin.Skybox({
 *         scene: scene
 *     });
 *     skybox.material.set('environmentMap', skyTex);
 */
var Skybox = __WEBPACK_IMPORTED_MODULE_0__Mesh__["a" /* default */].extend(function () {

    var skyboxShader = new __WEBPACK_IMPORTED_MODULE_2__Shader__["a" /* default */]({
        vertex: __WEBPACK_IMPORTED_MODULE_2__Shader__["a" /* default */].source('clay.skybox.vertex'),
        fragment: __WEBPACK_IMPORTED_MODULE_2__Shader__["a" /* default */].source('clay.skybox.fragment')
    });
    var material = new __WEBPACK_IMPORTED_MODULE_3__Material__["a" /* default */]({
        shader: skyboxShader,
        depthMask: false
    });

    return {
        /**
         * @type {clay.Scene}
         * @memberOf clay.plugin.Skybox.prototype
         */
        scene: null,

        geometry: new __WEBPACK_IMPORTED_MODULE_1__geometry_Cube__["a" /* default */](),

        material: material,

        environmentMap: null,

        culling: false
    };
}, function () {
    var scene = this.scene;
    if (scene) {
        this.attachScene(scene);
    }
    if (this.environmentMap) {
        this.setEnvironmentMap(this.environmentMap);
    }
}, /** @lends clay.plugin.Skybox# */ {
    /**
     * Attach the skybox to the scene
     * @param  {clay.Scene} scene
     */
    attachScene: function (scene) {
        if (this.scene) {
            this.detachScene();
        }
        scene.skybox = this;

        this.scene = scene;
        scene.on('beforerender', this._beforeRenderScene, this);
    },
    /**
     * Detach from scene
     */
    detachScene: function () {
        if (this.scene) {
            this.scene.off('beforerender', this._beforeRenderScene);
            this.scene.skybox = null;
        }
        this.scene = null;
    },

    /**
     * Dispose skybox
     * @param  {clay.Renderer} renderer
     */
    dispose: function (renderer) {
        this.detachScene();
        this.geometry.dispose(renderer);
    },
    /**
     * Set environment map
     * @param {clay.TextureCube} envMap
     */
    setEnvironmentMap: function (envMap) {
        if (envMap.textureType === 'texture2D') {
            this.material.define('EQUIRECTANGULAR');
            // LINEAR filter can remove the artifacts in pole
            envMap.minFilter = __WEBPACK_IMPORTED_MODULE_4__Texture__["a" /* default */].LINEAR;
        }
        else {
            this.material.undefine('EQUIRECTANGULAR');
        }
        this.material.set('environmentMap', envMap);
    },
    /**
     * Get environment map
     * @return {clay.TextureCube}
     */
    getEnvironmentMap: function () {
        return this.material.get('environmentMap');
    },

    _beforeRenderScene: function(renderer, scene, camera) {
        this.renderSkybox(renderer, camera);
    },

    renderSkybox: function (renderer, camera) {
        this.position.copy(camera.getWorldPosition());
        this.update();
        // Don't remember to disable blend
        renderer.gl.disable(renderer.gl.BLEND);
        if (this.material.get('lod') > 0) {
            this.material.define('fragment', 'LOD');
        }
        else {
            this.material.undefine('fragment', 'LOD');
        }
        renderer.renderPass([this], camera);
    }
});

/* harmony default export */ __webpack_exports__["a"] = (Skybox);


/***/ }),
/* 43 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Geometry__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_BoundingBox__ = __webpack_require__(18);



/**
 * @constructor clay.geometry.Plane
 * @extends clay.Geometry
 * @param {Object} [opt]
 * @param {number} [opt.widthSegments]
 * @param {number} [opt.heightSegments]
 */
var Plane = __WEBPACK_IMPORTED_MODULE_0__Geometry__["a" /* default */].extend(
/** @lends clay.geometry.Plane# */
{
    dynamic: false,
    /**
     * @type {number}
     */
    widthSegments: 1,
    /**
     * @type {number}
     */
    heightSegments: 1
}, function() {
    this.build();
},
/** @lends clay.geometry.Plane.prototype */
{
    /**
     * Build plane geometry
     */
    build: function() {
        var heightSegments = this.heightSegments;
        var widthSegments = this.widthSegments;
        var attributes = this.attributes;
        var positions = [];
        var texcoords = [];
        var normals = [];
        var faces = [];

        for (var y = 0; y <= heightSegments; y++) {
            var t = y / heightSegments;
            for (var x = 0; x <= widthSegments; x++) {
                var s = x / widthSegments;

                positions.push([2 * s - 1, 2 * t - 1, 0]);
                if (texcoords) {
                    texcoords.push([s, t]);
                }
                if (normals) {
                    normals.push([0, 0, 1]);
                }
                if (x < widthSegments && y < heightSegments) {
                    var i = x + y * (widthSegments + 1);
                    faces.push([i, i + 1, i + widthSegments + 1]);
                    faces.push([i + widthSegments + 1, i + 1, i + widthSegments + 2]);
                }
            }
        }

        attributes.position.fromArray(positions);
        attributes.texcoord0.fromArray(texcoords);
        attributes.normal.fromArray(normals);

        this.initIndicesFromArray(faces);

        this.boundingBox = new __WEBPACK_IMPORTED_MODULE_1__math_BoundingBox__["a" /* default */]();
        this.boundingBox.min.set(-1, -1, 0);
        this.boundingBox.max.set(1, 1, 0);
    }
});

/* harmony default export */ __webpack_exports__["a"] = (Plane);


/***/ }),
/* 44 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ({
    defaultOption: {

        viewControl: {
            // perspective, orthographic.
            // TODO Isometric
            projection: 'perspective',
            // If rotate on on init
            autoRotate: false,
            // cw or ccw
            autoRotateDirection: 'cw',
            // Degree per second
            autoRotateSpeed: 10,

            // Start rotating after still for a given time
            // default is 3 seconds
            autoRotateAfterStill: 3,

            // Rotate, zoom damping.
            damping: 0.8,
            // Sensitivities for operations.
            // Can be array to set x,y respectively
            rotateSensitivity: 1,
            zoomSensitivity: 1,
            // Can be array to set x,y respectively
            panSensitivity: 1,
            // Which mouse button do rotate or pan
            panMouseButton: 'middle',
            rotateMouseButton: 'left',

            // Distance to the target
            // Only available when camera is perspective.
            distance: 150,
            // Min distance mouse can zoom in
            minDistance: 40,
            // Max distance mouse can zoom out
            maxDistance: 400,

            // Size of viewing volume.
            // Only available when camera is orthographic
            orthographicSize: 150,
            maxOrthographicSize: 400,
            minOrthographicSize: 20,

            // Center view point
            center: [0, 0, 0],
            // Alpha angle for top-down rotation
            // Positive to rotate to top.
            alpha: 0,
            // beta angle for left-right rotation
            // Positive to rotate to right.
            beta: 0,

            minAlpha: -90,
            maxAlpha: 90

            // minBeta: -Infinity
            // maxBeta: -Infinity
        }
    },

    setView: function (opts) {
        opts = opts || {};
        this.option.viewControl = this.option.viewControl || {};
        if (opts.alpha != null) {
            this.option.viewControl.alpha = opts.alpha;
        }
        if (opts.beta != null) {
            this.option.viewControl.beta = opts.beta;
        }
        if (opts.distance != null) {
            this.option.viewControl.distance = opts.distance;
        }
        if (opts.center != null) {
            this.option.viewControl.center = opts.center;
        }
    }
});

/***/ }),
/* 45 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector2__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_math_Quaternion__ = __webpack_require__(56);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__retrieve__ = __webpack_require__(2);
/**
 * Provide orbit control for 3D objects
 *
 * @module echarts-gl/util/OrbitControl
 * @author Yi Shen(http://github.com/pissang)
 */

// TODO Remove magic numbers on sensitivity





var firstNotNull = __WEBPACK_IMPORTED_MODULE_4__retrieve__["a" /* default */].firstNotNull;


var MOUSE_BUTTON_KEY_MAP = {
    left: 0,
    middle: 1,
    right: 2
};

function convertToArray(val) {
    if (!(val instanceof Array)) {
        val = [val, val];
    }
    return val;
}

/**
 * @alias module:echarts-x/util/OrbitControl
 */
var OrbitControl = __WEBPACK_IMPORTED_MODULE_0_claygl_src_core_Base__["a" /* default */].extend(function () {

    return {
        /**
         * @type {module:zrender~ZRender}
         */
        zr: null,

        /**
         * @type {module:echarts-gl/core/ViewGL}
         */
        viewGL: null,

        /**
         * @type {clay.math.Vector3}
         */
        _center: new __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector3__["a" /* default */](),

        /**
         * Minimum distance to the center
         * Only available when camera is perspective.
         * @type {number}
         * @default 0.5
         */
        minDistance: 0.5,

        /**
         * Maximum distance to the center
         * Only available when camera is perspective.
         * @type {number}
         * @default 2
         */
        maxDistance: 1.5,

        /**
         * Only available when camera is orthographic
         */
        maxOrthographicSize: 300,

        /**
         * Only available when camera is orthographic
         */
        minOrthographicSize: 30,

        /**
         * Minimum alpha rotation
         */
        minAlpha: -90,

        /**
         * Maximum alpha rotation
         */
        maxAlpha: 90,

        /**
         * Minimum beta rotation
         */
        minBeta: -Infinity,
        /**
         * Maximum beta rotation
         */
        maxBeta: Infinity,

        /**
         * Start auto rotating after still for the given time
         */
        autoRotateAfterStill: 0,

        /**
         * Direction of autoRotate. cw or ccw when looking top down.
         */
        autoRotateDirection: 'cw',

        /**
         * Degree per second
         */
        autoRotateSpeed: 60,

        /**
         * @param {number}
         */
        damping: 0.8,

        /**
         * @param {number}
         */
        rotateSensitivity: 1,

        /**
         * @param {number}
         */
        zoomSensitivity: 1,

        /**
         * @param {number}
         */
        panSensitivity: 1,

        panMouseButton: 'middle',
        rotateMouseButton: 'left',

        /**
         * Pan or rotate
         * @private
         * @type {String}
         */
        _mode: 'rotate',

        /**
         * @private
         * @type {clay.Camera}
         */
        _camera: null,

        _needsUpdate: false,

        _rotating: false,

        // Rotation around yAxis in radian
        _phi: 0,
        // Rotation around xAxis in radian
        _theta: 0,

        _mouseX: 0,
        _mouseY: 0,

        _rotateVelocity: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector2__["a" /* default */](),

        _panVelocity: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector2__["a" /* default */](),

        _distance: 500,

        _zoomSpeed: 0,

        _stillTimeout: 0,

        _animators: []
    };
}, function () {
    // Each OrbitControl has it's own handler
    ['_mouseDownHandler', '_mouseWheelHandler', '_mouseMoveHandler', '_mouseUpHandler',
    '_pinchHandler', '_contextMenuHandler', '_update'].forEach(function (hdlName) {
        this[hdlName] = this[hdlName].bind(this);
    }, this);
}, {
    /**
     * Initialize.
     * Mouse event binding
     */
    init: function () {
        var zr = this.zr;

        if (zr) {
            zr.on('mousedown', this._mouseDownHandler);
            zr.on('globalout', this._mouseUpHandler);
            zr.on('mousewheel', this._mouseWheelHandler);
            zr.on('pinch', this._pinchHandler);

            zr.animation.on('frame', this._update);

            zr.dom.addEventListener('contextmenu', this._contextMenuHandler);
        }
    },

    /**
     * Dispose.
     * Mouse event unbinding
     */
    dispose: function () {
        var zr = this.zr;

        if (zr) {
            zr.off('mousedown', this._mouseDownHandler);
            zr.off('mousemove', this._mouseMoveHandler);
            zr.off('mouseup', this._mouseUpHandler);
            zr.off('mousewheel', this._mouseWheelHandler);
            zr.off('pinch', this._pinchHandler);
            zr.off('globalout', this._mouseUpHandler);
            zr.dom.removeEventListener('contextmenu', this._contextMenuHandler);

            zr.animation.off('frame', this._update);
        }
        this.stopAllAnimation();
    },

    /**
     * Get distance
     * @return {number}
     */
    getDistance: function () {
        return this._distance;
    },

    /**
     * Set distance
     * @param {number} distance
     */
    setDistance: function (distance) {
        this._distance = distance;
        this._needsUpdate = true;
    },

    /**
     * Get size of orthographic viewing volume
     * @return {number}
     */
    getOrthographicSize: function () {
        return this._orthoSize;
    },

    /**
     * Set size of orthographic viewing volume
     * @param {number} size
     */
    setOrthographicSize: function (size) {
        this._orthoSize = size;
        this._needsUpdate = true;
    },

    /**
     * Get alpha rotation
     * Alpha angle for top-down rotation. Positive to rotate to top.
     *
     * Which means camera rotation around x axis.
     */
    getAlpha: function () {
        return this._theta / Math.PI * 180;
    },

    /**
     * Get beta rotation
     * Beta angle for left-right rotation. Positive to rotate to right.
     *
     * Which means camera rotation around y axis.
     */
    getBeta: function () {
        return -this._phi / Math.PI * 180;
    },

    /**
     * Get control center
     * @return {Array.<number>}
     */
    getCenter: function () {
        return this._center.toArray();
    },

    /**
     * Set alpha rotation angle
     * @param {number} alpha
     */
    setAlpha: function (alpha) {
        alpha = Math.max(Math.min(this.maxAlpha, alpha), this.minAlpha);

        this._theta = alpha / 180 * Math.PI;
        this._needsUpdate = true;
    },

    /**
     * Set beta rotation angle
     * @param {number} beta
     */
    setBeta: function (beta) {
        beta = Math.max(Math.min(this.maxBeta, beta), this.minBeta);

        this._phi = -beta / 180 * Math.PI;
        this._needsUpdate = true;
    },

    /**
     * Set control center
     * @param {Array.<number>} center
     */
    setCenter: function (centerArr) {
        this._center.setArray(centerArr);
    },

    /**
     * @param {module:echarts-gl/core/ViewGL} viewGL
     */
    setViewGL: function (viewGL) {
        this.viewGL = viewGL;
    },

    /**
     * @return {clay.Camera}
     */
    getCamera: function () {
        return this.viewGL.camera;
    },

    setFromViewControlModel: function (viewControlModel, extraOpts) {
        extraOpts = extraOpts || {};
        var baseDistance = extraOpts.baseDistance || 0;
        var baseOrthoSize = extraOpts.baseOrthoSize || 1;

        var projection = viewControlModel.get('projection');
        if (projection !== 'perspective' && projection !== 'orthographic' && projection !== 'isometric') {
            if (true) {
                console.error('Unkown projection type %s, use perspective projection instead.', projection);
            }
            projection = 'perspective';
        }
        this._projection = projection;
        this.viewGL.setProjection(projection);

        var targetDistance = viewControlModel.get('distance') + baseDistance;
        var targetOrthographicSize = viewControlModel.get('orthographicSize') + baseOrthoSize;

        [
            ['damping', 0.8],
            ['autoRotate', false],
            ['autoRotateAfterStill', 3],
            ['autoRotateDirection', 'cw'],
            ['autoRotateSpeed', 10],
            ['minDistance', 30],
            ['maxDistance', 400],
            ['minOrthographicSize', 30],
            ['maxOrthographicSize', 300],
            ['minAlpha', -90],
            ['maxAlpha', 90],
            ['minBeta', -Infinity],
            ['maxBeta', Infinity],
            ['rotateSensitivity', 1],
            ['zoomSensitivity', 1],
            ['panSensitivity', 1],
            ['panMouseButton', 'left'],
            ['rotateMouseButton', 'middle'],
        ].forEach(function (prop) {
            this[prop[0]] = firstNotNull(viewControlModel.get(prop[0]), prop[1]);
        }, this);

        this.minDistance += baseDistance;
        this.maxDistance += baseDistance;
        this.minOrthographicSize += baseOrthoSize,
        this.maxOrthographicSize += baseOrthoSize;

        var ecModel = viewControlModel.ecModel;

        var animationOpts = {};
        ['animation', 'animationDurationUpdate', 'animationEasingUpdate'].forEach(function (key) {
            animationOpts[key] = firstNotNull(
                viewControlModel.get(key), ecModel && ecModel.get(key)
            );
        });

        var alpha = firstNotNull(extraOpts.alpha, viewControlModel.get('alpha')) || 0;
        var beta = firstNotNull(extraOpts.beta, viewControlModel.get('beta')) || 0;
        var center = firstNotNull(extraOpts.center, viewControlModel.get('center')) || [0, 0, 0];
        if (animationOpts.animation && animationOpts.animationDurationUpdate > 0 && this._notFirst) {
            this.animateTo({
                alpha: alpha,
                beta: beta,
                center: center,
                distance: targetDistance,
                targetOrthographicSize: targetOrthographicSize,
                easing: animationOpts.animationEasingUpdate,
                duration: animationOpts.animationDurationUpdate
            });
        }
        else {
            this.setDistance(targetDistance);
            this.setAlpha(alpha);
            this.setBeta(beta);
            this.setCenter(center);
            this.setOrthographicSize(targetOrthographicSize);
        }

        this._notFirst = true;

        this._validateProperties();
    },

    _validateProperties: function () {
        if (true) {
            if (MOUSE_BUTTON_KEY_MAP[this.panMouseButton] == null) {
                console.error('Unkown panMouseButton %s. It should be left|middle|right', this.panMouseButton);
            }
            if (MOUSE_BUTTON_KEY_MAP[this.rotateMouseButton] == null) {
                console.error('Unkown rotateMouseButton %s. It should be left|middle|right', this.rotateMouseButton);
            }
            if (this.autoRotateDirection !== 'cw' && this.autoRotateDirection !== 'ccw') {
                console.error('Unkown autoRotateDirection %s. It should be cw|ccw', this.autoRotateDirection);
            }
        }
    },

    /**
     * @param {Object} opts
     * @param {number} opts.distance
     * @param {number} opts.alpha
     * @param {number} opts.beta
     * @param {number} opts.orthographicSize
     * @param {number} [opts.duration=1000]
     * @param {number} [opts.easing='linear']
     */
    animateTo: function (opts) {
        var zr = this.zr;
        var self = this;

        var obj = {};
        var target = {};

        if (opts.distance != null) {
            obj.distance = this.getDistance();
            target.distance = opts.distance;
        }
        if (opts.orthographicSize != null) {
            obj.orthographicSize = this.getOrthographicSize();
            target.orthographicSize = opts.orthographicSize;
        }
        if (opts.alpha != null) {
            obj.alpha = this.getAlpha();
            target.alpha = opts.alpha;
        }
        if (opts.beta != null) {
            obj.beta = this.getBeta();
            target.beta = opts.beta;
        }
        if (opts.center != null) {
            obj.center = this.getCenter();
            target.center = opts.center;
        }

        return this._addAnimator(
            zr.animation.animate(obj)
                .when(opts.duration || 1000, target)
                .during(function () {
                    if (obj.alpha != null) {
                        self.setAlpha(obj.alpha);
                    }
                    if (obj.beta != null) {
                        self.setBeta(obj.beta);
                    }
                    if (obj.distance != null) {
                        self.setDistance(obj.distance);
                    }
                    if (obj.center != null) {
                        self.setCenter(obj.center);
                    }
                    if (obj.orthographicSize != null) {
                        self.setOrthographicSize(obj.orthographicSize);
                    }
                    self._needsUpdate = true;
                })
        ).start(opts.easing || 'linear');
    },

    /**
     * Stop all animation
     */
    stopAllAnimation: function () {
        for (var i = 0; i < this._animators.length; i++) {
            this._animators[i].stop();
        }
        this._animators.length = 0;
    },

    update: function () {
        this._needsUpdate = true;
        this._update(20);
    },

    _isAnimating: function () {
        return this._animators.length > 0;
    },
    /**
     * Call update each frame
     * @param  {number} deltaTime Frame time
     */
    _update: function (deltaTime) {

        if (this._rotating) {
            var radian = (this.autoRotateDirection === 'cw' ? 1 : -1)
                 * this.autoRotateSpeed / 180 * Math.PI;
            this._phi -= radian * deltaTime / 1000;
            this._needsUpdate = true;
        }
        else if (this._rotateVelocity.len() > 0) {
            this._needsUpdate = true;
        }

        if (Math.abs(this._zoomSpeed) > 0.1 || this._panVelocity.len() > 0) {
            this._needsUpdate = true;
        }

        if (!this._needsUpdate) {
            return;
        }

        deltaTime = Math.min(deltaTime, 50);

        this._updateDistanceOrSize(deltaTime);

        this._updatePan(deltaTime);

        this._updateRotate(deltaTime);

        this._updateTransform();

        this.getCamera().update();

        this.zr && this.zr.refresh();

        this.trigger('update');

        this._needsUpdate = false;
    },

    _updateRotate: function (deltaTime) {
        var velocity = this._rotateVelocity;
        this._phi = velocity.y * deltaTime / 20 + this._phi;
        this._theta = velocity.x * deltaTime / 20 + this._theta;

        this.setAlpha(this.getAlpha());
        this.setBeta(this.getBeta());

        this._vectorDamping(velocity, Math.pow(this.damping, deltaTime / 16));
    },

    _updateDistanceOrSize: function (deltaTime) {
        if (this._projection === 'perspective') {
            this._setDistance(this._distance + this._zoomSpeed * deltaTime / 20);
        }
        else {
            this._setOrthoSize(this._orthoSize + this._zoomSpeed * deltaTime / 20);
        }

        this._zoomSpeed *= Math.pow(this.damping, deltaTime / 16);
    },


    _setDistance: function (distance) {
        this._distance = Math.max(Math.min(distance, this.maxDistance), this.minDistance);
    },

    _setOrthoSize: function (size) {
        this._orthoSize = Math.max(Math.min(size, this.maxOrthographicSize), this.minOrthographicSize);
        var camera = this.getCamera();
        var cameraHeight = this._orthoSize;
        var cameraWidth = cameraHeight / this.viewGL.viewport.height * this.viewGL.viewport.width;
        camera.left = -cameraWidth / 2;
        camera.right = cameraWidth / 2;
        camera.top = cameraHeight / 2;
        camera.bottom = -cameraHeight / 2;
    },

    _updatePan: function (deltaTime) {

        var velocity = this._panVelocity;
        var len = this._distance;

        var target = this.getCamera();
        var yAxis = target.worldTransform.y;
        var xAxis = target.worldTransform.x;

        // PENDING
        this._center
            .scaleAndAdd(xAxis, -velocity.x * len / 200)
            .scaleAndAdd(yAxis, -velocity.y * len / 200);

        this._vectorDamping(velocity, 0);
    },

    _updateTransform: function () {
        var camera = this.getCamera();

        var dir = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector3__["a" /* default */]();
        var theta = this._theta + Math.PI / 2;
        var phi = this._phi + Math.PI / 2;
        var r = Math.sin(theta);

        dir.x = r * Math.cos(phi);
        dir.y = -Math.cos(theta);
        dir.z = r * Math.sin(phi);

        camera.position.copy(this._center).scaleAndAdd(dir, this._distance);
        camera.rotation.identity()
            // First around y, then around x
            .rotateY(-this._phi)
            .rotateX(-this._theta);
    },

    _startCountingStill: function () {
        clearTimeout(this._stillTimeout);

        var time = this.autoRotateAfterStill;
        var self = this;
        if (!isNaN(time) && time > 0) {
            this._stillTimeout = setTimeout(function () {
                self._rotating = true;
            }, time * 1000);
        }
    },

    _vectorDamping: function (v, damping) {
        var speed = v.len();
        speed = speed * damping;
        if (speed < 1e-4) {
            speed = 0;
        }
        v.normalize().scale(speed);
    },

    _decomposeTransform: function () {
        if (!this.getCamera()) {
            return;
        }

        this.getCamera().updateWorldTransform();

        var forward = this.getCamera().worldTransform.z;
        var alpha = Math.asin(forward.y);
        var beta = Math.atan2(forward.x, forward.z);

        this._theta = alpha;
        this._phi = -beta;

        this.setBeta(this.getBeta());
        this.setAlpha(this.getAlpha());

        // Is perspective
        if (this.getCamera().aspect) {
            this._setDistance(this.getCamera().position.dist(this._center));
        }
        else {
            this._setOrthoSize(this.getCamera().top - this.getCamera().bottom);
        }
    },

    _mouseDownHandler: function (e) {
        if (e.target) {
            // If mouseon some zrender element.
            return;
        }
        if (this._isAnimating()) {
            return;
        }

        var x = e.offsetX;
        var y = e.offsetY;
        if (this.viewGL && !this.viewGL.containPoint(x, y)) {
            return;
        }

        this.zr.on('mousemove', this._mouseMoveHandler);
        this.zr.on('mouseup', this._mouseUpHandler);

        if (e.event.targetTouches) {
            if (e.event.targetTouches.length === 1) {
                this._mode = 'rotate';
            }
        }
        else {
            if (e.event.button === MOUSE_BUTTON_KEY_MAP[this.rotateMouseButton]) {
                this._mode = 'rotate';
            }
            else if (e.event.button === MOUSE_BUTTON_KEY_MAP[this.panMouseButton]) {
                this._mode = 'pan';
            }
            else {
                this._mode = '';
            }
        }

        // Reset rotate velocity
        this._rotateVelocity.set(0, 0);
        this._rotating = false;
        if (this.autoRotate) {
            this._startCountingStill();
        }

        this._mouseX = e.offsetX;
        this._mouseY = e.offsetY;
    },

    _mouseMoveHandler: function (e) {
        if (e.target && e.target.__isGLToZRProxy) {
            return;
        }

        if (this._isAnimating()) {
            return;
        }

        var panSensitivity = convertToArray(this.panSensitivity);
        var rotateSensitivity = convertToArray(this.rotateSensitivity);

        if (this._mode === 'rotate') {
            this._rotateVelocity.y = (e.offsetX - this._mouseX) / this.zr.getHeight() * 2 * rotateSensitivity[0];
            this._rotateVelocity.x = (e.offsetY - this._mouseY) / this.zr.getWidth() * 2 * rotateSensitivity[1];
        }
        else if (this._mode === 'pan') {
            this._panVelocity.x = (e.offsetX - this._mouseX) / this.zr.getWidth() * panSensitivity[0] * 400;
            this._panVelocity.y = (-e.offsetY + this._mouseY) / this.zr.getHeight() * panSensitivity[1] * 400;
        }


        this._mouseX = e.offsetX;
        this._mouseY = e.offsetY;

        e.event.preventDefault();
    },

    _mouseWheelHandler: function (e) {
        if (this._isAnimating()) {
            return;
        }
        var delta = e.event.wheelDelta // Webkit
                || -e.event.detail; // Firefox
        this._zoomHandler(e, delta);
    },

    _pinchHandler: function (e) {
        if (this._isAnimating()) {
            return;
        }
        this._zoomHandler(e, e.pinchScale > 1 ? 1 : -1);
        // Not rotate when pinch
        this._mode = '';
    },

    _zoomHandler: function (e, delta) {
        if (delta === 0) {
            return;
        }

        var x = e.offsetX;
        var y = e.offsetY;
        if (this.viewGL && !this.viewGL.containPoint(x, y)) {
            return;
        }

        var speed;
        if (this._projection === 'perspective') {
            speed = Math.max(Math.max(Math.min(
                this._distance - this.minDistance,
                this.maxDistance - this._distance
            )) / 20, 0.5);
        }
        else {
            speed = Math.max(Math.max(Math.min(
                this._orthoSize - this.minOrthographicSize,
                this.maxOrthographicSize - this._orthoSize
            )) / 20, 0.5);
        }
        this._zoomSpeed = (delta > 0 ? -1 : 1) * speed * this.zoomSensitivity;

        this._rotating = false;

        if (this.autoRotate && this._mode === 'rotate') {
            this._startCountingStill();
        }

        e.event.preventDefault();
    },

    _mouseUpHandler: function () {
        this.zr.off('mousemove', this._mouseMoveHandler);
        this.zr.off('mouseup', this._mouseUpHandler);
    },

    _isRightMouseButtonUsed: function () {
        return this.rotateMouseButton === 'right'
            || this.panMouseButton === 'right';
    },

    _contextMenuHandler: function (e) {
        if (this._isRightMouseButtonUsed()) {
            e.preventDefault();
        }
    },

    _addAnimator: function (animator) {
        var animators = this._animators;
        animators.push(animator);
        animator.done(function () {
            var idx = animators.indexOf(animator);
            if (idx >= 0) {
                animators.splice(idx, 1);
            }
        });
        return animator;
    }
});

/**
 * If auto rotate the target
 * @type {boolean}
 * @default false
 */
Object.defineProperty(OrbitControl.prototype, 'autoRotate', {
    get: function (val) {
        return this._autoRotate;
    },
    set: function (val) {
        this._autoRotate = val;
        this._rotating = val;
    }
});


/* harmony default export */ __webpack_exports__["a"] = (OrbitControl);

/***/ }),
/* 46 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.lines3D.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nattribute vec3 position: POSITION;\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n\nvoid main()\n{\n gl_Position = worldViewProjection * vec4(position, 1.0);\n v_Color = a_Color;\n}\n\n@end\n\n@export ecgl.lines3D.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nvarying vec4 v_Color;\n\n@import clay.util.srgb\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color * v_Color);\n#else\n gl_FragColor = color * v_Color;\n#endif\n}\n@end\n\n\n\n@export ecgl.lines3D.clipNear\n\nvec4 clipNear(vec4 p1, vec4 p2) {\n float n = (p1.w - near) / (p1.w - p2.w);\n return vec4(mix(p1.xy, p2.xy, n), -near, near);\n}\n\n@end\n\n@export ecgl.lines3D.expandLine\n#ifdef VERTEX_ANIMATION\n vec4 prevProj = worldViewProjection * vec4(mix(prevPositionPrev, positionPrev, percent), 1.0);\n vec4 currProj = worldViewProjection * vec4(mix(prevPosition, position, percent), 1.0);\n vec4 nextProj = worldViewProjection * vec4(mix(prevPositionNext, positionNext, percent), 1.0);\n#else\n vec4 prevProj = worldViewProjection * vec4(positionPrev, 1.0);\n vec4 currProj = worldViewProjection * vec4(position, 1.0);\n vec4 nextProj = worldViewProjection * vec4(positionNext, 1.0);\n#endif\n\n if (currProj.w < 0.0) {\n if (nextProj.w > 0.0) {\n currProj = clipNear(currProj, nextProj);\n }\n else if (prevProj.w > 0.0) {\n currProj = clipNear(currProj, prevProj);\n }\n }\n\n vec2 prevScreen = (prevProj.xy / abs(prevProj.w) + 1.0) * 0.5 * viewport.zw;\n vec2 currScreen = (currProj.xy / abs(currProj.w) + 1.0) * 0.5 * viewport.zw;\n vec2 nextScreen = (nextProj.xy / abs(nextProj.w) + 1.0) * 0.5 * viewport.zw;\n\n vec2 dir;\n float len = offset;\n if (position == positionPrev) {\n dir = normalize(nextScreen - currScreen);\n }\n else if (position == positionNext) {\n dir = normalize(currScreen - prevScreen);\n }\n else {\n vec2 dirA = normalize(currScreen - prevScreen);\n vec2 dirB = normalize(nextScreen - currScreen);\n\n vec2 tanget = normalize(dirA + dirB);\n\n float miter = 1.0 / max(dot(tanget, dirA), 0.5);\n len *= miter;\n dir = tanget;\n }\n\n dir = vec2(-dir.y, dir.x) * len;\n currScreen += dir;\n\n currProj.xy = (currScreen / viewport.zw - 0.5) * 2.0 * abs(currProj.w);\n@end\n\n\n@export ecgl.meshLines3D.vertex\n\nattribute vec3 position: POSITION;\nattribute vec3 positionPrev;\nattribute vec3 positionNext;\nattribute float offset;\nattribute vec4 a_Color : COLOR;\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nattribute vec3 prevPositionPrev;\nattribute vec3 prevPositionNext;\nuniform float percent : 1.0;\n#endif\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec4 viewport : VIEWPORT;\nuniform float near : NEAR;\n\nvarying vec4 v_Color;\n\n@import ecgl.common.wireframe.vertexHeader\n\n@import ecgl.lines3D.clipNear\n\nvoid main()\n{\n @import ecgl.lines3D.expandLine\n\n gl_Position = currProj;\n\n v_Color = a_Color;\n\n @import ecgl.common.wireframe.vertexMain\n}\n@end\n\n\n@export ecgl.meshLines3D.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nvarying vec4 v_Color;\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.util.srgb\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color * v_Color);\n#else\n gl_FragColor = color * v_Color;\n#endif\n\n @import ecgl.common.wireframe.fragmentMain\n}\n\n@end");


/***/ }),
/* 47 */
/***/ (function(module, exports, __webpack_require__) {

var zrUtil = __webpack_require__(13);

var BoundingRect = __webpack_require__(82);

var _number = __webpack_require__(85);

var parsePercent = _number.parsePercent;

var formatUtil = __webpack_require__(171);

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

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

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

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

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

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

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

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

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

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

    if (child.newline) {
      return;
    }

    position[0] = x;
    position[1] = y;
    orient === 'horizontal' ? x = nextX + gap : y = nextY + gap;
  });
}
/**
 * VBox or HBox layouting
 * @param {string} orient
 * @param {module:zrender/container/Group} group
 * @param {number} gap
 * @param {number} [width=Infinity]
 * @param {number} [height=Infinity]
 */


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

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

var hbox = zrUtil.curry(boxLayout, 'horizontal');
/**
 * If x or x2 is not specified or 'center' 'left' 'right',
 * the width would be as long as possible.
 * If y or y2 is not specified or 'middle' 'top' 'bottom',
 * the height would be as long as possible.
 *
 * @param {Object} positionInfo
 * @param {number|string} [positionInfo.x]
 * @param {number|string} [positionInfo.y]
 * @param {number|string} [positionInfo.x2]
 * @param {number|string} [positionInfo.y2]
 * @param {Object} containerRect {width, height}
 * @param {string|number} margin
 * @return {Object} {width, height}
 */

function getAvailableSize(positionInfo, containerRect, margin) {
  var containerWidth = containerRect.width;
  var containerHeight = containerRect.height;
  var x = parsePercent(positionInfo.x, containerWidth);
  var y = parsePercent(positionInfo.y, containerHeight);
  var x2 = parsePercent(positionInfo.x2, containerWidth);
  var y2 = parsePercent(positionInfo.y2, containerHeight);
  (isNaN(x) || isNaN(parseFloat(positionInfo.x))) && (x = 0);
  (isNaN(x2) || isNaN(parseFloat(positionInfo.x2))) && (x2 = containerWidth);
  (isNaN(y) || isNaN(parseFloat(positionInfo.y))) && (y = 0);
  (isNaN(y2) || isNaN(parseFloat(positionInfo.y2))) && (y2 = containerHeight);
  margin = formatUtil.normalizeCssArray(margin || 0);
  return {
    width: Math.max(x2 - x - margin[1] - margin[3], 0),
    height: Math.max(y2 - y - margin[0] - margin[2], 0)
  };
}
/**
 * Parse position info.
 *
 * @param {Object} positionInfo
 * @param {number|string} [positionInfo.left]
 * @param {number|string} [positionInfo.top]
 * @param {number|string} [positionInfo.right]
 * @param {number|string} [positionInfo.bottom]
 * @param {number|string} [positionInfo.width]
 * @param {number|string} [positionInfo.height]
 * @param {number|string} [positionInfo.aspect] Aspect is width / height
 * @param {Object} containerRect
 * @param {string|number} [margin]
 *
 * @return {module:zrender/core/BoundingRect}
 */


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

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

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

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


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

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


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

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


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

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

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

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


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

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

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

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


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

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

  var rect;

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

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

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


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

  var elPos = el.position;
  var dx = h ? positionInfo.x - rect.x : 0;
  var dy = v ? positionInfo.y - rect.y : 0;
  el.attr('position', boundingMode === 'raw' ? [dx, dy] : [elPos[0] + dx, elPos[1] + dy]);
}
/**
 * @param {Object} option Contains some of the properties in HV_NAMES.
 * @param {number} hvIdx 0: horizontal; 1: vertical.
 */


function sizeCalculable(option, hvIdx) {
  return option[HV_NAMES[hvIdx][0]] != null || option[HV_NAMES[hvIdx][1]] != null && option[HV_NAMES[hvIdx][2]] != null;
}
/**
 * Consider Case:
 * When defulat option has {left: 0, width: 100}, and we set {right: 0}
 * through setOption or media query, using normal zrUtil.merge will cause
 * {right: 0} does not take effect.
 *
 * @example
 * ComponentModel.extend({
 *     init: function () {
 *         ...
 *         var inputPositionParams = layout.getLayoutParams(option);
 *         this.mergeOption(inputPositionParams);
 *     },
 *     mergeOption: function (newOption) {
 *         newOption && zrUtil.merge(thisOption, newOption, true);
 *         layout.mergeLayoutParam(thisOption, newOption);
 *     }
 * });
 *
 * @param {Object} targetOption
 * @param {Object} newOption
 * @param {Object|string} [opt]
 * @param {boolean|Array.<boolean>} [opt.ignoreSize=false] Used for the components
 *  that width (or height) should not be calculated by left and right (or top and bottom).
 */


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

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

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

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


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

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

        return newParams;
      }
  }

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

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

  function copy(names, target, source) {
    each(names, function (name) {
      target[name] = source[name];
    });
  }
}
/**
 * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.
 * @param {Object} source
 * @return {Object} Result contains those props.
 */


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


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

exports.LOCATION_PARAMS = LOCATION_PARAMS;
exports.HV_NAMES = HV_NAMES;
exports.box = box;
exports.vbox = vbox;
exports.hbox = hbox;
exports.getAvailableSize = getAvailableSize;
exports.getLayoutRect = getLayoutRect;
exports.positionElement = positionElement;
exports.sizeCalculable = sizeCalculable;
exports.mergeLayoutParam = mergeLayoutParam;
exports.getLayoutParams = getLayoutParams;
exports.copyLayoutParams = copyLayoutParams;

/***/ }),
/* 48 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(7);


// PENDING
// Use topological sort ?

/**
 * Node of graph based post processing.
 *
 * @constructor clay.compositor.CompositorNode
 * @extends clay.core.Base
 *
 */
var CompositorNode = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
    return /** @lends clay.compositor.CompositorNode# */ {
        /**
         * @type {string}
         */
        name: '',

        /**
         * Input links, will be updated by the graph
         * @example:
         *     inputName: {
         *         node: someNode,
         *         pin: 'xxxx'
         *     }
         * @type {Object}
         */
        inputLinks: {},

        /**
         * Output links, will be updated by the graph
         * @example:
         *     outputName: {
         *         node: someNode,
         *         pin: 'xxxx'
         *     }
         * @type {Object}
         */
        outputLinks: {},

        // Save the output texture of previous frame
        // Will be used when there exist a circular reference
        _prevOutputTextures: {},
        _outputTextures: {},

        // Example: { name: 2 }
        _outputReferences: {},

        _rendering: false,
        // If rendered in this frame
        _rendered: false,

        _compositor: null
    };
},
/** @lends clay.compositor.CompositorNode.prototype */
{

    // TODO Remove parameter function callback
    updateParameter: function (outputName, renderer) {
        var outputInfo = this.outputs[outputName];
        var parameters = outputInfo.parameters;
        var parametersCopy = outputInfo._parametersCopy;
        if (!parametersCopy) {
            parametersCopy = outputInfo._parametersCopy = {};
        }
        if (parameters) {
            for (var key in parameters) {
                if (key !== 'width' && key !== 'height') {
                    parametersCopy[key] = parameters[key];
                }
            }
        }
        var width, height;
        if (parameters.width instanceof Function) {
            width = parameters.width.call(this, renderer);
        }
        else {
            width = parameters.width;
        }
        if (parameters.height instanceof Function) {
            height = parameters.height.call(this, renderer);
        }
        else {
            height = parameters.height;
        }
        if (
            parametersCopy.width !== width
            || parametersCopy.height !== height
        ) {
            if (this._outputTextures[outputName]) {
                this._outputTextures[outputName].dispose(renderer.gl);
            }
        }
        parametersCopy.width = width;
        parametersCopy.height = height;

        return parametersCopy;
    },

    /**
     * Set parameter
     * @param {string} name
     * @param {} value
     */
    setParameter: function (name, value) {},
    /**
     * Get parameter value
     * @param  {string} name
     * @return {}
     */
    getParameter: function (name) {},
    /**
     * Set parameters
     * @param {Object} obj
     */
    setParameters: function (obj) {
        for (var name in obj) {
            this.setParameter(name, obj[name]);
        }
    },

    render: function () {},

    getOutput: function (renderer /*optional*/, name) {
        if (name == null) {
            // Return the output texture without rendering
            name = renderer;
            return this._outputTextures[name];
        }
        var outputInfo = this.outputs[name];
        if (!outputInfo) {
            return ;
        }

        // Already been rendered in this frame
        if (this._rendered) {
            // Force return texture in last frame
            if (outputInfo.outputLastFrame) {
                return this._prevOutputTextures[name];
            }
            else {
                return this._outputTextures[name];
            }
        }
        else if (
            // TODO
            this._rendering   // Solve Circular Reference
        ) {
            if (!this._prevOutputTextures[name]) {
                // Create a blank texture at first pass
                this._prevOutputTextures[name] = this._compositor.allocateTexture(outputInfo.parameters || {});
            }
            return this._prevOutputTextures[name];
        }

        this.render(renderer);

        return this._outputTextures[name];
    },

    removeReference: function (outputName) {
        this._outputReferences[outputName]--;
        if (this._outputReferences[outputName] === 0) {
            var outputInfo = this.outputs[outputName];
            if (outputInfo.keepLastFrame) {
                if (this._prevOutputTextures[outputName]) {
                    this._compositor.releaseTexture(this._prevOutputTextures[outputName]);
                }
                this._prevOutputTextures[outputName] = this._outputTextures[outputName];
            }
            else {
                // Output of this node have alreay been used by all other nodes
                // Put the texture back to the pool.
                this._compositor.releaseTexture(this._outputTextures[outputName]);
            }
        }
    },

    link: function (inputPinName, fromNode, fromPinName) {

        // The relationship from output pin to input pin is one-on-multiple
        this.inputLinks[inputPinName] = {
            node: fromNode,
            pin: fromPinName
        };
        if (!fromNode.outputLinks[fromPinName]) {
            fromNode.outputLinks[fromPinName] = [];
        }
        fromNode.outputLinks[fromPinName].push({
            node: this,
            pin: inputPinName
        });

        // Enabled the pin texture in shader
        this.pass.material.enableTexture(inputPinName);
    },

    clear: function () {
        this.inputLinks = {};
        this.outputLinks = {};
    },

    updateReference: function (outputName) {
        if (!this._rendering) {
            this._rendering = true;
            for (var inputName in this.inputLinks) {
                var link = this.inputLinks[inputName];
                link.node.updateReference(link.pin);
            }
            this._rendering = false;
        }
        if (outputName) {
            this._outputReferences[outputName] ++;
        }
    },

    beforeFrame: function () {
        this._rendered = false;

        for (var name in this.outputLinks) {
            this._outputReferences[name] = 0;
        }
    },

    afterFrame: function () {
        // Put back all the textures to pool
        for (var name in this.outputLinks) {
            if (this._outputReferences[name] > 0) {
                var outputInfo = this.outputs[name];
                if (outputInfo.keepLastFrame) {
                    if (this._prevOutputTextures[name]) {
                        this._compositor.releaseTexture(this._prevOutputTextures[name]);
                    }
                    this._prevOutputTextures[name] = this._outputTextures[name];
                }
                else {
                    this._compositor.releaseTexture(this._outputTextures[name]);
                }
            }
        }
    }
});

/* harmony default export */ __webpack_exports__["a"] = (CompositorNode);


/***/ }),
/* 49 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";

// Generate halton sequence
// https://en.wikipedia.org/wiki/Halton_sequence
function halton(index, base) {

    var result = 0;
    var f = 1 / base;
    var i = index;
    while (i > 0) {
        result = result + f * (i % base);
        i = Math.floor(i / base);
        f = f / base;
    }
    return result;
}


/* harmony default export */ __webpack_exports__["a"] = (halton);

/***/ }),
/* 50 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


/* harmony default export */ __webpack_exports__["a"] = (function (seriesModel, dims, source) {
    source = source || seriesModel.getSource();

    var coordSysDimensions = dims || __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.getCoordinateSystemDimensions(seriesModel.get('coordinateSystem')) || ['x', 'y', 'z'];

    var dimensions = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.createDimensions(source, {
        dimensionsDefine: source.dimensionsDefine || seriesModel.get('dimensions'),
        encodeDefine: source.encodeDefine || seriesModel.get('encode'),
        coordDimensions: coordSysDimensions.map(function (dim) {
            var axis3DModel = seriesModel.getReferringComponents(dim + 'Axis3D')[0];
            return {
                type: (axis3DModel && axis3DModel.get('type') === 'category') ? 'ordinal' : 'float',
                name: dim
                // Find stackable dimension. Which will represent value.
                // stackable: dim === 'z'
            };
        })
    });
    if (seriesModel.get('coordinateSystem') === 'cartesian3D') {
        dimensions.forEach(function (dimInfo) {
            if (coordSysDimensions.indexOf(dimInfo.coordDim) >= 0) {
                var axis3DModel = seriesModel.getReferringComponents(dimInfo.coordDim + 'Axis3D')[0];
                if (axis3DModel && axis3DModel.get('type') === 'category') {
                    dimInfo.ordinalMeta = axis3DModel.getOrdinalMeta();
                }
            }
        });
    }

    var stackCalculationInfo = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.dataStack.enableDataStack(
        // Only support 'z' and `byIndex` now.
        seriesModel, dimensions, {byIndex: true, stackedCoordDimension: 'z'}
    );

    var data = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(dimensions, seriesModel);

    data.setCalculationInfo(stackCalculationInfo);

    data.initData(source);

    return data;
});

/***/ }),
/* 51 */
/***/ (function(module, exports) {

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
function _default(seriesType, defaultSymbolType, legendSymbol) {
  // Encoding visual for all series include which is filtered for legend drawing
  return {
    seriesType: seriesType,
    // For legend.
    performRawSeries: true,
    reset: function (seriesModel, ecModel, api) {
      var data = seriesModel.getData();
      var symbolType = seriesModel.get('symbol') || defaultSymbolType;
      var symbolSize = seriesModel.get('symbolSize');
      var keepAspect = seriesModel.get('symbolKeepAspect');
      data.setVisual({
        legendSymbol: legendSymbol || symbolType,
        symbol: symbolType,
        symbolSize: symbolSize,
        symbolKeepAspect: keepAspect
      }); // Only visible series has each data be visual encoded

      if (ecModel.isSeriesFiltered(seriesModel)) {
        return;
      }

      var hasCallback = typeof symbolSize === 'function';

      function dataEach(data, idx) {
        if (typeof symbolSize === 'function') {
          var rawValue = seriesModel.getRawValue(idx); // FIXME

          var params = seriesModel.getDataParams(idx);
          data.setItemVisual(idx, 'symbolSize', symbolSize(rawValue, params));
        }

        if (data.hasItemOption) {
          var itemModel = data.getItemModel(idx);
          var itemSymbolType = itemModel.getShallow('symbol', true);
          var itemSymbolSize = itemModel.getShallow('symbolSize', true);
          var itemSymbolKeepAspect = itemModel.getShallow('symbolKeepAspect', true); // If has item symbol

          if (itemSymbolType != null) {
            data.setItemVisual(idx, 'symbol', itemSymbolType);
          }

          if (itemSymbolSize != null) {
            // PENDING Transform symbolSize ?
            data.setItemVisual(idx, 'symbolSize', itemSymbolSize);
          }

          if (itemSymbolKeepAspect != null) {
            data.setItemVisual(idx, 'symbolKeepAspect', itemSymbolKeepAspect);
          }
        }
      }

      return {
        dataEach: data.hasItemOption || hasCallback ? dataEach : null
      };
    }
  };
}

module.exports = _default;

/***/ }),
/* 52 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_GLInfo__ = __webpack_require__(111);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_vendor__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Material__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__math_Vector2__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__gpu_ProgramManager__ = __webpack_require__(115);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__shader_source_prez_glsl_js__ = __webpack_require__(71);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__glmatrix_vec3__ = __webpack_require__(12);
// TODO Resources like shader, texture, geometry reference management
// Trace and find out which shader, texture, geometry can be destroyed









// Light header



__WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_8__shader_source_prez_glsl_js__["a" /* default */]);




var mat4Create = __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].create;

var errorShader = {};

function defaultGetMaterial(renderable) {
    return renderable.material;
}
function defaultGetUniform(renderable, material, symbol) {
    return material.uniforms[symbol].value;
}
function defaultIsMaterialChanged(renderabled, prevRenderable, material, prevMaterial) {
    return material !== prevMaterial;
}
function defaultIfRender(renderable) {
    return true;
}

function noop() {}

var attributeBufferTypeMap = {
    float: __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].FLOAT,
    byte: __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].BYTE,
    ubyte: __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].UNSIGNED_BYTE,
    short: __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].SHORT,
    ushort: __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].UNSIGNED_SHORT
};

function VertexArrayObject(availableAttributes, availableAttributeSymbols, indicesBuffer) {
    this.availableAttributes = availableAttributes;
    this.availableAttributeSymbols = availableAttributeSymbols;
    this.indicesBuffer = indicesBuffer;

    this.vao = null;
}

function PlaceHolderTexture(renderer) {
    var blankCanvas;
    var webglTexture;
    this.bind = function (renderer) {
        if (!blankCanvas) {
            // TODO Environment not support createCanvas.
            blankCanvas = __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].createCanvas();
            blankCanvas.width = blankCanvas.height = 1;
            blankCanvas.getContext('2d');
        }

        var gl = renderer.gl;
        var firstBind = !webglTexture;
        if (firstBind) {
            webglTexture = gl.createTexture();
        }
        gl.bindTexture(gl.TEXTURE_2D, webglTexture);
        if (firstBind) {
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, blankCanvas);
        }
    };
    this.unbind = function (renderer) {
        renderer.gl.bindTexture(renderer.gl.TEXTURE_2D, null);
    };
    this.isRenderable = function () {
        return true;
    };
}
/**
 * @constructor clay.Renderer
 * @extends clay.core.Base
 */
var Renderer = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
    return /** @lends clay.Renderer# */ {

        /**
         * @type {HTMLCanvasElement}
         * @readonly
         */
        canvas: null,

        /**
         * Canvas width, set by resize method
         * @type {number}
         * @private
         */
        _width: 100,

        /**
         * Canvas width, set by resize method
         * @type {number}
         * @private
         */
        _height: 100,

        /**
         * Device pixel ratio, set by setDevicePixelRatio method
         * Specially for high defination display
         * @see http://www.khronos.org/webgl/wiki/HandlingHighDPI
         * @type {number}
         * @private
         */
        devicePixelRatio: (typeof window !== 'undefined' && window.devicePixelRatio) || 1.0,

        /**
         * Clear color
         * @type {number[]}
         */
        clearColor: [0.0, 0.0, 0.0, 0.0],

        /**
         * Default:
         *     _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT
         * @type {number}
         */
        clearBit: 17664,

        // Settings when getting context
        // http://www.khronos.org/registry/webgl/specs/latest/#2.4

        /**
         * If enable alpha, default true
         * @type {boolean}
         */
        alpha: true,
        /**
         * If enable depth buffer, default true
         * @type {boolean}
         */
        depth: true,
        /**
         * If enable stencil buffer, default false
         * @type {boolean}
         */
        stencil: false,
        /**
         * If enable antialias, default true
         * @type {boolean}
         */
        antialias: true,
        /**
         * If enable premultiplied alpha, default true
         * @type {boolean}
         */
        premultipliedAlpha: true,
        /**
         * If preserve drawing buffer, default false
         * @type {boolean}
         */
        preserveDrawingBuffer: false,
        /**
         * If throw context error, usually turned on in debug mode
         * @type {boolean}
         */
        throwError: true,
        /**
         * WebGL Context created from given canvas
         * @type {WebGLRenderingContext}
         */
        gl: null,
        /**
         * Renderer viewport, read-only, can be set by setViewport method
         * @type {Object}
         */
        viewport: {},

        // Set by FrameBuffer#bind
        __currentFrameBuffer: null,

        _viewportStack: [],
        _clearStack: [],

        _sceneRendering: null
    };
}, function () {

    if (!this.canvas) {
        this.canvas = __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].createCanvas();
    }
    var canvas = this.canvas;
    try {
        var opts = {
            alpha: this.alpha,
            depth: this.depth,
            stencil: this.stencil,
            antialias: this.antialias,
            premultipliedAlpha: this.premultipliedAlpha,
            preserveDrawingBuffer: this.preserveDrawingBuffer
        };

        this.gl = canvas.getContext('webgl', opts)
            || canvas.getContext('experimental-webgl', opts);

        if (!this.gl) {
            throw new Error();
        }

        this._glinfo = new __WEBPACK_IMPORTED_MODULE_1__core_GLInfo__["a" /* default */](this.gl);

        if (this.gl.targetRenderer) {
            console.error('Already created a renderer');
        }
        this.gl.targetRenderer = this;

        this.resize();
    }
    catch (e) {
        throw 'Error creating WebGL Context ' + e;
    }

    // Init managers
    this._programMgr = new __WEBPACK_IMPORTED_MODULE_6__gpu_ProgramManager__["a" /* default */](this);

    this._placeholderTexture = new PlaceHolderTexture(this);
},
/** @lends clay.Renderer.prototype. **/
{
    /**
     * Resize the canvas
     * @param {number} width
     * @param {number} height
     */
    resize: function(width, height) {
        var canvas = this.canvas;
        // http://www.khronos.org/webgl/wiki/HandlingHighDPI
        // set the display size of the canvas.
        var dpr = this.devicePixelRatio;
        if (width != null) {
            canvas.style.width = width + 'px';
            canvas.style.height = height + 'px';
            // set the size of the drawingBuffer
            canvas.width = width * dpr;
            canvas.height = height * dpr;

            this._width = width;
            this._height = height;
        }
        else {
            this._width = canvas.width / dpr;
            this._height = canvas.height / dpr;
        }

        this.setViewport(0, 0, this._width, this._height);
    },

    /**
     * Get renderer width
     * @return {number}
     */
    getWidth: function () {
        return this._width;
    },

    /**
     * Get renderer height
     * @return {number}
     */
    getHeight: function () {
        return this._height;
    },

    /**
     * Get viewport aspect,
     * @return {number}
     */
    getViewportAspect: function () {
        var viewport = this.viewport;
        return viewport.width / viewport.height;
    },

    /**
     * Set devicePixelRatio
     * @param {number} devicePixelRatio
     */
    setDevicePixelRatio: function(devicePixelRatio) {
        this.devicePixelRatio = devicePixelRatio;
        this.resize(this._width, this._height);
    },

    /**
     * Get devicePixelRatio
     * @param {number} devicePixelRatio
     */
    getDevicePixelRatio: function () {
        return this.devicePixelRatio;
    },

    /**
     * Get WebGL extension
     * @param {string} name
     * @return {object}
     */
    getGLExtension: function (name) {
        return this._glinfo.getExtension(name);
    },

    /**
     * Get WebGL parameter
     * @param {string} name
     * @return {*}
     */
    getGLParameter: function (name) {
        return this._glinfo.getParameter(name);
    },

    /**
     * Set rendering viewport
     * @param {number|Object} x
     * @param {number} [y]
     * @param {number} [width]
     * @param {number} [height]
     * @param {number} [devicePixelRatio]
     *        Defaultly use the renderere devicePixelRatio
     *        It needs to be 1 when setViewport is called by frameBuffer
     *
     * @example
     *  setViewport(0,0,width,height,1)
     *  setViewport({
     *      x: 0,
     *      y: 0,
     *      width: width,
     *      height: height,
     *      devicePixelRatio: 1
     *  })
     */
    setViewport: function (x, y, width, height, dpr) {

        if (typeof x === 'object') {
            var obj = x;

            x = obj.x;
            y = obj.y;
            width = obj.width;
            height = obj.height;
            dpr = obj.devicePixelRatio;
        }
        dpr = dpr || this.devicePixelRatio;

        this.gl.viewport(
            x * dpr, y * dpr, width * dpr, height * dpr
        );
        // Use a fresh new object, not write property.
        this.viewport = {
            x: x,
            y: y,
            width: width,
            height: height,
            devicePixelRatio: dpr
        };
    },

    /**
     * Push current viewport into a stack
     */
    saveViewport: function () {
        this._viewportStack.push(this.viewport);
    },

    /**
     * Pop viewport from stack, restore in the renderer
     */
    restoreViewport: function () {
        if (this._viewportStack.length > 0) {
            this.setViewport(this._viewportStack.pop());
        }
    },

    /**
     * Push current clear into a stack
     */
    saveClear: function () {
        this._clearStack.push({
            clearBit: this.clearBit,
            clearColor: this.clearColor
        });
    },

    /**
     * Pop clear from stack, restore in the renderer
     */
    restoreClear: function () {
        if (this._clearStack.length > 0) {
            var opt = this._clearStack.pop();
            this.clearColor = opt.clearColor;
            this.clearBit = opt.clearBit;
        }
    },

    bindSceneRendering: function (scene) {
        this._sceneRendering = scene;
    },

    /**
     * Render the scene in camera to the screen or binded offline framebuffer
     * @param  {clay.Scene}       scene
     * @param  {clay.Camera}      camera
     * @param  {boolean}     [notUpdateScene] If not call the scene.update methods in the rendering, default true
     * @param  {boolean}     [preZ]           If use preZ optimization, default false
     * @return {IRenderInfo}
     */
    render: function(scene, camera, notUpdateScene, preZ) {
        var _gl = this.gl;

        var clearColor = this.clearColor;

        if (this.clearBit) {

            // Must set depth and color mask true before clear
            _gl.colorMask(true, true, true, true);
            _gl.depthMask(true);
            var viewport = this.viewport;
            var needsScissor = false;
            var viewportDpr = viewport.devicePixelRatio;
            if (viewport.width !== this._width || viewport.height !== this._height
                || (viewportDpr && viewportDpr !== this.devicePixelRatio)
                || viewport.x || viewport.y
            ) {
                needsScissor = true;
                // http://stackoverflow.com/questions/11544608/how-to-clear-a-rectangle-area-in-webgl
                // Only clear the viewport
                _gl.enable(_gl.SCISSOR_TEST);
                _gl.scissor(viewport.x * viewportDpr, viewport.y * viewportDpr, viewport.width * viewportDpr, viewport.height * viewportDpr);
            }
            _gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
            _gl.clear(this.clearBit);
            if (needsScissor) {
                _gl.disable(_gl.SCISSOR_TEST);
            }
        }

        // If the scene have been updated in the prepass like shadow map
        // There is no need to update it again
        if (!notUpdateScene) {
            scene.update(false);
        }
        scene.updateLights();

        camera = camera || scene.getMainCamera();
        if (!camera) {
            console.error('Can\'t find camera in the scene.');
            return;
        }
        camera.update();
        var renderList = scene.updateRenderList(camera, true);

        this._sceneRendering = scene;

        var opaqueList = renderList.opaque;
        var transparentList = renderList.transparent;
        var sceneMaterial = scene.material;

        scene.trigger('beforerender', this, scene, camera, renderList);

        // Render pre z
        if (preZ) {
            this.renderPreZ(opaqueList, scene, camera);
            _gl.depthFunc(_gl.LEQUAL);
        }
        else {
            _gl.depthFunc(_gl.LESS);
        }

        // Update the depth of transparent list.
        var worldViewMat = mat4Create();
        var posViewSpace = __WEBPACK_IMPORTED_MODULE_10__glmatrix_vec3__["a" /* default */].create();
        for (var i = 0; i < transparentList.length; i++) {
            var renderable = transparentList[i];
            __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].multiplyAffine(worldViewMat, camera.viewMatrix.array, renderable.worldTransform.array);
            __WEBPACK_IMPORTED_MODULE_10__glmatrix_vec3__["a" /* default */].transformMat4(posViewSpace, renderable.position.array, worldViewMat);
            renderable.__depth = posViewSpace[2];
        }

        // Render opaque list
        this.renderPass(opaqueList, camera, {
            getMaterial: function (renderable) {
                return sceneMaterial || renderable.material;
            },
            sortCompare: this.opaqueSortCompare
        });

        this.renderPass(transparentList, camera, {
            getMaterial: function (renderable) {
                return sceneMaterial || renderable.material;
            },
            sortCompare: this.transparentSortCompare
        });

        scene.trigger('afterrender', this, scene, camera, renderList);

        // Cleanup
        this._sceneRendering = null;
    },

    getProgram: function (renderable, renderMaterial, scene) {
        renderMaterial = renderMaterial || renderable.material;
        return this._programMgr.getProgram(renderable, renderMaterial, scene);
    },

    validateProgram: function (program) {
        if (program.__error) {
            var errorMsg = program.__error;
            if (errorShader[program.__uid__]) {
                return;
            }
            errorShader[program.__uid__] = true;

            if (this.throwError) {
                throw new Error(errorMsg);
            }
            else {
                this.trigger('error', errorMsg);
            }
        }

    },

    updatePrograms: function (list, scene, passConfig) {
        var getMaterial = (passConfig && passConfig.getMaterial) || defaultGetMaterial;
        scene = scene || null;
        for (var i = 0; i < list.length; i++) {
            var renderable = list[i];
            var renderMaterial = getMaterial.call(this, renderable);
            if (i > 0) {
                var prevRenderable = list[i - 1];
                var prevJointsLen = prevRenderable.joints ? prevRenderable.joints.length : 0;
                var jointsLen = renderable.joints ? renderable.joints.length : 0;
                // Keep program not change if joints, material, lightGroup are same of two renderables.
                if (jointsLen === prevJointsLen
                    && renderable.material === prevRenderable.material
                    && renderable.lightGroup === prevRenderable.lightGroup
                ) {
                    renderable.__program = prevRenderable.__program;
                    continue;
                }
            }

            var program = this._programMgr.getProgram(renderable, renderMaterial, scene);

            this.validateProgram(program);

            renderable.__program = program;
        }
    },

    /**
     * Render a single renderable list in camera in sequence
     * @param {clay.Renderable[]} list List of all renderables.
     * @param {clay.Camera} [camera] Camera provide view matrix and porjection matrix. It can be null.
     * @param {Object} [passConfig]
     * @param {Function} [passConfig.getMaterial] Get renderable material.
     * @param {Function} [passConfig.getUniform] Get material uniform value.
     * @param {Function} [passConfig.isMaterialChanged] If material changed.
     * @param {Function} [passConfig.beforeRender] Before render each renderable.
     * @param {Function} [passConfig.afterRender] After render each renderable
     * @param {Function} [passConfig.ifRender] If render the renderable.
     * @param {Function} [passConfig.sortCompare] Sort compare function.
     * @return {IRenderInfo}
     */
    renderPass: function(list, camera, passConfig) {
        this.trigger('beforerenderpass', this, list, camera, passConfig);

        passConfig = passConfig || {};
        passConfig.getMaterial = passConfig.getMaterial || defaultGetMaterial;
        passConfig.getUniform = passConfig.getUniform || defaultGetUniform;
        // PENDING Better solution?
        passConfig.isMaterialChanged = passConfig.isMaterialChanged || defaultIsMaterialChanged;
        passConfig.beforeRender = passConfig.beforeRender || noop;
        passConfig.afterRender = passConfig.afterRender || noop;

        var ifRenderObject = passConfig.ifRender || defaultIfRender;

        this.updatePrograms(list, this._sceneRendering, passConfig);
        if (passConfig.sortCompare) {
            list.sort(passConfig.sortCompare);
        }

        // Some common builtin uniforms
        var viewport = this.viewport;
        var vDpr = viewport.devicePixelRatio;
        var viewportUniform = [
            viewport.x * vDpr, viewport.y * vDpr,
            viewport.width * vDpr, viewport.height * vDpr
        ];
        var windowDpr = this.devicePixelRatio;
        var windowSizeUniform = this.__currentFrameBuffer
            ? [this.__currentFrameBuffer.getTextureWidth(), this.__currentFrameBuffer.getTextureHeight()]
            : [this._width * windowDpr, this._height * windowDpr];
        // DEPRECATED
        var viewportSizeUniform = [
            viewportUniform[2], viewportUniform[3]
        ];
        var time = Date.now();

        // Calculate view and projection matrix
        if (camera) {
            __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].copy(matrices.VIEW, camera.viewMatrix.array);
            __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].copy(matrices.PROJECTION, camera.projectionMatrix.array);
            __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].copy(matrices.VIEWINVERSE, camera.worldTransform.array);
        }
        else {
            __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].identity(matrices.VIEW);
            __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].identity(matrices.PROJECTION);
            __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].identity(matrices.VIEWINVERSE);
        }
        __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].multiply(matrices.VIEWPROJECTION, matrices.PROJECTION, matrices.VIEW);
        __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].invert(matrices.PROJECTIONINVERSE, matrices.PROJECTION);
        __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].invert(matrices.VIEWPROJECTIONINVERSE, matrices.VIEWPROJECTION);

        var _gl = this.gl;
        var scene = this._sceneRendering;

        var prevMaterial;
        var prevProgram;
        var prevRenderable;

        // Status
        var depthTest, depthMask;
        var culling, cullFace, frontFace;
        var transparent;
        var drawID;
        var currentVAO;
        var materialTakesTextureSlot;

        var vaoExt = this.getGLExtension('OES_vertex_array_object');

        for (var i = 0; i < list.length; i++) {
            var renderable = list[i];
            var isSceneNode = renderable.worldTransform != null;
            var worldM;

            if (!ifRenderObject(renderable)) {
                continue;
            }

            // Skinned mesh will transformed to joint space. Ignore the mesh transform
            if (isSceneNode) {
                worldM = (renderable.isSkinnedMesh && renderable.isSkinnedMesh())
                    ? matrices.IDENTITY : renderable.worldTransform.array;
            }
            var geometry = renderable.geometry;
            var material = passConfig.getMaterial.call(this, renderable);

            var program = renderable.__program;
            var shader = material.shader;

            var currentDrawID = geometry.__uid__ + '-' + program.__uid__;
            var drawIDChanged = currentDrawID !== drawID;
            drawID = currentDrawID;
            if (drawIDChanged && vaoExt) {
                // TODO Seems need to be bound to null immediately (or before bind another program?) if vao is changed
                vaoExt.bindVertexArrayOES(null);
            }
            if (isSceneNode) {
                __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].copy(matrices.WORLD, worldM);
                __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].multiply(matrices.WORLDVIEWPROJECTION, matrices.VIEWPROJECTION, worldM);
                __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].multiplyAffine(matrices.WORLDVIEW, matrices.VIEW, worldM);
                if (shader.matrixSemantics.WORLDINVERSE ||
                    shader.matrixSemantics.WORLDINVERSETRANSPOSE) {
                    __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].invert(matrices.WORLDINVERSE, worldM);
                }
                if (shader.matrixSemantics.WORLDVIEWINVERSE ||
                    shader.matrixSemantics.WORLDVIEWINVERSETRANSPOSE) {
                    __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].invert(matrices.WORLDVIEWINVERSE, matrices.WORLDVIEW);
                }
                if (shader.matrixSemantics.WORLDVIEWPROJECTIONINVERSE ||
                    shader.matrixSemantics.WORLDVIEWPROJECTIONINVERSETRANSPOSE) {
                    __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].invert(matrices.WORLDVIEWPROJECTIONINVERSE, matrices.WORLDVIEWPROJECTION);
                }
            }

            // Before render hook
            renderable.beforeRender && renderable.beforeRender(this);
            passConfig.beforeRender.call(this, renderable, material, prevMaterial);

            var programChanged = program !== prevProgram;
            if (programChanged) {
                // Set lights number
                program.bind(this);
                // Set some common uniforms
                program.setUniformOfSemantic(_gl, 'VIEWPORT', viewportUniform);
                program.setUniformOfSemantic(_gl, 'WINDOW_SIZE', windowSizeUniform);
                if (camera) {
                    program.setUniformOfSemantic(_gl, 'NEAR', camera.near);
                    program.setUniformOfSemantic(_gl, 'FAR', camera.far);
                }
                program.setUniformOfSemantic(_gl, 'DEVICEPIXELRATIO', vDpr);
                program.setUniformOfSemantic(_gl, 'TIME', time);
                // DEPRECATED
                program.setUniformOfSemantic(_gl, 'VIEWPORT_SIZE', viewportSizeUniform);

                // Set lights uniforms
                // TODO needs optimized
                if (scene) {
                    scene.setLightUniforms(program, renderable.lightGroup, this);
                }
            }
            else {
                program = prevProgram;
            }

            // Program changes also needs reset the materials.
            if (programChanged || passConfig.isMaterialChanged(
                renderable, prevRenderable, material, prevMaterial
            )) {
                if (material.depthTest !== depthTest) {
                    material.depthTest ? _gl.enable(_gl.DEPTH_TEST) : _gl.disable(_gl.DEPTH_TEST);
                    depthTest = material.depthTest;
                }
                if (material.depthMask !== depthMask) {
                    _gl.depthMask(material.depthMask);
                    depthMask = material.depthMask;
                }
                if (material.transparent !== transparent) {
                    material.transparent ? _gl.enable(_gl.BLEND) : _gl.disable(_gl.BLEND);
                    transparent = material.transparent;
                }
                // TODO cache blending
                if (material.transparent) {
                    if (material.blend) {
                        material.blend(_gl);
                    }
                    else {
                        // Default blend function
                        _gl.blendEquationSeparate(_gl.FUNC_ADD, _gl.FUNC_ADD);
                        _gl.blendFuncSeparate(_gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA);
                    }
                }

                materialTakesTextureSlot = this._bindMaterial(
                    renderable, material, program,
                    prevRenderable || null, prevMaterial || null, prevProgram || null,
                    passConfig.getUniform
                );
                prevMaterial = material;
            }

            var matrixSemanticKeys = shader.matrixSemanticKeys;

            if (isSceneNode) {
                for (var k = 0; k < matrixSemanticKeys.length; k++) {
                    var semantic = matrixSemanticKeys[k];
                    var semanticInfo = shader.matrixSemantics[semantic];
                    var matrix = matrices[semantic];
                    if (semanticInfo.isTranspose) {
                        var matrixNoTranspose = matrices[semanticInfo.semanticNoTranspose];
                        __WEBPACK_IMPORTED_MODULE_9__glmatrix_mat4__["a" /* default */].transpose(matrix, matrixNoTranspose);
                    }
                    program.setUniform(_gl, semanticInfo.type, semanticInfo.symbol, matrix);
                }
            }

            if (renderable.cullFace !== cullFace) {
                cullFace = renderable.cullFace;
                _gl.cullFace(cullFace);
            }
            if (renderable.frontFace !== frontFace) {
                frontFace = renderable.frontFace;
                _gl.frontFace(frontFace);
            }
            if (renderable.culling !== culling) {
                culling = renderable.culling;
                culling ? _gl.enable(_gl.CULL_FACE) : _gl.disable(_gl.CULL_FACE);
            }
            // TODO Not update skeleton in each renderable.
            this._updateSkeleton(renderable, program, materialTakesTextureSlot);
            if (drawIDChanged) {
                currentVAO = this._bindVAO(vaoExt, shader, geometry, program);
            }
            this._renderObject(renderable, currentVAO);

            // After render hook
            passConfig.afterRender(this, renderable);
            renderable.afterRender && renderable.afterRender(this);

            prevProgram = program;
            prevRenderable = renderable;
        }

        // TODO Seems need to be bound to null immediately if vao is changed?
        if (vaoExt) {
            vaoExt.bindVertexArrayOES(null);
        }

        this.trigger('afterrenderpass', this, list, camera, passConfig);
    },

    getMaxJointNumber: function () {
        return this._glinfo.getMaxJointNumber();
    },

    _updateSkeleton: function (object, program, slot) {
        var _gl = this.gl;
        var skeleton = object.skeleton;
        // Set pose matrices of skinned mesh
        if (skeleton) {
            // TODO Update before culling.
            skeleton.update();
            if (object.joints.length > this._glinfo.getMaxJointNumber()) {
                var skinMatricesTexture = skeleton.getSubSkinMatricesTexture(object.__uid__, object.joints);
                program.useTextureSlot(this, skinMatricesTexture, slot);
                program.setUniform(_gl, '1i', 'skinMatricesTexture', slot);
                program.setUniform(_gl, '1f', 'skinMatricesTextureSize', skinMatricesTexture.width);
            }
            else {
                var skinMatricesArray = skeleton.getSubSkinMatrices(object.__uid__, object.joints);
                program.setUniformOfSemantic(_gl, 'SKIN_MATRIX', skinMatricesArray);
            }
        }
    },

    _renderObject: function (renderable, vao) {
        var _gl = this.gl;
        var geometry = renderable.geometry;

        var glDrawMode = renderable.mode;
        if (glDrawMode == null) {
            glDrawMode = 0x0004;
        }

        // if (glDrawMode === glenum.LINES || glDrawMode === glenum.LINE_STRIP || glDrawMode === glenum.LINE_LOOP) {
        //     _gl.lineWidth(this.lineWidth);
        // }

        if (vao.indicesBuffer) {
            var uintExt = this.getGLExtension('OES_element_index_uint');
            var useUintExt = uintExt && (geometry.indices instanceof Uint32Array);
            var indicesType = useUintExt ? _gl.UNSIGNED_INT : _gl.UNSIGNED_SHORT;

            _gl.drawElements(glDrawMode, vao.indicesBuffer.count, indicesType, 0);
        }
        else {
            // FIXME Use vertex number in buffer
            // vertexCount may get the wrong value when geometry forget to mark dirty after update
            _gl.drawArrays(glDrawMode, 0, geometry.vertexCount);
        }
    },

    _bindMaterial: function (renderable, material, program, prevRenderable, prevMaterial, prevProgram, getUniformValue) {
        var _gl = this.gl;
        // PENDING Same texture in different material take different slot?

        // May use shader of other material if shader code are same
        var sameProgram = prevProgram === program;

        var currentTextureSlot = program.currentTextureSlot();
        var enabledUniforms = material.getEnabledUniforms();
        var textureUniforms = material.getTextureUniforms();
        var placeholderTexture = this._placeholderTexture;

        for (var u = 0; u < textureUniforms.length; u++) {
            var symbol = textureUniforms[u];
            var uniformValue = getUniformValue(renderable, material, symbol);
            var uniformType = material.uniforms[symbol].type;
            // Not use `instanceof` to determine if a value is texture in Material#bind.
            // Use type instead, in some case texture may be in different namespaces.
            // TODO Duck type validate.
            if (uniformType === 't' && uniformValue) {
                // Reset slot
                uniformValue.__slot = -1;
            }
            else if (uniformType === 'tv') {
                for (var i = 0; i < uniformValue.length; i++) {
                    if (uniformValue[i]) {
                        uniformValue[i].__slot = -1;
                    }
                }
            }
        }

        placeholderTexture.__slot = -1;

        // Set uniforms
        for (var u = 0; u < enabledUniforms.length; u++) {
            var symbol = enabledUniforms[u];
            var uniform = material.uniforms[symbol];
            var uniformValue = getUniformValue(renderable, material, symbol);
            var uniformType = uniform.type;
            var isTexture = uniformType === 't';

            if (isTexture) {
                if (!uniformValue || !uniformValue.isRenderable()) {
                    uniformValue = placeholderTexture;
                }
            }
            // PENDING
            // When binding two materials with the same shader
            // Many uniforms will be be set twice even if they have the same value
            // So add a evaluation to see if the uniform is really needed to be set
            if (prevMaterial && sameProgram) {
                var prevUniformValue = getUniformValue(prevRenderable, prevMaterial, symbol);
                if (isTexture) {
                    if (!prevUniformValue || !prevUniformValue.isRenderable()) {
                        prevUniformValue = placeholderTexture;
                    }
                }

                if (prevUniformValue === uniformValue) {
                    if (isTexture) {
                        // Still take the slot to make sure same texture in different materials have same slot.
                        program.takeCurrentTextureSlot(this, null);
                    }
                    else if (uniformType === 'tv' && uniformValue) {
                        for (var i = 0; i < uniformValue.length; i++) {
                            program.takeCurrentTextureSlot(this, null);
                        }
                    }
                    continue;
                }
            }

            if (uniformValue == null) {
                continue;
            }
            else if (isTexture) {
                if (uniformValue.__slot < 0) {
                    var slot = program.currentTextureSlot();
                    var res = program.setUniform(_gl, '1i', symbol, slot);
                    if (res) { // Texture uniform is enabled
                        program.takeCurrentTextureSlot(this, uniformValue);
                        uniformValue.__slot = slot;
                    }
                }
                // Multiple uniform use same texture..
                else {
                    program.setUniform(_gl, '1i', symbol, uniformValue.__slot);
                }
            }
            else if (Array.isArray(uniformValue)) {
                if (uniformValue.length === 0) {
                    continue;
                }
                // Texture Array
                if (uniformType === 'tv') {
                    if (!program.hasUniform(symbol)) {
                        continue;
                    }

                    var arr = [];
                    for (var i = 0; i < uniformValue.length; i++) {
                        var texture = uniformValue[i];

                        if (texture.__slot < 0) {
                            var slot = program.currentTextureSlot();
                            arr.push(slot);
                            program.takeCurrentTextureSlot(this, texture);
                            texture.__slot = slot;
                        }
                        else {
                            arr.push(texture.__slot);
                        }
                    }

                    program.setUniform(_gl, '1iv', symbol, arr);
                }
                else {
                    program.setUniform(_gl, uniform.type, symbol, uniformValue);
                }
            }
            else{
                program.setUniform(_gl, uniform.type, symbol, uniformValue);
            }
        }
        var newSlot = program.currentTextureSlot();
        // Texture slot maybe used out of material.
        program.resetTextureSlot(currentTextureSlot);
        return newSlot;
    },

    _bindVAO: function (vaoExt, shader, geometry, program) {
        var isStatic = !geometry.dynamic;
        var _gl = this.gl;

        var vaoId = this.__uid__ + '-' + program.__uid__;
        var vao = geometry.__vaoCache[vaoId];
        if (!vao) {
            var chunks = geometry.getBufferChunks(this);
            if (!chunks || !chunks.length) {  // Empty mesh
                return;
            }
            var chunk = chunks[0];
            var attributeBuffers = chunk.attributeBuffers;
            var indicesBuffer = chunk.indicesBuffer;

            var availableAttributes = [];
            var availableAttributeSymbols = [];
            for (var a = 0; a < attributeBuffers.length; a++) {
                var attributeBufferInfo = attributeBuffers[a];
                var name = attributeBufferInfo.name;
                var semantic = attributeBufferInfo.semantic;
                var symbol;
                if (semantic) {
                    var semanticInfo = shader.attributeSemantics[semantic];
                    symbol = semanticInfo && semanticInfo.symbol;
                }
                else {
                    symbol = name;
                }
                if (symbol && program.attributes[symbol]) {
                    availableAttributes.push(attributeBufferInfo);
                    availableAttributeSymbols.push(symbol);
                }
            }

            vao = new VertexArrayObject(
                availableAttributes,
                availableAttributeSymbols,
                indicesBuffer
            );

            if (isStatic) {
                geometry.__vaoCache[vaoId] = vao;
            }
        }

        var needsBindAttributes = true;

        // Create vertex object array cost a lot
        // So we don't use it on the dynamic object
        if (vaoExt && isStatic) {
            // Use vertex array object
            // http://blog.tojicode.com/2012/10/oesvertexarrayobject-extension.html
            if (vao.vao == null) {
                vao.vao = vaoExt.createVertexArrayOES();
            }
            else {
                needsBindAttributes = false;
            }
            vaoExt.bindVertexArrayOES(vao.vao);
        }

        var availableAttributes = vao.availableAttributes;
        var indicesBuffer = vao.indicesBuffer;

        if (needsBindAttributes) {
            var locationList = program.enableAttributes(this, vao.availableAttributeSymbols, (vaoExt && isStatic && vao));
            // Setting attributes;
            for (var a = 0; a < availableAttributes.length; a++) {
                var location = locationList[a];
                if (location === -1) {
                    continue;
                }
                var attributeBufferInfo = availableAttributes[a];
                var buffer = attributeBufferInfo.buffer;
                var size = attributeBufferInfo.size;
                var glType = attributeBufferTypeMap[attributeBufferInfo.type] || _gl.FLOAT;

                _gl.bindBuffer(_gl.ARRAY_BUFFER, buffer);
                _gl.vertexAttribPointer(location, size, glType, false, 0, 0);
            }

            if (geometry.isUseIndices()) {
                _gl.bindBuffer(_gl.ELEMENT_ARRAY_BUFFER, indicesBuffer.buffer);
            }
        }

        return vao;
    },

    renderPreZ: function (list, scene, camera) {
        var _gl = this.gl;
        var preZPassMaterial = this._prezMaterial || new __WEBPACK_IMPORTED_MODULE_4__Material__["a" /* default */]({
            shader: new __WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */](__WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */].source('clay.prez.vertex'), __WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */].source('clay.prez.fragment'))
        });
        this._prezMaterial = preZPassMaterial;

        _gl.colorMask(false, false, false, false);
        _gl.depthMask(true);

        // Status
        this.renderPass(list, camera, {
            ifRender: function (renderable) {
                return !renderable.ignorePreZ;
            },
            isMaterialChanged: function (renderable, prevRenderable) {
                var matA = renderable.material;
                var matB = prevRenderable.material;
                return matA.get('diffuseMap') !== matB.get('diffuseMap')
                    || (matA.get('alphaCutoff') || 0) !== (matB.get('alphaCutoff') || 0);
            },
            getUniform: function (renderable, depthMaterial, symbol) {
                if (symbol === 'alphaMap') {
                    return renderable.material.get('diffuseMap');
                }
                else if (symbol === 'alphaCutoff') {
                    if (renderable.material.isDefined('fragment', 'ALPHA_TEST')
                        && renderable.material.get('diffuseMap')
                    ) {
                        var alphaCutoff = renderable.material.get('alphaCutoff');
                        return alphaCutoff || 0;
                    }
                    return 0;
                }
                else {
                    return depthMaterial.get(symbol);
                }
            },
            getMaterial: function () {
                return preZPassMaterial;
            },
            sort: this.opaqueSortCompare
        });

        _gl.colorMask(true, true, true, true);
        _gl.depthMask(true);
    },

    /**
     * Dispose given scene, including all geometris, textures and shaders in the scene
     * @param {clay.Scene} scene
     */
    disposeScene: function(scene) {
        this.disposeNode(scene, true, true);
        scene.dispose();
    },

    /**
     * Dispose given node, including all geometries, textures and shaders attached on it or its descendant
     * @param {clay.Node} node
     * @param {boolean} [disposeGeometry=false] If dispose the geometries used in the descendant mesh
     * @param {boolean} [disposeTexture=false] If dispose the textures used in the descendant mesh
     */
    disposeNode: function(root, disposeGeometry, disposeTexture) {
        // Dettached from parent
        if (root.getParent()) {
            root.getParent().remove(root);
        }
        var disposedMap = {};
        root.traverse(function(node) {
            var material = node.material;
            if (node.geometry && disposeGeometry) {
                node.geometry.dispose(this);
            }
            if (disposeTexture && material && !disposedMap[material.__uid__]) {
                var textureUniforms = material.getTextureUniforms();
                for (var u = 0; u < textureUniforms.length; u++) {
                    var uniformName = textureUniforms[u];
                    var val = material.uniforms[uniformName].value;
                    var uniformType = material.uniforms[uniformName].type;
                    if (!val) {
                        continue;
                    }
                    if (uniformType === 't') {
                        val.dispose && val.dispose(this);
                    }
                    else if (uniformType === 'tv') {
                        for (var k = 0; k < val.length; k++) {
                            if (val[k]) {
                                val[k].dispose && val[k].dispose(this);
                            }
                        }
                    }
                }
                disposedMap[material.__uid__] = true;
            }
            // Particle system and AmbientCubemap light need to dispose
            if (node.dispose) {
                node.dispose(this);
            }
        }, this);
    },

    /**
     * Dispose given geometry
     * @param {clay.Geometry} geometry
     */
    disposeGeometry: function(geometry) {
        geometry.dispose(this);
    },

    /**
     * Dispose given texture
     * @param {clay.Texture} texture
     */
    disposeTexture: function(texture) {
        texture.dispose(this);
    },

    /**
     * Dispose given frame buffer
     * @param {clay.FrameBuffer} frameBuffer
     */
    disposeFrameBuffer: function(frameBuffer) {
        frameBuffer.dispose(this);
    },

    /**
     * Dispose renderer
     */
    dispose: function () {},

    /**
     * Convert screen coords to normalized device coordinates(NDC)
     * Screen coords can get from mouse event, it is positioned relative to canvas element
     * NDC can be used in ray casting with Camera.prototype.castRay methods
     *
     * @param  {number}       x
     * @param  {number}       y
     * @param  {clay.Vector2} [out]
     * @return {clay.Vector2}
     */
    screenToNDC: function(x, y, out) {
        if (!out) {
            out = new __WEBPACK_IMPORTED_MODULE_5__math_Vector2__["a" /* default */]();
        }
        // Invert y;
        y = this._height - y;

        var viewport = this.viewport;
        var arr = out.array;
        arr[0] = (x - viewport.x) / viewport.width;
        arr[0] = arr[0] * 2 - 1;
        arr[1] = (y - viewport.y) / viewport.height;
        arr[1] = arr[1] * 2 - 1;

        return out;
    }
});

/**
 * Opaque renderables compare function
 * @param  {clay.Renderable} x
 * @param  {clay.Renderable} y
 * @return {boolean}
 * @static
 */
Renderer.opaqueSortCompare = Renderer.prototype.opaqueSortCompare = function(x, y) {
    // Priority renderOrder -> program -> material -> geometry
    if (x.renderOrder === y.renderOrder) {
        if (x.__program === y.__program) {
            if (x.material === y.material) {
                return x.geometry.__uid__ - y.geometry.__uid__;
            }
            return x.material.__uid__ - y.material.__uid__;
        }
        if (x.__program && y.__program) {
            return x.__program.__uid__ - y.__program.__uid__;
        }
        return 0;
    }
    return x.renderOrder - y.renderOrder;
};

/**
 * Transparent renderables compare function
 * @param  {clay.Renderable} a
 * @param  {clay.Renderable} b
 * @return {boolean}
 * @static
 */
Renderer.transparentSortCompare = Renderer.prototype.transparentSortCompare = function(x, y) {
    // Priority renderOrder -> depth -> program -> material -> geometry

    if (x.renderOrder === y.renderOrder) {
        if (x.__depth === y.__depth) {
            if (x.__program === y.__program) {
                if (x.material === y.material) {
                    return x.geometry.__uid__ - y.geometry.__uid__;
                }
                return x.material.__uid__ - y.material.__uid__;
            }
            if (x.__program  && y.__program) {
                return x.__program.__uid__ - y.__program.__uid__;
            }
            return 0;
        }
        // Depth is negative
        // So farther object has smaller depth value
        return x.__depth - y.__depth;
    }
    return x.renderOrder - y.renderOrder;
};

// Temporary variables
var matrices = {
    IDENTITY: mat4Create(),

    WORLD: mat4Create(),
    VIEW: mat4Create(),
    PROJECTION: mat4Create(),
    WORLDVIEW: mat4Create(),
    VIEWPROJECTION: mat4Create(),
    WORLDVIEWPROJECTION: mat4Create(),

    WORLDINVERSE: mat4Create(),
    VIEWINVERSE: mat4Create(),
    PROJECTIONINVERSE: mat4Create(),
    WORLDVIEWINVERSE: mat4Create(),
    VIEWPROJECTIONINVERSE: mat4Create(),
    WORLDVIEWPROJECTIONINVERSE: mat4Create(),

    WORLDTRANSPOSE: mat4Create(),
    VIEWTRANSPOSE: mat4Create(),
    PROJECTIONTRANSPOSE: mat4Create(),
    WORLDVIEWTRANSPOSE: mat4Create(),
    VIEWPROJECTIONTRANSPOSE: mat4Create(),
    WORLDVIEWPROJECTIONTRANSPOSE: mat4Create(),
    WORLDINVERSETRANSPOSE: mat4Create(),
    VIEWINVERSETRANSPOSE: mat4Create(),
    PROJECTIONINVERSETRANSPOSE: mat4Create(),
    WORLDVIEWINVERSETRANSPOSE: mat4Create(),
    VIEWPROJECTIONINVERSETRANSPOSE: mat4Create(),
    WORLDVIEWPROJECTIONINVERSETRANSPOSE: mat4Create()
};

/**
 * @name clay.Renderer.COLOR_BUFFER_BIT
 * @type {number}
 */
Renderer.COLOR_BUFFER_BIT = __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].COLOR_BUFFER_BIT;
/**
 * @name clay.Renderer.DEPTH_BUFFER_BIT
 * @type {number}
 */
Renderer.DEPTH_BUFFER_BIT = __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].DEPTH_BUFFER_BIT;
/**
 * @name clay.Renderer.STENCIL_BUFFER_BIT
 * @type {number}
 */
Renderer.STENCIL_BUFFER_BIT = __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].STENCIL_BUFFER_BIT;

/* harmony default export */ __webpack_exports__["a"] = (Renderer);


/***/ }),
/* 53 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
function Handler(action, context) {
    this.action = action;
    this.context = context;
}
/**
 * @mixin
 * @alias clay.core.mixin.notifier
 */
var notifier = {
    /**
     * Trigger event
     * @param  {string} name
     */
    trigger: function(name) {
        if (!this.hasOwnProperty('__handlers__')) {
            return;
        }
        if (!this.__handlers__.hasOwnProperty(name)) {
            return;
        }

        var hdls = this.__handlers__[name];
        var l = hdls.length, i = -1, args = arguments;
        // Optimize advise from backbone
        switch (args.length) {
            case 1:
                while (++i < l) {
                    hdls[i].action.call(hdls[i].context);
                }
                return;
            case 2:
                while (++i < l) {
                    hdls[i].action.call(hdls[i].context, args[1]);
                }
                return;
            case 3:
                while (++i < l) {
                    hdls[i].action.call(hdls[i].context, args[1], args[2]);
                }
                return;
            case 4:
                while (++i < l) {
                    hdls[i].action.call(hdls[i].context, args[1], args[2], args[3]);
                }
                return;
            case 5:
                while (++i < l) {
                    hdls[i].action.call(hdls[i].context, args[1], args[2], args[3], args[4]);
                }
                return;
            default:
                while (++i < l) {
                    hdls[i].action.apply(hdls[i].context, Array.prototype.slice.call(args, 1));
                }
                return;
        }
    },
    /**
     * Register event handler
     * @param  {string} name
     * @param  {Function} action
     * @param  {Object} [context]
     * @chainable
     */
    on: function(name, action, context) {
        if (!name || !action) {
            return;
        }
        var handlers = this.__handlers__ || (this.__handlers__={});
        if (!handlers[name]) {
            handlers[name] = [];
        }
        else {
            if (this.has(name, action)) {
                return;
            }
        }
        var handler = new Handler(action, context || this);
        handlers[name].push(handler);

        return this;
    },

    /**
     * Register event, event will only be triggered once and then removed
     * @param  {string} name
     * @param  {Function} action
     * @param  {Object} [context]
     * @chainable
     */
    once: function(name, action, context) {
        if (!name || !action) {
            return;
        }
        var self = this;
        function wrapper() {
            self.off(name, wrapper);
            action.apply(this, arguments);
        }
        return this.on(name, wrapper, context);
    },

    /**
     * Alias of once('before' + name)
     * @param  {string} name
     * @param  {Function} action
     * @param  {Object} [context]
     * @chainable
     */
    before: function(name, action, context) {
        if (!name || !action) {
            return;
        }
        name = 'before' + name;
        return this.on(name, action, context);
    },

    /**
     * Alias of once('after' + name)
     * @param  {string} name
     * @param  {Function} action
     * @param  {Object} [context]
     * @chainable
     */
    after: function(name, action, context) {
        if (!name || !action) {
            return;
        }
        name = 'after' + name;
        return this.on(name, action, context);
    },

    /**
     * Alias of on('success')
     * @param  {Function} action
     * @param  {Object} [context]
     * @chainable
     */
    success: function(action, context) {
        return this.once('success', action, context);
    },

    /**
     * Alias of on('error')
     * @param  {Function} action
     * @param  {Object} [context]
     * @chainable
     */
    error: function(action, context) {
        return this.once('error', action, context);
    },

    /**
     * Remove event listener
     * @param  {Function} action
     * @param  {Object} [context]
     * @chainable
     */
    off: function(name, action) {

        var handlers = this.__handlers__ || (this.__handlers__={});

        if (!action) {
            handlers[name] = [];
            return;
        }
        if (handlers[name]) {
            var hdls = handlers[name];
            var retains = [];
            for (var i = 0; i < hdls.length; i++) {
                if (action && hdls[i].action !== action) {
                    retains.push(hdls[i]);
                }
            }
            handlers[name] = retains;
        }

        return this;
    },

    /**
     * If registered the event handler
     * @param  {string}  name
     * @param  {Function}  action
     * @return {boolean}
     */
    has: function(name, action) {
        var handlers = this.__handlers__;

        if (! handlers ||
            ! handlers[name]) {
            return false;
        }
        var hdls = handlers[name];
        for (var i = 0; i < hdls.length; i++) {
            if (hdls[i].action === action) {
                return true;
            }
        }
    }
};

/* harmony default export */ __webpack_exports__["a"] = (notifier);

/***/ }),
/* 54 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__ = __webpack_require__(12);



var EPSILON = 1e-5;

/**
 * @constructor
 * @alias clay.Ray
 * @param {clay.Vector3} [origin]
 * @param {clay.Vector3} [direction]
 */
var Ray = function (origin, direction) {
    /**
     * @type {clay.Vector3}
     */
    this.origin = origin || new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
    /**
     * @type {clay.Vector3}
     */
    this.direction = direction || new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
};

Ray.prototype = {

    constructor: Ray,

    // http://www.siggraph.org/education/materials/HyperGraph/raytrace/rayplane_intersection.htm
    /**
     * Calculate intersection point between ray and a give plane
     * @param  {clay.Plane} plane
     * @param  {clay.Vector3} [out]
     * @return {clay.Vector3}
     */
    intersectPlane: function (plane, out) {
        var pn = plane.normal.array;
        var d = plane.distance;
        var ro = this.origin.array;
        var rd = this.direction.array;

        var divider = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].dot(pn, rd);
        // ray is parallel to the plane
        if (divider === 0) {
            return null;
        }
        if (!out) {
            out = new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
        }
        var t = (__WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].dot(pn, ro) - d) / divider;
        __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].scaleAndAdd(out.array, ro, rd, -t);
        out._dirty = true;
        return out;
    },

    /**
     * Mirror the ray against plane
     * @param  {clay.Plane} plane
     */
    mirrorAgainstPlane: function (plane) {
        // Distance to plane
        var d = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].dot(plane.normal.array, this.direction.array);
        __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].scaleAndAdd(this.direction.array, this.direction.array, plane.normal.array, -d * 2);
        this.direction._dirty = true;
    },

    distanceToPoint: (function () {
        var v = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();
        return function (point) {
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].sub(v, point, this.origin.array);
            // Distance from projection point to origin
            var b = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].dot(v, this.direction.array);
            if (b < 0) {
                return __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].distance(this.origin.array, point);
            }
            // Squared distance from center to origin
            var c2 = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].lenSquared(v);
            // Squared distance from center to projection point
            return Math.sqrt(c2 - b * b);
        };
    })(),

    /**
     * Calculate intersection point between ray and sphere
     * @param  {clay.Vector3} center
     * @param  {number} radius
     * @param  {clay.Vector3} out
     * @return {clay.Vector3}
     */
    intersectSphere: (function () {
        var v = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();
        return function (center, radius, out) {
            var origin = this.origin.array;
            var direction = this.direction.array;
            center = center.array;
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].sub(v, center, origin);
            // Distance from projection point to origin
            var b = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].dot(v, direction);
            // Squared distance from center to origin
            var c2 = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].squaredLength(v);
            // Squared distance from center to projection point
            var d2 = c2 - b * b;

            var r2 = radius * radius;
            // No intersection
            if (d2 > r2) {
                return;
            }

            var a = Math.sqrt(r2 - d2);
            // First intersect point
            var t0 = b - a;
            // Second intersect point
            var t1 = b + a;

            if (!out) {
                out = new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
            }
            if (t0 < 0) {
                if (t1 < 0) {
                    return null;
                }
                else {
                    __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].scaleAndAdd(out.array, origin, direction, t1);
                    return out;
                }
            }
            else {
                __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].scaleAndAdd(out.array, origin, direction, t0);
                return out;
            }
        };
    })(),

    // http://www.scratchapixel.com/lessons/3d-basic-lessons/lesson-7-intersecting-simple-shapes/ray-box-intersection/
    /**
     * Calculate intersection point between ray and bounding box
     * @param {clay.BoundingBox} bbox
     * @param {clay.Vector3}
     * @return {clay.Vector3}
     */
    intersectBoundingBox: function (bbox, out) {
        var dir = this.direction.array;
        var origin = this.origin.array;
        var min = bbox.min.array;
        var max = bbox.max.array;

        var invdirx = 1 / dir[0];
        var invdiry = 1 / dir[1];
        var invdirz = 1 / dir[2];

        var tmin, tmax, tymin, tymax, tzmin, tzmax;
        if (invdirx >= 0) {
            tmin = (min[0] - origin[0]) * invdirx;
            tmax = (max[0] - origin[0]) * invdirx;
        }
        else {
            tmax = (min[0] - origin[0]) * invdirx;
            tmin = (max[0] - origin[0]) * invdirx;
        }
        if (invdiry >= 0) {
            tymin = (min[1] - origin[1]) * invdiry;
            tymax = (max[1] - origin[1]) * invdiry;
        }
        else {
            tymax = (min[1] - origin[1]) * invdiry;
            tymin = (max[1] - origin[1]) * invdiry;
        }

        if ((tmin > tymax) || (tymin > tmax)) {
            return null;
        }

        if (tymin > tmin || tmin !== tmin) {
            tmin = tymin;
        }
        if (tymax < tmax || tmax !== tmax) {
            tmax = tymax;
        }

        if (invdirz >= 0) {
            tzmin = (min[2] - origin[2]) * invdirz;
            tzmax = (max[2] - origin[2]) * invdirz;
        }
        else {
            tzmax = (min[2] - origin[2]) * invdirz;
            tzmin = (max[2] - origin[2]) * invdirz;
        }

        if ((tmin > tzmax) || (tzmin > tmax)) {
            return null;
        }

        if (tzmin > tmin || tmin !== tmin) {
            tmin = tzmin;
        }
        if (tzmax < tmax || tmax !== tmax) {
            tmax = tzmax;
        }
        if (tmax < 0) {
            return null;
        }

        var t = tmin >= 0 ? tmin : tmax;

        if (!out) {
            out = new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
        }
        __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].scaleAndAdd(out.array, origin, dir, t);
        return out;
    },

    // http://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
    /**
     * Calculate intersection point between ray and three triangle vertices
     * @param {clay.Vector3} a
     * @param {clay.Vector3} b
     * @param {clay.Vector3} c
     * @param {boolean}           singleSided, CW triangle will be ignored
     * @param {clay.Vector3} [out]
     * @param {clay.Vector3} [barycenteric] barycentric coords
     * @return {clay.Vector3}
     */
    intersectTriangle: (function () {

        var eBA = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();
        var eCA = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();
        var AO = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();
        var vCross = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].create();

        return function (a, b, c, singleSided, out, barycenteric) {
            var dir = this.direction.array;
            var origin = this.origin.array;
            a = a.array;
            b = b.array;
            c = c.array;

            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].sub(eBA, b, a);
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].sub(eCA, c, a);

            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].cross(vCross, eCA, dir);

            var det = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].dot(eBA, vCross);

            if (singleSided) {
                if (det > -EPSILON) {
                    return null;
                }
            }
            else {
                if (det > -EPSILON && det < EPSILON) {
                    return null;
                }
            }

            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].sub(AO, origin, a);
            var u = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].dot(vCross, AO) / det;
            if (u < 0 || u > 1) {
                return null;
            }

            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].cross(vCross, eBA, AO);
            var v = __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].dot(dir, vCross) / det;

            if (v < 0 || v > 1 || (u + v > 1)) {
                return null;
            }

            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].cross(vCross, eBA, eCA);
            var t = -__WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].dot(AO, vCross) / det;

            if (t < 0) {
                return null;
            }

            if (!out) {
                out = new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
            }
            if (barycenteric) {
                __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].set(barycenteric, (1 - u - v), u, v);
            }
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_vec3__["a" /* default */].scaleAndAdd(out.array, origin, dir, t);

            return out;
        };
    })(),

    /**
     * Apply an affine transform matrix to the ray
     * @return {clay.Matrix4} matrix
     */
    applyTransform: function (matrix) {
        __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].add(this.direction, this.direction, this.origin);
        __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].transformMat4(this.origin, this.origin, matrix);
        __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].transformMat4(this.direction, this.direction, matrix);

        __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].sub(this.direction, this.direction, this.origin);
        __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].normalize(this.direction, this.direction);
    },

    /**
     * Copy values from another ray
     * @param {clay.Ray} ray
     */
    copy: function (ray) {
        __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].copy(this.origin, ray.origin);
        __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].copy(this.direction, ray.direction);
    },

    /**
     * Clone a new ray
     * @return {clay.Ray}
     */
    clone: function () {
        var ray = new Ray();
        ray.copy(this);
        return ray;
    }
};

/* harmony default export */ __webpack_exports__["a"] = (Ray);


/***/ }),
/* 55 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common__ = __webpack_require__(20);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__vec3__ = __webpack_require__(12);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__vec4__ = __webpack_require__(33);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__mat3__ = __webpack_require__(34);


/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */







/**
 * @class Quaternion
 * @name quat
 */

var quat = {};

/**
 * Creates a new identity quat
 *
 * @returns {quat} a new quaternion
 */
quat.create = function() {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](4);
    out[0] = 0;
    out[1] = 0;
    out[2] = 0;
    out[3] = 1;
    return out;
};

/**
 * Sets a quaternion to represent the shortest rotation from one
 * vector to another.
 *
 * Both vectors are assumed to be unit length.
 *
 * @param {quat} out the receiving quaternion.
 * @param {vec3} a the initial vector
 * @param {vec3} b the destination vector
 * @returns {quat} out
 */
quat.rotationTo = (function() {
    var tmpvec3 = __WEBPACK_IMPORTED_MODULE_1__vec3__["a" /* default */].create();
    var xUnitVec3 = __WEBPACK_IMPORTED_MODULE_1__vec3__["a" /* default */].fromValues(1,0,0);
    var yUnitVec3 = __WEBPACK_IMPORTED_MODULE_1__vec3__["a" /* default */].fromValues(0,1,0);

    return function(out, a, b) {
        var dot = __WEBPACK_IMPORTED_MODULE_1__vec3__["a" /* default */].dot(a, b);
        if (dot < -0.999999) {
            __WEBPACK_IMPORTED_MODULE_1__vec3__["a" /* default */].cross(tmpvec3, xUnitVec3, a);
            if (__WEBPACK_IMPORTED_MODULE_1__vec3__["a" /* default */].length(tmpvec3) < 0.000001)
                __WEBPACK_IMPORTED_MODULE_1__vec3__["a" /* default */].cross(tmpvec3, yUnitVec3, a);
            __WEBPACK_IMPORTED_MODULE_1__vec3__["a" /* default */].normalize(tmpvec3, tmpvec3);
            quat.setAxisAngle(out, tmpvec3, Math.PI);
            return out;
        } else if (dot > 0.999999) {
            out[0] = 0;
            out[1] = 0;
            out[2] = 0;
            out[3] = 1;
            return out;
        } else {
            __WEBPACK_IMPORTED_MODULE_1__vec3__["a" /* default */].cross(tmpvec3, a, b);
            out[0] = tmpvec3[0];
            out[1] = tmpvec3[1];
            out[2] = tmpvec3[2];
            out[3] = 1 + dot;
            return quat.normalize(out, out);
        }
    };
})();

/**
 * Sets the specified quaternion with values corresponding to the given
 * axes. Each axis is a vec3 and is expected to be unit length and
 * perpendicular to all other specified axes.
 *
 * @param {vec3} view  the vector representing the viewing direction
 * @param {vec3} right the vector representing the local "right" direction
 * @param {vec3} up    the vector representing the local "up" direction
 * @returns {quat} out
 */
quat.setAxes = (function() {
    var matr = __WEBPACK_IMPORTED_MODULE_3__mat3__["a" /* default */].create();

    return function(out, view, right, up) {
        matr[0] = right[0];
        matr[3] = right[1];
        matr[6] = right[2];

        matr[1] = up[0];
        matr[4] = up[1];
        matr[7] = up[2];

        matr[2] = -view[0];
        matr[5] = -view[1];
        matr[8] = -view[2];

        return quat.normalize(out, quat.fromMat3(out, matr));
    };
})();

/**
 * Creates a new quat initialized with values from an existing quaternion
 *
 * @param {quat} a quaternion to clone
 * @returns {quat} a new quaternion
 * @function
 */
quat.clone = __WEBPACK_IMPORTED_MODULE_2__vec4__["a" /* default */].clone;

/**
 * Creates a new quat initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {quat} a new quaternion
 * @function
 */
quat.fromValues = __WEBPACK_IMPORTED_MODULE_2__vec4__["a" /* default */].fromValues;

/**
 * Copy the values from one quat to another
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a the source quaternion
 * @returns {quat} out
 * @function
 */
quat.copy = __WEBPACK_IMPORTED_MODULE_2__vec4__["a" /* default */].copy;

/**
 * Set the components of a quat to the given values
 *
 * @param {quat} out the receiving quaternion
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {quat} out
 * @function
 */
quat.set = __WEBPACK_IMPORTED_MODULE_2__vec4__["a" /* default */].set;

/**
 * Set a quat to the identity quaternion
 *
 * @param {quat} out the receiving quaternion
 * @returns {quat} out
 */
quat.identity = function(out) {
    out[0] = 0;
    out[1] = 0;
    out[2] = 0;
    out[3] = 1;
    return out;
};

/**
 * Sets a quat from the given angle and rotation axis,
 * then returns it.
 *
 * @param {quat} out the receiving quaternion
 * @param {vec3} axis the axis around which to rotate
 * @param {Number} rad the angle in radians
 * @returns {quat} out
 **/
quat.setAxisAngle = function(out, axis, rad) {
    rad = rad * 0.5;
    var s = Math.sin(rad);
    out[0] = s * axis[0];
    out[1] = s * axis[1];
    out[2] = s * axis[2];
    out[3] = Math.cos(rad);
    return out;
};

/**
 * Adds two quat's
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a the first operand
 * @param {quat} b the second operand
 * @returns {quat} out
 * @function
 */
quat.add = __WEBPACK_IMPORTED_MODULE_2__vec4__["a" /* default */].add;

/**
 * Multiplies two quat's
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a the first operand
 * @param {quat} b the second operand
 * @returns {quat} out
 */
quat.multiply = function(out, a, b) {
    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
        bx = b[0], by = b[1], bz = b[2], bw = b[3];

    out[0] = ax * bw + aw * bx + ay * bz - az * by;
    out[1] = ay * bw + aw * by + az * bx - ax * bz;
    out[2] = az * bw + aw * bz + ax * by - ay * bx;
    out[3] = aw * bw - ax * bx - ay * by - az * bz;
    return out;
};

/**
 * Alias for {@link quat.multiply}
 * @function
 */
quat.mul = quat.multiply;

/**
 * Scales a quat by a scalar number
 *
 * @param {quat} out the receiving vector
 * @param {quat} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {quat} out
 * @function
 */
quat.scale = __WEBPACK_IMPORTED_MODULE_2__vec4__["a" /* default */].scale;

/**
 * Rotates a quaternion by the given angle about the X axis
 *
 * @param {quat} out quat receiving operation result
 * @param {quat} a quat to rotate
 * @param {number} rad angle (in radians) to rotate
 * @returns {quat} out
 */
quat.rotateX = function (out, a, rad) {
    rad *= 0.5;

    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
        bx = Math.sin(rad), bw = Math.cos(rad);

    out[0] = ax * bw + aw * bx;
    out[1] = ay * bw + az * bx;
    out[2] = az * bw - ay * bx;
    out[3] = aw * bw - ax * bx;
    return out;
};

/**
 * Rotates a quaternion by the given angle about the Y axis
 *
 * @param {quat} out quat receiving operation result
 * @param {quat} a quat to rotate
 * @param {number} rad angle (in radians) to rotate
 * @returns {quat} out
 */
quat.rotateY = function (out, a, rad) {
    rad *= 0.5;

    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
        by = Math.sin(rad), bw = Math.cos(rad);

    out[0] = ax * bw - az * by;
    out[1] = ay * bw + aw * by;
    out[2] = az * bw + ax * by;
    out[3] = aw * bw - ay * by;
    return out;
};

/**
 * Rotates a quaternion by the given angle about the Z axis
 *
 * @param {quat} out quat receiving operation result
 * @param {quat} a quat to rotate
 * @param {number} rad angle (in radians) to rotate
 * @returns {quat} out
 */
quat.rotateZ = function (out, a, rad) {
    rad *= 0.5;

    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
        bz = Math.sin(rad), bw = Math.cos(rad);

    out[0] = ax * bw + ay * bz;
    out[1] = ay * bw - ax * bz;
    out[2] = az * bw + aw * bz;
    out[3] = aw * bw - az * bz;
    return out;
};

/**
 * Calculates the W component of a quat from the X, Y, and Z components.
 * Assumes that quaternion is 1 unit in length.
 * Any existing W component will be ignored.
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a quat to calculate W component of
 * @returns {quat} out
 */
quat.calculateW = function (out, a) {
    var x = a[0], y = a[1], z = a[2];

    out[0] = x;
    out[1] = y;
    out[2] = z;
    out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));
    return out;
};

/**
 * Calculates the dot product of two quat's
 *
 * @param {quat} a the first operand
 * @param {quat} b the second operand
 * @returns {Number} dot product of a and b
 * @function
 */
quat.dot = __WEBPACK_IMPORTED_MODULE_2__vec4__["a" /* default */].dot;

/**
 * Performs a linear interpolation between two quat's
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a the first operand
 * @param {quat} b the second operand
 * @param {Number} t interpolation amount between the two inputs
 * @returns {quat} out
 * @function
 */
quat.lerp = __WEBPACK_IMPORTED_MODULE_2__vec4__["a" /* default */].lerp;

/**
 * Performs a spherical linear interpolation between two quat
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a the first operand
 * @param {quat} b the second operand
 * @param {Number} t interpolation amount between the two inputs
 * @returns {quat} out
 */
quat.slerp = function (out, a, b, t) {
    // benchmarks:
    //    http://jsperf.com/quaternion-slerp-implementations

    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
        bx = b[0], by = b[1], bz = b[2], bw = b[3];

    var        omega, cosom, sinom, scale0, scale1;

    // calc cosine
    cosom = ax * bx + ay * by + az * bz + aw * bw;
    // adjust signs (if necessary)
    if ( cosom < 0.0 ) {
        cosom = -cosom;
        bx = - bx;
        by = - by;
        bz = - bz;
        bw = - bw;
    }
    // calculate coefficients
    if ( (1.0 - cosom) > 0.000001 ) {
        // standard case (slerp)
        omega  = Math.acos(cosom);
        sinom  = Math.sin(omega);
        scale0 = Math.sin((1.0 - t) * omega) / sinom;
        scale1 = Math.sin(t * omega) / sinom;
    } else {
        // "from" and "to" quaternions are very close
        //  ... so we can do a linear interpolation
        scale0 = 1.0 - t;
        scale1 = t;
    }
    // calculate final values
    out[0] = scale0 * ax + scale1 * bx;
    out[1] = scale0 * ay + scale1 * by;
    out[2] = scale0 * az + scale1 * bz;
    out[3] = scale0 * aw + scale1 * bw;

    return out;
};

/**
 * Calculates the inverse of a quat
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a quat to calculate inverse of
 * @returns {quat} out
 */
quat.invert = function(out, a) {
    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
        dot = a0*a0 + a1*a1 + a2*a2 + a3*a3,
        invDot = dot ? 1.0/dot : 0;

    // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0

    out[0] = -a0*invDot;
    out[1] = -a1*invDot;
    out[2] = -a2*invDot;
    out[3] = a3*invDot;
    return out;
};

/**
 * Calculates the conjugate of a quat
 * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a quat to calculate conjugate of
 * @returns {quat} out
 */
quat.conjugate = function (out, a) {
    out[0] = -a[0];
    out[1] = -a[1];
    out[2] = -a[2];
    out[3] = a[3];
    return out;
};

/**
 * Calculates the length of a quat
 *
 * @param {quat} a vector to calculate length of
 * @returns {Number} length of a
 * @function
 */
quat.length = __WEBPACK_IMPORTED_MODULE_2__vec4__["a" /* default */].length;

/**
 * Alias for {@link quat.length}
 * @function
 */
quat.len = quat.length;

/**
 * Calculates the squared length of a quat
 *
 * @param {quat} a vector to calculate squared length of
 * @returns {Number} squared length of a
 * @function
 */
quat.squaredLength = __WEBPACK_IMPORTED_MODULE_2__vec4__["a" /* default */].squaredLength;

/**
 * Alias for {@link quat.squaredLength}
 * @function
 */
quat.sqrLen = quat.squaredLength;

/**
 * Normalize a quat
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a quaternion to normalize
 * @returns {quat} out
 * @function
 */
quat.normalize = __WEBPACK_IMPORTED_MODULE_2__vec4__["a" /* default */].normalize;

/**
 * Creates a quaternion from the given 3x3 rotation matrix.
 *
 * NOTE: The resultant quaternion is not normalized, so you should be sure
 * to renormalize the quaternion yourself where necessary.
 *
 * @param {quat} out the receiving quaternion
 * @param {mat3} m rotation matrix
 * @returns {quat} out
 * @function
 */
quat.fromMat3 = function(out, m) {
    // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
    // article "Quaternion Calculus and Fast Animation".
    var fTrace = m[0] + m[4] + m[8];
    var fRoot;

    if ( fTrace > 0.0 ) {
        // |w| > 1/2, may as well choose w > 1/2
        fRoot = Math.sqrt(fTrace + 1.0);  // 2w
        out[3] = 0.5 * fRoot;
        fRoot = 0.5/fRoot;  // 1/(4w)
        out[0] = (m[5]-m[7])*fRoot;
        out[1] = (m[6]-m[2])*fRoot;
        out[2] = (m[1]-m[3])*fRoot;
    } else {
        // |w| <= 1/2
        var i = 0;
        if ( m[4] > m[0] )
          i = 1;
        if ( m[8] > m[i*3+i] )
          i = 2;
        var j = (i+1)%3;
        var k = (i+2)%3;

        fRoot = Math.sqrt(m[i*3+i]-m[j*3+j]-m[k*3+k] + 1.0);
        out[i] = 0.5 * fRoot;
        fRoot = 0.5 / fRoot;
        out[3] = (m[j*3+k] - m[k*3+j]) * fRoot;
        out[j] = (m[j*3+i] + m[i*3+j]) * fRoot;
        out[k] = (m[k*3+i] + m[i*3+k]) * fRoot;
    }

    return out;
};

/* harmony default export */ __webpack_exports__["a"] = (quat);

/***/ }),
/* 56 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__ = __webpack_require__(55);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__glmatrix_mat3__ = __webpack_require__(34);



/**
 * @constructor
 * @alias clay.Quaternion
 * @param {number} x
 * @param {number} y
 * @param {number} z
 * @param {number} w
 */
var Quaternion = function (x, y, z, w) {

    x = x || 0;
    y = y || 0;
    z = z || 0;
    w = w === undefined ? 1 : w;

    /**
     * Storage of Quaternion, read and write of x, y, z, w will change the values in array
     * All methods also operate on the array instead of x, y, z, w components
     * @name array
     * @type {Float32Array}
     * @memberOf clay.Quaternion#
     */
    this.array = __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].fromValues(x, y, z, w);

    /**
     * Dirty flag is used by the Node to determine
     * if the matrix is updated to latest
     * @name _dirty
     * @type {boolean}
     * @memberOf clay.Quaternion#
     */
    this._dirty = true;
};

Quaternion.prototype = {

    constructor: Quaternion,

    /**
     * Add b to self
     * @param  {clay.Quaternion} b
     * @return {clay.Quaternion}
     */
    add: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].add(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Calculate the w component from x, y, z component
     * @return {clay.Quaternion}
     */
    calculateW: function () {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].calculateW(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Set x, y and z components
     * @param  {number}  x
     * @param  {number}  y
     * @param  {number}  z
     * @param  {number}  w
     * @return {clay.Quaternion}
     */
    set: function (x, y, z, w) {
        this.array[0] = x;
        this.array[1] = y;
        this.array[2] = z;
        this.array[3] = w;
        this._dirty = true;
        return this;
    },

    /**
     * Set x, y, z and w components from array
     * @param  {Float32Array|number[]} arr
     * @return {clay.Quaternion}
     */
    setArray: function (arr) {
        this.array[0] = arr[0];
        this.array[1] = arr[1];
        this.array[2] = arr[2];
        this.array[3] = arr[3];

        this._dirty = true;
        return this;
    },

    /**
     * Clone a new Quaternion
     * @return {clay.Quaternion}
     */
    clone: function () {
        return new Quaternion(this.x, this.y, this.z, this.w);
    },

    /**
     * Calculates the conjugate of self If the quaternion is normalized,
     * this function is faster than invert and produces the same result.
     *
     * @return {clay.Quaternion}
     */
    conjugate: function () {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].conjugate(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Copy from b
     * @param  {clay.Quaternion} b
     * @return {clay.Quaternion}
     */
    copy: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].copy(this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Dot product of self and b
     * @param  {clay.Quaternion} b
     * @return {number}
     */
    dot: function (b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].dot(this.array, b.array);
    },

    /**
     * Set from the given 3x3 rotation matrix
     * @param  {clay.Matrix3} m
     * @return {clay.Quaternion}
     */
    fromMat3: function (m) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].fromMat3(this.array, m.array);
        this._dirty = true;
        return this;
    },

    /**
     * Set from the given 4x4 rotation matrix
     * The 4th column and 4th row will be droped
     * @param  {clay.Matrix4} m
     * @return {clay.Quaternion}
     */
    fromMat4: (function () {
        var m3 = __WEBPACK_IMPORTED_MODULE_1__glmatrix_mat3__["a" /* default */].create();
        return function (m) {
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_mat3__["a" /* default */].fromMat4(m3, m.array);
            // TODO Not like mat4, mat3 in glmatrix seems to be row-based
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_mat3__["a" /* default */].transpose(m3, m3);
            __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].fromMat3(this.array, m3);
            this._dirty = true;
            return this;
        };
    })(),

    /**
     * Set to identity quaternion
     * @return {clay.Quaternion}
     */
    identity: function () {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].identity(this.array);
        this._dirty = true;
        return this;
    },
    /**
     * Invert self
     * @return {clay.Quaternion}
     */
    invert: function () {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].invert(this.array, this.array);
        this._dirty = true;
        return this;
    },
    /**
     * Alias of length
     * @return {number}
     */
    len: function () {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].len(this.array);
    },

    /**
     * Calculate the length
     * @return {number}
     */
    length: function () {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].length(this.array);
    },

    /**
     * Linear interpolation between a and b
     * @param  {clay.Quaternion} a
     * @param  {clay.Quaternion} b
     * @param  {number}  t
     * @return {clay.Quaternion}
     */
    lerp: function (a, b, t) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].lerp(this.array, a.array, b.array, t);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for multiply
     * @param  {clay.Quaternion} b
     * @return {clay.Quaternion}
     */
    mul: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].mul(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for multiplyLeft
     * @param  {clay.Quaternion} a
     * @return {clay.Quaternion}
     */
    mulLeft: function (a) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].multiply(this.array, a.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Mutiply self and b
     * @param  {clay.Quaternion} b
     * @return {clay.Quaternion}
     */
    multiply: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].multiply(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Mutiply a and self
     * Quaternion mutiply is not commutative, so the result of mutiplyLeft is different with multiply.
     * @param  {clay.Quaternion} a
     * @return {clay.Quaternion}
     */
    multiplyLeft: function (a) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].multiply(this.array, a.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Normalize self
     * @return {clay.Quaternion}
     */
    normalize: function () {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].normalize(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Rotate self by a given radian about X axis
     * @param {number} rad
     * @return {clay.Quaternion}
     */
    rotateX: function (rad) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].rotateX(this.array, this.array, rad);
        this._dirty = true;
        return this;
    },

    /**
     * Rotate self by a given radian about Y axis
     * @param {number} rad
     * @return {clay.Quaternion}
     */
    rotateY: function (rad) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].rotateY(this.array, this.array, rad);
        this._dirty = true;
        return this;
    },

    /**
     * Rotate self by a given radian about Z axis
     * @param {number} rad
     * @return {clay.Quaternion}
     */
    rotateZ: function (rad) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].rotateZ(this.array, this.array, rad);
        this._dirty = true;
        return this;
    },

    /**
     * Sets self to represent the shortest rotation from Vector3 a to Vector3 b.
     * a and b needs to be normalized
     * @param  {clay.Vector3} a
     * @param  {clay.Vector3} b
     * @return {clay.Quaternion}
     */
    rotationTo: function (a, b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].rotationTo(this.array, a.array, b.array);
        this._dirty = true;
        return this;
    },
    /**
     * Sets self with values corresponding to the given axes
     * @param {clay.Vector3} view
     * @param {clay.Vector3} right
     * @param {clay.Vector3} up
     * @return {clay.Quaternion}
     */
    setAxes: function (view, right, up) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].setAxes(this.array, view.array, right.array, up.array);
        this._dirty = true;
        return this;
    },

    /**
     * Sets self with a rotation axis and rotation angle
     * @param {clay.Vector3} axis
     * @param {number} rad
     * @return {clay.Quaternion}
     */
    setAxisAngle: function (axis, rad) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].setAxisAngle(this.array, axis.array, rad);
        this._dirty = true;
        return this;
    },
    /**
     * Perform spherical linear interpolation between a and b
     * @param  {clay.Quaternion} a
     * @param  {clay.Quaternion} b
     * @param  {number} t
     * @return {clay.Quaternion}
     */
    slerp: function (a, b, t) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].slerp(this.array, a.array, b.array, t);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for squaredLength
     * @return {number}
     */
    sqrLen: function () {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].sqrLen(this.array);
    },

    /**
     * Squared length of self
     * @return {number}
     */
    squaredLength: function () {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].squaredLength(this.array);
    },

    /**
     * Set from euler
     * @param {clay.Vector3} v
     * @param {String} order
     */
    fromEuler: function (v, order) {
        return Quaternion.fromEuler(this, v, order);
    },

    toString: function () {
        return '[' + Array.prototype.join.call(this.array, ',') + ']';
    },

    toArray: function () {
        return Array.prototype.slice.call(this.array);
    }
};

var defineProperty = Object.defineProperty;
// Getter and Setter
if (defineProperty) {

    var proto = Quaternion.prototype;
    /**
     * @name x
     * @type {number}
     * @memberOf clay.Quaternion
     * @instance
     */
    defineProperty(proto, 'x', {
        get: function () {
            return this.array[0];
        },
        set: function (value) {
            this.array[0] = value;
            this._dirty = true;
        }
    });

    /**
     * @name y
     * @type {number}
     * @memberOf clay.Quaternion
     * @instance
     */
    defineProperty(proto, 'y', {
        get: function () {
            return this.array[1];
        },
        set: function (value) {
            this.array[1] = value;
            this._dirty = true;
        }
    });

    /**
     * @name z
     * @type {number}
     * @memberOf clay.Quaternion
     * @instance
     */
    defineProperty(proto, 'z', {
        get: function () {
            return this.array[2];
        },
        set: function (value) {
            this.array[2] = value;
            this._dirty = true;
        }
    });

    /**
     * @name w
     * @type {number}
     * @memberOf clay.Quaternion
     * @instance
     */
    defineProperty(proto, 'w', {
        get: function () {
            return this.array[3];
        },
        set: function (value) {
            this.array[3] = value;
            this._dirty = true;
        }
    });
}

// Supply methods that are not in place

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} a
 * @param  {clay.Quaternion} b
 * @return {clay.Quaternion}
 */
Quaternion.add = function (out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].add(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {number}     x
 * @param  {number}     y
 * @param  {number}     z
 * @param  {number}     w
 * @return {clay.Quaternion}
 */
Quaternion.set = function (out, x, y, z, w) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].set(out.array, x, y, z, w);
    out._dirty = true;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} b
 * @return {clay.Quaternion}
 */
Quaternion.copy = function (out, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].copy(out.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} a
 * @return {clay.Quaternion}
 */
Quaternion.calculateW = function (out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].calculateW(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} a
 * @return {clay.Quaternion}
 */
Quaternion.conjugate = function (out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].conjugate(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @return {clay.Quaternion}
 */
Quaternion.identity = function (out) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].identity(out.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} a
 * @return {clay.Quaternion}
 */
Quaternion.invert = function (out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].invert(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} a
 * @param  {clay.Quaternion} b
 * @return {number}
 */
Quaternion.dot = function (a, b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].dot(a.array, b.array);
};

/**
 * @param  {clay.Quaternion} a
 * @return {number}
 */
Quaternion.len = function (a) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].length(a.array);
};

// Quaternion.length = Quaternion.len;

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} a
 * @param  {clay.Quaternion} b
 * @param  {number}     t
 * @return {clay.Quaternion}
 */
Quaternion.lerp = function (out, a, b, t) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].lerp(out.array, a.array, b.array, t);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} a
 * @param  {clay.Quaternion} b
 * @param  {number}     t
 * @return {clay.Quaternion}
 */
Quaternion.slerp = function (out, a, b, t) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].slerp(out.array, a.array, b.array, t);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} a
 * @param  {clay.Quaternion} b
 * @return {clay.Quaternion}
 */
Quaternion.mul = function (out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].multiply(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @function
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} a
 * @param  {clay.Quaternion} b
 * @return {clay.Quaternion}
 */
Quaternion.multiply = Quaternion.mul;

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} a
 * @param  {number}     rad
 * @return {clay.Quaternion}
 */
Quaternion.rotateX = function (out, a, rad) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].rotateX(out.array, a.array, rad);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} a
 * @param  {number}     rad
 * @return {clay.Quaternion}
 */
Quaternion.rotateY = function (out, a, rad) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].rotateY(out.array, a.array, rad);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} a
 * @param  {number}     rad
 * @return {clay.Quaternion}
 */
Quaternion.rotateZ = function (out, a, rad) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].rotateZ(out.array, a.array, rad);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Vector3}    axis
 * @param  {number}     rad
 * @return {clay.Quaternion}
 */
Quaternion.setAxisAngle = function (out, axis, rad) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].setAxisAngle(out.array, axis.array, rad);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Quaternion} a
 * @return {clay.Quaternion}
 */
Quaternion.normalize = function (out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].normalize(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} a
 * @return {number}
 */
Quaternion.sqrLen = function (a) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].sqrLen(a.array);
};

/**
 * @function
 * @param  {clay.Quaternion} a
 * @return {number}
 */
Quaternion.squaredLength = Quaternion.sqrLen;

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Matrix3}    m
 * @return {clay.Quaternion}
 */
Quaternion.fromMat3 = function (out, m) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].fromMat3(out.array, m.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Vector3}    view
 * @param  {clay.Vector3}    right
 * @param  {clay.Vector3}    up
 * @return {clay.Quaternion}
 */
Quaternion.setAxes = function (out, view, right, up) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].setAxes(out.array, view.array, right.array, up.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Quaternion} out
 * @param  {clay.Vector3}    a
 * @param  {clay.Vector3}    b
 * @return {clay.Quaternion}
 */
Quaternion.rotationTo = function (out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_quat__["a" /* default */].rotationTo(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * Set quaternion from euler
 * @param {clay.Quaternion} out
 * @param {clay.Vector3} v
 * @param {String} order
 */
Quaternion.fromEuler = function (out, v, order) {

    out._dirty = true;

    v = v.array;
    var target = out.array;
    var c1 = Math.cos(v[0] / 2);
    var c2 = Math.cos(v[1] / 2);
    var c3 = Math.cos(v[2] / 2);
    var s1 = Math.sin(v[0] / 2);
    var s2 = Math.sin(v[1] / 2);
    var s3 = Math.sin(v[2] / 2);

    var order = (order || 'XYZ').toUpperCase();

    // http://www.mathworks.com/matlabcentral/fileexchange/
    //  20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
    //  content/SpinCalc.m

    switch (order) {
        case 'XYZ':
            target[0] = s1 * c2 * c3 + c1 * s2 * s3;
            target[1] = c1 * s2 * c3 - s1 * c2 * s3;
            target[2] = c1 * c2 * s3 + s1 * s2 * c3;
            target[3] = c1 * c2 * c3 - s1 * s2 * s3;
            break;
        case 'YXZ':
            target[0] = s1 * c2 * c3 + c1 * s2 * s3;
            target[1] = c1 * s2 * c3 - s1 * c2 * s3;
            target[2] = c1 * c2 * s3 - s1 * s2 * c3;
            target[3] = c1 * c2 * c3 + s1 * s2 * s3;
            break;
        case 'ZXY':
            target[0] = s1 * c2 * c3 - c1 * s2 * s3;
            target[1] = c1 * s2 * c3 + s1 * c2 * s3;
            target[2] = c1 * c2 * s3 + s1 * s2 * c3;
            target[3] = c1 * c2 * c3 - s1 * s2 * s3;
            break;
        case 'ZYX':
            target[0] = s1 * c2 * c3 - c1 * s2 * s3;
            target[1] = c1 * s2 * c3 + s1 * c2 * s3;
            target[2] = c1 * c2 * s3 - s1 * s2 * c3;
            target[3] = c1 * c2 * c3 + s1 * s2 * s3;
            break;
        case 'YZX':
            target[0] = s1 * c2 * c3 + c1 * s2 * s3;
            target[1] = c1 * s2 * c3 + s1 * c2 * s3;
            target[2] = c1 * c2 * s3 - s1 * s2 * c3;
            target[3] = c1 * c2 * c3 - s1 * s2 * s3;
            break;
        case 'XZY':
            target[0] = s1 * c2 * c3 - c1 * s2 * s3;
            target[1] = c1 * s2 * c3 - s1 * c2 * s3;
            target[2] = c1 * c2 * s3 + s1 * s2 * c3;
            target[3] = c1 * c2 * c3 + s1 * s2 * s3;
            break;
    }
};

/* harmony default export */ __webpack_exports__["a"] = (Quaternion);


/***/ }),
/* 57 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
var DIRTY_PREFIX = '__dt__';

var Cache = function () {

    this._contextId = 0;

    this._caches = [];

    this._context = {};
};

Cache.prototype = {

    use: function (contextId, documentSchema) {
        var caches = this._caches;
        if (!caches[contextId]) {
            caches[contextId] = {};

            if (documentSchema) {
                caches[contextId] = documentSchema();
            }
        }
        this._contextId = contextId;

        this._context = caches[contextId];
    },

    put: function (key, value) {
        this._context[key] = value;
    },

    get: function (key) {
        return this._context[key];
    },

    dirty: function (field) {
        field = field || '';
        var key = DIRTY_PREFIX + field;
        this.put(key, true);
    },

    dirtyAll: function (field) {
        field = field || '';
        var key = DIRTY_PREFIX + field;
        var caches = this._caches;
        for (var i = 0; i < caches.length; i++) {
            if (caches[i]) {
                caches[i][key] = true;
            }
        }
    },

    fresh: function (field) {
        field = field || '';
        var key = DIRTY_PREFIX + field;
        this.put(key, false);
    },

    freshAll: function (field) {
        field = field || '';
        var key = DIRTY_PREFIX + field;
        var caches = this._caches;
        for (var i = 0; i < caches.length; i++) {
            if (caches[i]) {
                caches[i][key] = false;
            }
        }
    },

    isDirty: function (field) {
        field = field || '';
        var key = DIRTY_PREFIX + field;
        var context = this._context;
        return  !context.hasOwnProperty(key)
            || context[key] === true;
    },

    deleteContext: function (contextId) {
        delete this._caches[contextId];
        this._context = {};
    },

    delete: function (key) {
        delete this._context[key];
    },

    clearAll: function () {
        this._caches = {};
    },

    getContext: function () {
        return this._context;
    },

    eachContext : function (cb, context) {
        var keys = Object.keys(this._caches);
        keys.forEach(function (key) {
            cb && cb.call(context, key);
        });
    },

    miss: function (key) {
        return ! this._context.hasOwnProperty(key);
    }
};

Cache.prototype.constructor = Cache;

/* harmony default export */ __webpack_exports__["a"] = (Cache);


/***/ }),
/* 58 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Node__ = __webpack_require__(35);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__math_Frustum__ = __webpack_require__(59);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_Ray__ = __webpack_require__(54);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__glmatrix_vec4__ = __webpack_require__(33);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__glmatrix_vec3__ = __webpack_require__(12);









/**
 * @constructor clay.Camera
 * @extends clay.Node
 */
var Camera = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].extend(function () {
    return /** @lends clay.Camera# */ {
        /**
         * Camera projection matrix
         * @type {clay.Matrix4}
         */
        projectionMatrix: new __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */](),

        /**
         * Inverse of camera projection matrix
         * @type {clay.Matrix4}
         */
        invProjectionMatrix: new __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */](),

        /**
         * View matrix, equal to inverse of camera's world matrix
         * @type {clay.Matrix4}
         */
        viewMatrix: new __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */](),

        /**
         * Camera frustum in view space
         * @type {clay.Frustum}
         */
        frustum: new __WEBPACK_IMPORTED_MODULE_2__math_Frustum__["a" /* default */]()
    };
}, function () {
    this.update(true);
},
/** @lends clay.Camera.prototype */
{

    update: function (force) {
        __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].prototype.update.call(this, force);
        __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */].invert(this.viewMatrix, this.worldTransform);

        this.updateProjectionMatrix();
        __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */].invert(this.invProjectionMatrix, this.projectionMatrix);

        this.frustum.setFromProjection(this.projectionMatrix);
    },

    /**
     * Set camera view matrix
     */
    setViewMatrix: function (viewMatrix) {
        __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */].copy(this.viewMatrix, viewMatrix);
        __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */].invert(this.worldTransform, viewMatrix);
        this.decomposeWorldTransform();
    },

    /**
     * Decompose camera projection matrix
     */
    decomposeProjectionMatrix: function () {},

    /**
     * Set camera projection matrix
     * @param {clay.Matrix4} projectionMatrix
     */
    setProjectionMatrix: function (projectionMatrix) {
        __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */].copy(this.projectionMatrix, projectionMatrix);
        __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */].invert(this.invProjectionMatrix, projectionMatrix);
        this.decomposeProjectionMatrix();
    },
    /**
     * Update projection matrix, called after update
     */
    updateProjectionMatrix: function () {},

    /**
     * Cast a picking ray from camera near plane to far plane
     * @function
     * @param {clay.Vector2} ndc
     * @param {clay.Ray} [out]
     * @return {clay.Ray}
     */
    castRay: (function () {
        var v4 = __WEBPACK_IMPORTED_MODULE_4__glmatrix_vec4__["a" /* default */].create();
        return function (ndc, out) {
            var ray = out !== undefined ? out : new __WEBPACK_IMPORTED_MODULE_3__math_Ray__["a" /* default */]();
            var x = ndc.array[0];
            var y = ndc.array[1];
            __WEBPACK_IMPORTED_MODULE_4__glmatrix_vec4__["a" /* default */].set(v4, x, y, -1, 1);
            __WEBPACK_IMPORTED_MODULE_4__glmatrix_vec4__["a" /* default */].transformMat4(v4, v4, this.invProjectionMatrix.array);
            __WEBPACK_IMPORTED_MODULE_4__glmatrix_vec4__["a" /* default */].transformMat4(v4, v4, this.worldTransform.array);
            __WEBPACK_IMPORTED_MODULE_5__glmatrix_vec3__["a" /* default */].scale(ray.origin.array, v4, 1 / v4[3]);

            __WEBPACK_IMPORTED_MODULE_4__glmatrix_vec4__["a" /* default */].set(v4, x, y, 1, 1);
            __WEBPACK_IMPORTED_MODULE_4__glmatrix_vec4__["a" /* default */].transformMat4(v4, v4, this.invProjectionMatrix.array);
            __WEBPACK_IMPORTED_MODULE_4__glmatrix_vec4__["a" /* default */].transformMat4(v4, v4, this.worldTransform.array);
            __WEBPACK_IMPORTED_MODULE_5__glmatrix_vec3__["a" /* default */].scale(v4, v4, 1 / v4[3]);
            __WEBPACK_IMPORTED_MODULE_5__glmatrix_vec3__["a" /* default */].sub(ray.direction.array, v4, ray.origin.array);

            __WEBPACK_IMPORTED_MODULE_5__glmatrix_vec3__["a" /* default */].normalize(ray.direction.array, ray.direction.array);
            ray.direction._dirty = true;
            ray.origin._dirty = true;

            return ray;
        };
    })(),

    /**
     * @function
     * @name clone
     * @return {clay.Camera}
     * @memberOf clay.Camera.prototype
     */
});

/* harmony default export */ __webpack_exports__["a"] = (Camera);


/***/ }),
/* 59 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__BoundingBox__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Plane__ = __webpack_require__(74);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__ = __webpack_require__(12);





var vec3Set = __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].set;
var vec3Copy = __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].copy;
var vec3TranformMat4 = __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].transformMat4;
var mathMin = Math.min;
var mathMax = Math.max;
/**
 * @constructor
 * @alias clay.Frustum
 */
var Frustum = function() {

    /**
     * Eight planes to enclose the frustum
     * @type {clay.Plane[]}
     */
    this.planes = [];

    for (var i = 0; i < 6; i++) {
        this.planes.push(new __WEBPACK_IMPORTED_MODULE_1__Plane__["a" /* default */]());
    }

    /**
     * Bounding box of frustum
     * @type {clay.BoundingBox}
     */
    this.boundingBox = new __WEBPACK_IMPORTED_MODULE_0__BoundingBox__["a" /* default */]();

    /**
     * Eight vertices of frustum
     * @type {Float32Array[]}
     */
    this.vertices = [];
    for (var i = 0; i < 8; i++) {
        this.vertices[i] = __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].fromValues(0, 0, 0);
    }
};

Frustum.prototype = {

    // http://web.archive.org/web/20120531231005/http://crazyjoke.free.fr/doc/3D/plane%20extraction.pdf
    /**
     * Set frustum from a projection matrix
     * @param {clay.Matrix4} projectionMatrix
     */
    setFromProjection: function(projectionMatrix) {

        var planes = this.planes;
        var m = projectionMatrix.array;
        var m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3];
        var m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7];
        var m8 = m[8], m9 = m[9], m10 = m[10], m11 = m[11];
        var m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15];

        // Update planes
        vec3Set(planes[0].normal.array, m3 - m0, m7 - m4, m11 - m8);
        planes[0].distance = -(m15 - m12);
        planes[0].normalize();

        vec3Set(planes[1].normal.array, m3 + m0, m7 + m4, m11 + m8);
        planes[1].distance = -(m15 + m12);
        planes[1].normalize();

        vec3Set(planes[2].normal.array, m3 + m1, m7 + m5, m11 + m9);
        planes[2].distance = -(m15 + m13);
        planes[2].normalize();

        vec3Set(planes[3].normal.array, m3 - m1, m7 - m5, m11 - m9);
        planes[3].distance = -(m15 - m13);
        planes[3].normalize();

        vec3Set(planes[4].normal.array, m3 - m2, m7 - m6, m11 - m10);
        planes[4].distance = -(m15 - m14);
        planes[4].normalize();

        vec3Set(planes[5].normal.array, m3 + m2, m7 + m6, m11 + m10);
        planes[5].distance = -(m15 + m14);
        planes[5].normalize();

        // Perspective projection
        var boundingBox = this.boundingBox;
        var vertices = this.vertices;
        if (m15 === 0)  {
            var aspect = m5 / m0;
            var zNear = -m14 / (m10 - 1);
            var zFar = -m14 / (m10 + 1);
            var farY = -zFar / m5;
            var nearY = -zNear / m5;
            // Update bounding box
            boundingBox.min.set(-farY * aspect, -farY, zFar);
            boundingBox.max.set(farY * aspect, farY, zNear);
            // update vertices
            //--- min z
            // min x
            vec3Set(vertices[0], -farY * aspect, -farY, zFar);
            vec3Set(vertices[1], -farY * aspect, farY, zFar);
            // max x
            vec3Set(vertices[2], farY * aspect, -farY, zFar);
            vec3Set(vertices[3], farY * aspect, farY, zFar);
            //-- max z
            vec3Set(vertices[4], -nearY * aspect, -nearY, zNear);
            vec3Set(vertices[5], -nearY * aspect, nearY, zNear);
            vec3Set(vertices[6], nearY * aspect, -nearY, zNear);
            vec3Set(vertices[7], nearY * aspect, nearY, zNear);
        }
        else { // Orthographic projection
            var left = (-1 - m12) / m0;
            var right = (1 - m12) / m0;
            var top = (1 - m13) / m5;
            var bottom = (-1 - m13) / m5;
            var near = (-1 - m14) / m10;
            var far = (1 - m14) / m10;


            boundingBox.min.set(Math.min(left, right), Math.min(bottom, top), Math.min(far, near));
            boundingBox.max.set(Math.max(right, left), Math.max(top, bottom), Math.max(near, far));

            var min = boundingBox.min.array;
            var max = boundingBox.max.array;
            //--- min z
            // min x
            vec3Set(vertices[0], min[0], min[1], min[2]);
            vec3Set(vertices[1], min[0], max[1], min[2]);
            // max x
            vec3Set(vertices[2], max[0], min[1], min[2]);
            vec3Set(vertices[3], max[0], max[1], min[2]);
            //-- max z
            vec3Set(vertices[4], min[0], min[1], max[2]);
            vec3Set(vertices[5], min[0], max[1], max[2]);
            vec3Set(vertices[6], max[0], min[1], max[2]);
            vec3Set(vertices[7], max[0], max[1], max[2]);
        }
    },

    /**
     * Apply a affine transform matrix and set to the given bounding box
     * @function
     * @param {clay.BoundingBox}
     * @param {clay.Matrix4}
     * @return {clay.BoundingBox}
     */
    getTransformedBoundingBox: (function() {

        var tmpVec3 = __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].create();

        return function(bbox, matrix) {
            var vertices = this.vertices;

            var m4 = matrix.array;
            var min = bbox.min;
            var max = bbox.max;
            var minArr = min.array;
            var maxArr = max.array;
            var v = vertices[0];
            vec3TranformMat4(tmpVec3, v, m4);
            vec3Copy(minArr, tmpVec3);
            vec3Copy(maxArr, tmpVec3);

            for (var i = 1; i < 8; i++) {
                v = vertices[i];
                vec3TranformMat4(tmpVec3, v, m4);

                minArr[0] = mathMin(tmpVec3[0], minArr[0]);
                minArr[1] = mathMin(tmpVec3[1], minArr[1]);
                minArr[2] = mathMin(tmpVec3[2], minArr[2]);

                maxArr[0] = mathMax(tmpVec3[0], maxArr[0]);
                maxArr[1] = mathMax(tmpVec3[1], maxArr[1]);
                maxArr[2] = mathMax(tmpVec3[2], maxArr[2]);
            }

            min._dirty = true;
            max._dirty = true;

            return bbox;
        };
    }) ()
};
/* harmony default export */ __webpack_exports__["a"] = (Frustum);


/***/ }),
/* 60 */
/***/ (function(module, exports) {

// Simple LRU cache use doubly linked list
// @module zrender/core/LRU

/**
 * Simple double linked list. Compared with array, it has O(1) remove operation.
 * @constructor
 */
var LinkedList = function () {
  /**
   * @type {module:zrender/core/LRU~Entry}
   */
  this.head = null;
  /**
   * @type {module:zrender/core/LRU~Entry}
   */

  this.tail = null;
  this._len = 0;
};

var linkedListProto = LinkedList.prototype;
/**
 * Insert a new value at the tail
 * @param  {} val
 * @return {module:zrender/core/LRU~Entry}
 */

linkedListProto.insert = function (val) {
  var entry = new Entry(val);
  this.insertEntry(entry);
  return entry;
};
/**
 * Insert an entry at the tail
 * @param  {module:zrender/core/LRU~Entry} entry
 */


linkedListProto.insertEntry = function (entry) {
  if (!this.head) {
    this.head = this.tail = entry;
  } else {
    this.tail.next = entry;
    entry.prev = this.tail;
    entry.next = null;
    this.tail = entry;
  }

  this._len++;
};
/**
 * Remove entry.
 * @param  {module:zrender/core/LRU~Entry} entry
 */


linkedListProto.remove = function (entry) {
  var prev = entry.prev;
  var next = entry.next;

  if (prev) {
    prev.next = next;
  } else {
    // Is head
    this.head = next;
  }

  if (next) {
    next.prev = prev;
  } else {
    // Is tail
    this.tail = prev;
  }

  entry.next = entry.prev = null;
  this._len--;
};
/**
 * @return {number}
 */


linkedListProto.len = function () {
  return this._len;
};
/**
 * Clear list
 */


linkedListProto.clear = function () {
  this.head = this.tail = null;
  this._len = 0;
};
/**
 * @constructor
 * @param {} val
 */


var Entry = function (val) {
  /**
   * @type {}
   */
  this.value = val;
  /**
   * @type {module:zrender/core/LRU~Entry}
   */

  this.next;
  /**
   * @type {module:zrender/core/LRU~Entry}
   */

  this.prev;
};
/**
 * LRU Cache
 * @constructor
 * @alias module:zrender/core/LRU
 */


var LRU = function (maxSize) {
  this._list = new LinkedList();
  this._map = {};
  this._maxSize = maxSize || 10;
  this._lastRemovedEntry = null;
};

var LRUProto = LRU.prototype;
/**
 * @param  {string} key
 * @param  {} value
 * @return {} Removed value
 */

LRUProto.put = function (key, value) {
  var list = this._list;
  var map = this._map;
  var removed = null;

  if (map[key] == null) {
    var len = list.len(); // Reuse last removed entry

    var entry = this._lastRemovedEntry;

    if (len >= this._maxSize && len > 0) {
      // Remove the least recently used
      var leastUsedEntry = list.head;
      list.remove(leastUsedEntry);
      delete map[leastUsedEntry.key];
      removed = leastUsedEntry.value;
      this._lastRemovedEntry = leastUsedEntry;
    }

    if (entry) {
      entry.value = value;
    } else {
      entry = new Entry(value);
    }

    entry.key = key;
    list.insertEntry(entry);
    map[key] = entry;
  }

  return removed;
};
/**
 * @param  {string} key
 * @return {}
 */


LRUProto.get = function (key) {
  var entry = this._map[key];
  var list = this._list;

  if (entry != null) {
    // Put the latest used entry in the tail
    if (entry !== list.tail) {
      list.remove(entry);
      list.insertEntry(entry);
    }

    return entry.value;
  }
};
/**
 * Clear the cache
 */


LRUProto.clear = function () {
  this._list.clear();

  this._map = {};
};

var _default = LRU;
module.exports = _default;

/***/ }),
/* 61 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__TextureCube__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_vendor__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__prePass_EnvironmentMap__ = __webpack_require__(62);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__plugin_Skydome__ = __webpack_require__(75);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Scene__ = __webpack_require__(36);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__dds__ = __webpack_require__(122);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__hdr__ = __webpack_require__(123);










/**
 * @alias clay.util.texture
 */
var textureUtil = {
    /**
     * @param  {string|object} path
     * @param  {object} [option]
     * @param  {Function} [onsuccess]
     * @param  {Function} [onerror]
     * @return {clay.Texture}
     */
    loadTexture: function (path, option, onsuccess, onerror) {
        var texture;
        if (typeof(option) === 'function') {
            onsuccess = option;
            onerror = onsuccess;
            option = {};
        }
        else {
            option = option || {};
        }
        if (typeof(path) === 'string') {
            if (path.match(/.hdr$/) || option.fileType === 'hdr') {
                texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
                    width: 0,
                    height: 0,
                    sRGB: false
                });
                textureUtil._fetchTexture(
                    path,
                    function (data) {
                        __WEBPACK_IMPORTED_MODULE_7__hdr__["a" /* default */].parseRGBE(data, texture, option.exposure);
                        texture.dirty();
                        onsuccess && onsuccess(texture);
                    },
                    onerror
                );
                return texture;
            }
            else if (path.match(/.dds$/) || option.fileType === 'dds') {
                texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
                    width: 0,
                    height: 0
                });
                textureUtil._fetchTexture(
                    path,
                    function (data) {
                        __WEBPACK_IMPORTED_MODULE_6__dds__["a" /* default */].parse(data, texture);
                        texture.dirty();
                        onsuccess && onsuccess(texture);
                    },
                    onerror
                );
            }
            else {
                texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]();
                texture.load(path);
                texture.success(onsuccess);
                texture.error(onerror);
            }
        }
        else if (typeof path === 'object' && typeof(path.px) !== 'undefined') {
            texture = new __WEBPACK_IMPORTED_MODULE_1__TextureCube__["a" /* default */]();
            texture.load(path);
            texture.success(onsuccess);
            texture.error(onerror);
        }
        return texture;
    },

    /**
     * Load a panorama texture and render it to a cube map
     * @param  {clay.Renderer} renderer
     * @param  {string} path
     * @param  {clay.TextureCube} cubeMap
     * @param  {object} [option]
     * @param  {boolean} [option.encodeRGBM]
     * @param  {number} [option.exposure]
     * @param  {Function} [onsuccess]
     * @param  {Function} [onerror]
     */
    loadPanorama: function (renderer, path, cubeMap, option, onsuccess, onerror) {
        var self = this;

        if (typeof(option) === 'function') {
            onsuccess = option;
            onerror = onsuccess;
            option = {};
        }
        else {
            option = option || {};
        }

        textureUtil.loadTexture(path, option, function (texture) {
            // PENDING
            texture.flipY = option.flipY || false;
            self.panoramaToCubeMap(renderer, texture, cubeMap, option);
            texture.dispose(renderer);
            onsuccess && onsuccess(cubeMap);
        }, onerror);
    },

    /**
     * Render a panorama texture to a cube map
     * @param  {clay.Renderer} renderer
     * @param  {clay.Texture2D} panoramaMap
     * @param  {clay.TextureCube} cubeMap
     * @param  {Object} option
     * @param  {boolean} [option.encodeRGBM]
     */
    panoramaToCubeMap: function (renderer, panoramaMap, cubeMap, option) {
        var environmentMapPass = new __WEBPACK_IMPORTED_MODULE_3__prePass_EnvironmentMap__["a" /* default */]();
        var skydome = new __WEBPACK_IMPORTED_MODULE_4__plugin_Skydome__["a" /* default */]({
            scene: new __WEBPACK_IMPORTED_MODULE_5__Scene__["a" /* default */]()
        });
        skydome.setEnvironmentMap(panoramaMap);

        option = option || {};
        if (option.encodeRGBM) {
            skydome.material.define('fragment', 'RGBM_ENCODE');
        }

        // Share sRGB
        cubeMap.sRGB = panoramaMap.sRGB;

        environmentMapPass.texture = cubeMap;
        environmentMapPass.render(renderer, skydome.scene);
        environmentMapPass.texture = null;
        environmentMapPass.dispose(renderer);
        return cubeMap;
    },

    /**
     * Convert height map to normal map
     * @param {HTMLImageElement|HTMLCanvasElement} image
     * @param {boolean} [checkBump=false]
     * @return {HTMLCanvasElement}
     */
    heightToNormal: function (image, checkBump) {
        var canvas = document.createElement('canvas');
        var width = canvas.width = image.width;
        var height = canvas.height = image.height;
        var ctx = canvas.getContext('2d');
        ctx.drawImage(image, 0, 0, width, height);
        checkBump = checkBump || false;
        var srcData = ctx.getImageData(0, 0, width, height);
        var dstData = ctx.createImageData(width, height);
        for (var i = 0; i < srcData.data.length; i += 4) {
            if (checkBump) {
                var r = srcData.data[i];
                var g = srcData.data[i + 1];
                var b = srcData.data[i + 2];
                var diff = Math.abs(r - g) + Math.abs(g - b);
                if (diff > 20) {
                    console.warn('Given image is not a height map');
                    return image;
                }
            }
            // Modified from http://mrdoob.com/lab/javascript/height2normal/
            var x1, y1, x2, y2;
            if (i % (width * 4) === 0) {
                // left edge
                x1 = srcData.data[i];
                x2 = srcData.data[i + 4];
            }
            else if (i % (width * 4) === (width - 1) * 4) {
                // right edge
                x1 = srcData.data[i - 4];
                x2 = srcData.data[i];
            }
            else {
                x1 = srcData.data[i - 4];
                x2 = srcData.data[i + 4];
            }

            if (i < width * 4) {
                // top edge
                y1 = srcData.data[i];
                y2 = srcData.data[i + width * 4];
            }
            else if (i > width * (height - 1) * 4) {
                // bottom edge
                y1 = srcData.data[i - width * 4];
                y2 = srcData.data[i];
            }
            else {
                y1 = srcData.data[i - width * 4];
                y2 = srcData.data[i + width * 4];
            }

            dstData.data[i] = (x1 - x2) + 127;
            dstData.data[i + 1] = (y1 - y2) + 127;
            dstData.data[i + 2] = 255;
            dstData.data[i + 3] = 255;
        }
        ctx.putImageData(dstData, 0, 0);
        return canvas;
    },

    /**
     * Convert height map to normal map
     * @param {HTMLImageElement|HTMLCanvasElement} image
     * @param {boolean} [checkBump=false]
     * @param {number} [threshold=20]
     * @return {HTMLCanvasElement}
     */
    isHeightImage: function (img, downScaleSize, threshold) {
        if (!img || !img.width || !img.height) {
            return false;
        }

        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
        var size = downScaleSize || 32;
        threshold = threshold || 20;
        canvas.width = canvas.height = size;
        ctx.drawImage(img, 0, 0, size, size);
        var srcData = ctx.getImageData(0, 0, size, size);
        for (var i = 0; i < srcData.data.length; i += 4) {
            var r = srcData.data[i];
            var g = srcData.data[i + 1];
            var b = srcData.data[i + 2];
            var diff = Math.abs(r - g) + Math.abs(g - b);
            if (diff > threshold) {
                return false;
            }
        }
        return true;
    },

    _fetchTexture: function (path, onsuccess, onerror) {
        __WEBPACK_IMPORTED_MODULE_2__core_vendor__["a" /* default */].request.get({
            url: path,
            responseType: 'arraybuffer',
            onload: onsuccess,
            onerror: onerror
        });
    },

    /**
     * Create a chessboard texture
     * @param  {number} [size]
     * @param  {number} [unitSize]
     * @param  {string} [color1]
     * @param  {string} [color2]
     * @return {clay.Texture2D}
     */
    createChessboard: function (size, unitSize, color1, color2) {
        size = size || 512;
        unitSize = unitSize || 64;
        color1 = color1 || 'black';
        color2 = color2 || 'white';

        var repeat = Math.ceil(size / unitSize);

        var canvas = document.createElement('canvas');
        canvas.width = size;
        canvas.height = size;
        var ctx = canvas.getContext('2d');
        ctx.fillStyle = color2;
        ctx.fillRect(0, 0, size, size);

        ctx.fillStyle = color1;
        for (var i = 0; i < repeat; i++) {
            for (var j = 0; j < repeat; j++) {
                var isFill = j % 2 ? (i % 2) : (i % 2 - 1);
                if (isFill) {
                    ctx.fillRect(i * unitSize, j * unitSize, unitSize, unitSize);
                }
            }
        }

        var texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
            image: canvas,
            anisotropic: 8
        });

        return texture;
    },

    /**
     * Create a blank pure color 1x1 texture
     * @param  {string} color
     * @return {clay.Texture2D}
     */
    createBlank: function (color) {
        var canvas = document.createElement('canvas');
        canvas.width = 1;
        canvas.height = 1;
        var ctx = canvas.getContext('2d');
        ctx.fillStyle = color;
        ctx.fillRect(0, 0, 1, 1);

        var texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
            image: canvas
        });

        return texture;
    }
};

/* harmony default export */ __webpack_exports__["a"] = (textureUtil);


/***/ }),
/* 62 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__ = __webpack_require__(41);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__FrameBuffer__ = __webpack_require__(10);





var targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz'];

/**
 * Pass rendering scene to a environment cube map
 *
 * @constructor clay.prePass.EnvironmentMap
 * @extends clay.core.Base
 * @example
 *     // Example of car reflection
 *     var envMap = new clay.TextureCube({
 *         width: 256,
 *         height: 256
 *     });
 *     var envPass = new clay.prePass.EnvironmentMap({
 *         position: car.position,
 *         texture: envMap
 *     });
 *     var carBody = car.getChildByName('body');
 *     carBody.material.enableTexture('environmentMap');
 *     carBody.material.set('environmentMap', envMap);
 *     ...
 *     animation.on('frame', function(frameTime) {
 *         envPass.render(renderer, scene);
 *         renderer.render(scene, camera);
 *     });
 */
var EnvironmentMapPass = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function() {
    var ret = /** @lends clay.prePass.EnvironmentMap# */ {
        /**
         * Camera position
         * @type {clay.Vector3}
         * @memberOf clay.prePass.EnvironmentMap#
         */
        position: new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */](),
        /**
         * Camera far plane
         * @type {number}
         * @memberOf clay.prePass.EnvironmentMap#
         */
        far: 1000,
        /**
         * Camera near plane
         * @type {number}
         * @memberOf clay.prePass.EnvironmentMap#
         */
        near: 0.1,
        /**
         * Environment cube map
         * @type {clay.TextureCube}
         * @memberOf clay.prePass.EnvironmentMap#
         */
        texture: null,

        /**
         * Used if you wan't have shadow in environment map
         * @type {clay.prePass.ShadowMap}
         */
        shadowMapPass: null,
    };
    var cameras = ret._cameras = {
        px: new __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__["a" /* default */]({ fov: 90 }),
        nx: new __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__["a" /* default */]({ fov: 90 }),
        py: new __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__["a" /* default */]({ fov: 90 }),
        ny: new __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__["a" /* default */]({ fov: 90 }),
        pz: new __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__["a" /* default */]({ fov: 90 }),
        nz: new __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__["a" /* default */]({ fov: 90 })
    };
    cameras.px.lookAt(__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].POSITIVE_X, __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Y);
    cameras.nx.lookAt(__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_X, __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Y);
    cameras.py.lookAt(__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].POSITIVE_Y, __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].POSITIVE_Z);
    cameras.ny.lookAt(__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Y, __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Z);
    cameras.pz.lookAt(__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].POSITIVE_Z, __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Y);
    cameras.nz.lookAt(__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Z, __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Y);

    // FIXME In windows, use one framebuffer only renders one side of cubemap
    ret._frameBuffer = new __WEBPACK_IMPORTED_MODULE_3__FrameBuffer__["a" /* default */]();

    return ret;
},  /** @lends clay.prePass.EnvironmentMap# */ {
    /**
     * @param  {string} target
     * @return  {clay.Camera}
     */
    getCamera: function (target) {
        return this._cameras[target];
    },
    /**
     * @param  {clay.Renderer} renderer
     * @param  {clay.Scene} scene
     * @param  {boolean} [notUpdateScene=false]
     */
    render: function(renderer, scene, notUpdateScene) {
        var _gl = renderer.gl;
        if (!notUpdateScene) {
            scene.update();
        }
        // Tweak fov
        // http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
        var n = this.texture.width;
        var fov = 2 * Math.atan(n / (n - 0.5)) / Math.PI * 180;

        for (var i = 0; i < 6; i++) {
            var target = targets[i];
            var camera = this._cameras[target];
            __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].copy(camera.position, this.position);

            camera.far = this.far;
            camera.near = this.near;
            camera.fov = fov;

            if (this.shadowMapPass) {
                camera.update();

                // update boundingBoxLastFrame
                var bbox = scene.getBoundingBox();
                bbox.applyTransform(camera.viewMatrix);
                scene.viewBoundingBoxLastFrame.copy(bbox);

                this.shadowMapPass.render(renderer, scene, camera, true);
            }
            this._frameBuffer.attach(
                this.texture, _gl.COLOR_ATTACHMENT0,
                _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i
            );
            this._frameBuffer.bind(renderer);
            renderer.render(scene, camera, true);
            this._frameBuffer.unbind(renderer);
        }
    },
    /**
     * @param {clay.Renderer} renderer
     */
    dispose: function (renderer) {
        this._frameBuffer.dispose(renderer);
    }
});

/* harmony default export */ __webpack_exports__["a"] = (EnvironmentMapPass);


/***/ }),
/* 63 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__geometry_Sprites__ = __webpack_require__(165);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__shader_labels_glsl_js__ = __webpack_require__(166);




__WEBPACK_IMPORTED_MODULE_0__graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_2__shader_labels_glsl_js__["a" /* default */]);

/* harmony default export */ __webpack_exports__["a"] = (__WEBPACK_IMPORTED_MODULE_0__graphicGL__["a" /* default */].Mesh.extend(function () {
    var geometry = new __WEBPACK_IMPORTED_MODULE_1__geometry_Sprites__["a" /* default */]({
        dynamic: true
    });
    var material = new __WEBPACK_IMPORTED_MODULE_0__graphicGL__["a" /* default */].Material({
        shader: __WEBPACK_IMPORTED_MODULE_0__graphicGL__["a" /* default */].createShader('ecgl.labels'),
        transparent: true,
        depthMask: false
    });

    return {
        geometry: geometry,
        material: material,
        culling: false,
        castShadow: false,
        ignorePicking: true
    };
}));

/***/ }),
/* 64 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_earcut__ = __webpack_require__(204);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_dep_glmatrix__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__util_geometry_trianglesSortMixin__ = __webpack_require__(65);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__LabelsBuilder__ = __webpack_require__(66);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__util_shader_lines3D_glsl_js__ = __webpack_require__(46);










var vec3 = __WEBPACK_IMPORTED_MODULE_5_claygl_src_dep_glmatrix__["a" /* default */].vec3;

__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_8__util_shader_lines3D_glsl_js__["a" /* default */]);

function Geo3DBuilder(api) {

    this.rootNode = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();

    // Cache triangulation result
    this._triangulationResults = {};

    this._shadersMap = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].COMMON_SHADERS.reduce(function (obj, shaderName) {
        obj[shaderName] = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.' + shaderName);
        return obj;
    }, {});

    this._linesShader = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.meshLines3D');

    var groundMaterials = {};
    __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].COMMON_SHADERS.forEach(function (shading) {
        groundMaterials[shading] = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
            shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.' + shading)
        });
    });
    this._groundMaterials = groundMaterials;

    this._groundMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
        geometry: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].PlaneGeometry({ dynamic: true }),
        castShadow: false,
        renderNormal: true,
        $ignorePicking: true
    });
    this._groundMesh.rotation.rotateX(-Math.PI / 2);

    this._labelsBuilder = new __WEBPACK_IMPORTED_MODULE_7__LabelsBuilder__["a" /* default */](512, 512, api);

    // Give a large render order.
    this._labelsBuilder.getMesh().renderOrder = 100;
    this._labelsBuilder.getMesh().material.depthTest = false;

    this.rootNode.add(this._labelsBuilder.getMesh());

    this._initMeshes();

    this._api = api;
}

Geo3DBuilder.prototype = {

    constructor: Geo3DBuilder,

    // Which dimension to extrude. Y or Z
    extrudeY: true,

    update: function (componentModel, ecModel, api, start, end) {

        var data = componentModel.getData();

        if (start == null) {
            start = 0;
        }
        if (end == null) {
            end = data.count();
        }

        this._startIndex = start;
        this._endIndex = end - 1;

        this._triangulation(componentModel, start, end);

        var shader = this._getShader(componentModel.get('shading'));

        this._prepareMesh(componentModel, shader, api, start, end);

        this.rootNode.updateWorldTransform();

        this._updateRegionMesh(componentModel, api, start, end);

        var coordSys = componentModel.coordinateSystem;
        // PENDING
        if (coordSys.type === 'geo3D') {
            this._updateGroundPlane(componentModel, coordSys, api);
        }

        var self = this;
        this._labelsBuilder.updateData(data, start, end);
        this._labelsBuilder.getLabelPosition = function (dataIndex, positionDesc, distance) {
            var name = data.getName(dataIndex);

            var center;
            var height = distance;
            if (coordSys.type === 'geo3D') {
                var region = coordSys.getRegion(name);
                if (!region) {
                    return [NaN, NaN, NaN];
                }
                center = region.center;
                var pos = coordSys.dataToPoint([center[0], center[1], height]);
                return pos;
            }
            else {
                var tmp = self._triangulationResults[dataIndex - self._startIndex];
                var center = self.extrudeY ? [
                    (tmp.max[0] + tmp.min[0]) / 2,
                    tmp.max[1] + height,
                    (tmp.max[2] + tmp.min[2]) / 2
                ] : [
                    (tmp.max[0] + tmp.min[0]) / 2,
                    (tmp.max[1] + tmp.min[1]) / 2,
                    tmp.max[2] + height
                ];
            }
        };

        this._data = data;

        this._labelsBuilder.updateLabels();

        this._updateDebugWireframe(componentModel);

        // Reset some state.
        this._lastHoverDataIndex = 0;
    },

    _initMeshes: function () {
        var self = this;
        function createPolygonMesh() {
            var mesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
                name: 'Polygon',
                material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
                    shader: self._shadersMap.lambert
                }),
                geometry: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry({
                    sortTriangles: true,
                    dynamic: true
                }),
                // TODO Disable culling
                culling: false,
                ignorePicking: true,
                // Render normal in normal pass
                renderNormal: true
            });
            __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.extend(mesh.geometry, __WEBPACK_IMPORTED_MODULE_6__util_geometry_trianglesSortMixin__["a" /* default */]);
            return mesh;
        }

        var polygonMesh = createPolygonMesh();

        var linesMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
            material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
                shader: this._linesShader
            }),
            castShadow: false,
            ignorePicking: true,
            $ignorePicking: true,
            geometry: new __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__["a" /* default */]({
                useNativeLine: false
            })
        });

        this.rootNode.add(polygonMesh);
        this.rootNode.add(linesMesh);

        polygonMesh.material.define('both', 'VERTEX_COLOR');
        polygonMesh.material.define('fragment', 'DOUBLE_SIDED');

        this._polygonMesh = polygonMesh;
        this._linesMesh = linesMesh;

        this.rootNode.add(this._groundMesh);
    },

    _getShader: function (shading) {
        var shader = this._shadersMap[shading];
        if (!shader) {
            if (true) {
                console.warn('Unkown shading ' + shading);
            }
            // Default use lambert shader.
            shader = this._shadersMap.lambert;
        }
        shader.__shading = shading;
        return shader;
    },

    _prepareMesh: function (componentModel, shader, api, start, end) {
        var polygonVertexCount = 0;
        var polygonTriangleCount = 0;
        var linesVertexCount = 0;
        var linesTriangleCount = 0;
        // TODO Lines
        for (var idx = start; idx < end; idx++) {
            var polyInfo = this._getRegionPolygonInfo(idx);
            var lineInfo = this._getRegionLinesInfo(idx, componentModel, this._linesMesh.geometry);
            polygonVertexCount += polyInfo.vertexCount;
            polygonTriangleCount += polyInfo.triangleCount;
            linesVertexCount += lineInfo.vertexCount;
            linesTriangleCount += lineInfo.triangleCount;
        }

        var polygonMesh = this._polygonMesh;
        var polygonGeo = polygonMesh.geometry;
        ['position', 'normal', 'texcoord0', 'color'].forEach(function (attrName) {
            polygonGeo.attributes[attrName].init(polygonVertexCount);
        });
        polygonGeo.indices = polygonVertexCount > 0xffff ? new Uint32Array(polygonTriangleCount * 3) : new Uint16Array(polygonTriangleCount * 3);

        if (polygonMesh.material.shader !== shader) {
            polygonMesh.material.attachShader(shader, true);
        }
        __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].setMaterialFromModel(shader.__shading, polygonMesh.material, componentModel, api);

        if (linesVertexCount > 0) {
            this._linesMesh.geometry.resetOffset();
            this._linesMesh.geometry.setVertexCount(linesVertexCount);
            this._linesMesh.geometry.setTriangleCount(linesTriangleCount);
        }

        // Indexing data index from vertex index.
        this._dataIndexOfVertex = new Uint32Array(polygonVertexCount);
        // Indexing vertex index range from data index
        this._vertexRangeOfDataIndex = new Uint32Array((end - start) * 2);
    },

    _updateRegionMesh: function (componentModel, api, start, end) {

        var data = componentModel.getData();

        var vertexOffset = 0;
        var triangleOffset = 0;

        // Materials configurations.
        var hasTranparentRegion = false;

        var polygonMesh = this._polygonMesh;
        var linesMesh = this._linesMesh;

        for (var dataIndex = start; dataIndex < end; dataIndex++) {
            // Get bunch of visual properties.
            var regionModel = componentModel.getRegionModel(dataIndex);
            var itemStyleModel = regionModel.getModel('itemStyle');
            var color = itemStyleModel.get('color');
            var opacity = __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(itemStyleModel.get('opacity'), 1.0);

            // Use visual color if it is encoded by visualMap component
            var visualColor = data.getItemVisual(dataIndex, 'color', true);
            if (visualColor != null && data.hasValue(dataIndex)) {
                color = visualColor;
            }
            // Set color, opacity to visual for label usage.
            data.setItemVisual(dataIndex, 'color', color);
            data.setItemVisual(dataIndex, 'opacity', opacity);

            color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color);
            var borderColor = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(itemStyleModel.get('borderColor'));

            color[3] *= opacity;
            borderColor[3] *= opacity;

            var isTransparent = color[3] < 0.99;

            polygonMesh.material.set('color', [1,1,1,1]);
            hasTranparentRegion = hasTranparentRegion || isTransparent;

            var regionHeight = __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(regionModel.get('height', true), componentModel.get('regionHeight'));

            var newOffsets = this._updatePolygonGeometry(
                componentModel, polygonMesh.geometry, dataIndex, regionHeight,
                vertexOffset, triangleOffset, color
            );

            for (var i = vertexOffset; i < newOffsets.vertexOffset; i++) {
                this._dataIndexOfVertex[i] = dataIndex;
            }
            this._vertexRangeOfDataIndex[(dataIndex - start) * 2] = vertexOffset;
            this._vertexRangeOfDataIndex[(dataIndex - start) * 2 + 1] = newOffsets.vertexOffset;

            vertexOffset = newOffsets.vertexOffset;
            triangleOffset = newOffsets.triangleOffset;

            // Update lines.
            var lineWidth = itemStyleModel.get('borderWidth');
            var hasLine = lineWidth > 0;
            if (hasLine) {
                lineWidth *= api.getDevicePixelRatio();
                this._updateLinesGeometry(
                    linesMesh.geometry, componentModel, dataIndex, regionHeight, lineWidth,
                    componentModel.coordinateSystem.transform
                );
            }
            linesMesh.invisible = !hasLine;
            linesMesh.material.set({
                color: borderColor
            });
        }

        var polygonMesh = this._polygonMesh;
        polygonMesh.material.transparent = hasTranparentRegion;
        polygonMesh.material.depthMask = !hasTranparentRegion;
        polygonMesh.geometry.updateBoundingBox();

        polygonMesh.frontFace = this.extrudeY ? __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.CCW : __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.CW;

        // Update tangents
        if (polygonMesh.material.get('normalMap')) {
            polygonMesh.geometry.generateTangents();
        }

        polygonMesh.seriesIndex = componentModel.seriesIndex;

        polygonMesh.on('mousemove', this._onmousemove, this);
        polygonMesh.on('mouseout', this._onmouseout, this);
    },

    _updateDebugWireframe: function (componentModel) {
        var debugWireframeModel = componentModel.getModel('debug.wireframe');

        // TODO Unshow
        if (debugWireframeModel.get('show')) {
            var color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(
                debugWireframeModel.get('lineStyle.color') || 'rgba(0,0,0,0.5)'
            );
            var width = __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(
                debugWireframeModel.get('lineStyle.width'), 1
            );

            // TODO  Will cause highlight wrong
            var mesh = this._polygonMesh;
            mesh.geometry.generateBarycentric();
            mesh.material.define('both', 'WIREFRAME_TRIANGLE');
            mesh.material.set('wireframeLineColor', color);
            mesh.material.set('wireframeLineWidth', width);
        }
    },

    _onmousemove: function (e) {
        var dataIndex = this._dataIndexOfVertex[e.triangle[0]];
        if (dataIndex == null) {
            dataIndex = -1;
        }
        if (dataIndex !== this._lastHoverDataIndex) {
            this.downplay(this._lastHoverDataIndex);
            this.highlight(dataIndex);
            this._labelsBuilder.updateLabels([dataIndex]);
        }
        this._lastHoverDataIndex = dataIndex;
        this._polygonMesh.dataIndex = dataIndex;
    },

    _onmouseout: function (e) {
        if (e.target) {
            this.downplay(this._lastHoverDataIndex);
            this._lastHoverDataIndex = -1;
            this._polygonMesh.dataIndex = -1;
        }

        this._labelsBuilder.updateLabels([]);
    },

    _updateGroundPlane: function (componentModel, geo3D, api) {
        var groundModel = componentModel.getModel('groundPlane', componentModel);
        this._groundMesh.invisible = !groundModel.get('show', true);
        if (this._groundMesh.invisible) {
            return;
        }

        var shading = componentModel.get('shading');
        var material = this._groundMaterials[shading];
        if (!material) {
            if (true) {
                console.warn('Unkown shading ' + shading);
            }
            material = this._groundMaterials.lambert;
        }

        __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].setMaterialFromModel(shading, material, groundModel, api);
        if (material.get('normalMap')) {
            this._groundMesh.geometry.generateTangents();
        }

        this._groundMesh.material = material;
        this._groundMesh.material.set('color', __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(groundModel.get('color')));

        this._groundMesh.scale.set(geo3D.size[0], geo3D.size[2], 1);
    },

    _triangulation: function (componentModel, start, end) {
        this._triangulationResults = [];

        var minAll = [Infinity, Infinity, Infinity];
        var maxAll = [-Infinity, -Infinity, -Infinity];

        var coordSys = componentModel.coordinateSystem;

        for (var idx = start; idx < end; idx++) {
            var polygons = [];
            var polygonCoords = componentModel.getRegionPolygonCoords(idx);
            for (var i = 0; i < polygonCoords.length; i++) {
                var exterior = polygonCoords[i].exterior;
                var interiors = polygonCoords[i].interiors;
                var points = [];
                var holes = [];
                if (exterior.length < 3) {
                    continue;
                }
                var offset = 0;
                for (var j = 0; j < exterior.length; j++) {
                    var p = exterior[j];
                    points[offset++] = p[0];
                    points[offset++] = p[1];
                }

                for (var j = 0; j < interiors.length; j++) {
                    if (interiors[j].length < 3) {
                        continue;
                    }
                    var startIdx = points.length / 2;
                    for (var k = 0; k < interiors[j].length; k++) {
                        var p = interiors[j][k];
                        points.push(p[0]);
                        points.push(p[1]);
                    }

                    holes.push(startIdx);
                }
                var triangles = Object(__WEBPACK_IMPORTED_MODULE_2__util_earcut__["a" /* default */])(points, holes);

                var points3 = new Float64Array(points.length / 2 * 3);
                var pos = [];
                var min = [Infinity, Infinity, Infinity];
                var max = [-Infinity, -Infinity, -Infinity];
                var off3 = 0;
                for (var j = 0; j < points.length;) {
                    vec3.set(pos, points[j++], 0, points[j++]);
                    if (coordSys && coordSys.transform) {
                        vec3.transformMat4(pos, pos, coordSys.transform);
                    }
                    vec3.min(min, min, pos);
                    vec3.max(max, max, pos);
                    points3[off3++] = pos[0];
                    points3[off3++] = pos[1];
                    points3[off3++] = pos[2];
                }
                vec3.min(minAll, minAll, min);
                vec3.max(maxAll, maxAll, max);
                polygons.push({
                    points: points3,
                    indices: triangles,
                    min: min,
                    max: max
                });
            }
            this._triangulationResults.push(polygons);
        }

        this._geoBoundingBox = [minAll, maxAll];
    },

    /**
     * Get region vertex and triangle count
     */
    _getRegionPolygonInfo: function (idx) {

        var polygons = this._triangulationResults[idx - this._startIndex];

        var sideVertexCount = 0;
        var sideTriangleCount = 0;

        for (var i = 0; i < polygons.length; i++) {
            sideVertexCount += polygons[i].points.length / 3;
            sideTriangleCount += polygons[i].indices.length / 3;
        }

        var vertexCount = sideVertexCount * 2 + sideVertexCount * 4;
        var triangleCount = sideTriangleCount * 2 + sideVertexCount * 2;

        return {
            vertexCount: vertexCount,
            triangleCount: triangleCount
        };
    },

    _updatePolygonGeometry: function (
        componentModel, geometry, dataIndex, regionHeight,
        vertexOffset, triangleOffset, color
    ) {
        // FIXME
        var projectUVOnGround = componentModel.get('projectUVOnGround');

        var positionAttr = geometry.attributes.position;
        var normalAttr = geometry.attributes.normal;
        var texcoordAttr = geometry.attributes.texcoord0;
        var colorAttr = geometry.attributes.color;
        var polygons = this._triangulationResults[dataIndex - this._startIndex];

        var hasColor = colorAttr.value && color;

        var indices = geometry.indices;

        var extrudeCoordIndex = this.extrudeY ? 1 : 2;
        var sideCoordIndex = this.extrudeY ? 2 : 1;

        var scale = [
            this.rootNode.worldTransform.x.len(),
            this.rootNode.worldTransform.y.len(),
            this.rootNode.worldTransform.z.len()
        ];

        var min = vec3.mul([], this._geoBoundingBox[0], scale);
        var max = vec3.mul([], this._geoBoundingBox[1], scale);
        var maxDimSize = Math.max(max[0] - min[0], max[2] - min[2]);

        function addVertices(polygon, y, insideOffset) {
            var points = polygon.points;

            var pointsLen = points.length;
            var currentPosition = [];
            var uv = [];

            for (var k = 0; k < pointsLen; k += 3) {
                currentPosition[0] = points[k];
                currentPosition[extrudeCoordIndex] = y;
                currentPosition[sideCoordIndex] = points[k + 2];

                uv[0] = (points[k] * scale[0] - min[0]) / maxDimSize;
                uv[1] = (points[k + 2] * scale[sideCoordIndex] - min[2]) / maxDimSize;

                positionAttr.set(vertexOffset, currentPosition);
                if (hasColor) {
                    colorAttr.set(vertexOffset, color);
                }
                texcoordAttr.set(vertexOffset++, uv);
            }
        }

        function buildTopBottom(polygon, y, insideOffset) {

            var startVertexOffset = vertexOffset;

            addVertices(polygon, y, insideOffset);

            var len = polygon.indices.length;
            for (var k = 0; k < len; k++) {
                indices[triangleOffset * 3 + k] = polygon.indices[k] + startVertexOffset;
            }
            triangleOffset += polygon.indices.length / 3;
        }

        var normalTop = this.extrudeY ? [0, 1, 0] : [0, 0, 1];
        var normalBottom = vec3.negate([], normalTop);
        for (var p = 0; p < polygons.length; p++) {
            var startVertexOffset = vertexOffset;
            var polygon = polygons[p];
            // BOTTOM
            buildTopBottom(polygon, 0, 0);
            // TOP
            buildTopBottom(polygon, regionHeight, 0);

            var ringVertexCount = polygon.points.length / 3;
            for (var v = 0; v < ringVertexCount; v++) {
                normalAttr.set(startVertexOffset + v, normalBottom);
                normalAttr.set(startVertexOffset + v + ringVertexCount, normalTop);
            }

            var quadToTriangle = [0, 3, 1, 1, 3, 2];

            var quadPos = [[], [], [], []];
            var a = [];
            var b = [];
            var normal = [];
            var uv = [];
            var len = 0;
            for (var v = 0; v < ringVertexCount; v++) {
                var next = (v + 1) % ringVertexCount;

                var dx = (polygon.points[next * 3] - polygon.points[v * 3]) * scale[0];
                var dy = (polygon.points[next * 3 + 2] - polygon.points[v * 3 + 2]) * scale[sideCoordIndex];
                var sideLen = Math.sqrt(dx * dx + dy * dy);

                // 0----1
                // 3----2
                for (var k = 0; k < 4; k++) {
                    var isCurrent = (k === 0 || k === 3);
                    var idx3 = (isCurrent ? v : next) * 3;
                    quadPos[k][0] = polygon.points[idx3];
                    quadPos[k][extrudeCoordIndex] = k > 1 ? regionHeight : 0;
                    quadPos[k][sideCoordIndex] = polygon.points[idx3 + 2];

                    positionAttr.set(vertexOffset + k, quadPos[k]);

                    if (projectUVOnGround) {
                        uv[0] = (polygon.points[idx3] * scale[0] - min[0]) / maxDimSize;
                        uv[1] = (polygon.points[idx3 + 2] * scale[sideCoordIndex] - min[sideCoordIndex]) / maxDimSize;
                    }
                    else {
                        uv[0] = (isCurrent ? len : (len + sideLen)) / maxDimSize;
                        uv[1] = (quadPos[k][extrudeCoordIndex] * scale[extrudeCoordIndex] - min[extrudeCoordIndex])  / maxDimSize;
                    }
                    texcoordAttr.set(vertexOffset + k, uv);
                }
                vec3.sub(a, quadPos[1], quadPos[0]);
                vec3.sub(b, quadPos[3], quadPos[0]);
                vec3.cross(normal, a, b);
                vec3.normalize(normal, normal);

                for (var k = 0; k < 4; k++) {
                    normalAttr.set(vertexOffset + k, normal);
                    if (hasColor) {
                        colorAttr.set(vertexOffset + k, color);
                    }
                }

                for (var k = 0; k < 6; k++) {
                    indices[triangleOffset * 3 + k] = quadToTriangle[k] + vertexOffset;
                }

                vertexOffset += 4;
                triangleOffset += 2;

                len += sideLen;
            }
        }

        geometry.dirty();

        return {
            vertexOffset: vertexOffset,
            triangleOffset: triangleOffset
        };
    },

    _getRegionLinesInfo: function (idx, componentModel, geometry) {
        var vertexCount = 0;
        var triangleCount = 0;

        var regionModel = componentModel.getRegionModel(idx);
        var itemStyleModel = regionModel.getModel('itemStyle');

        var lineWidth = itemStyleModel.get('borderWidth');
        if (lineWidth > 0) {
            var polygonCoords = componentModel.getRegionPolygonCoords(idx);
            polygonCoords.forEach(function (coords) {
                var exterior = coords.exterior;
                var interiors = coords.interiors;
                vertexCount += geometry.getPolylineVertexCount(exterior);
                triangleCount += geometry.getPolylineTriangleCount(exterior);
                for (var i = 0; i < interiors.length; i++) {
                    vertexCount += geometry.getPolylineVertexCount(interiors[i]);
                    triangleCount += geometry.getPolylineTriangleCount(interiors[i]);
                }
            }, this);
        }

        return {
            vertexCount: vertexCount,
            triangleCount: triangleCount
        };

    },

    _updateLinesGeometry: function (geometry, componentModel, dataIndex, regionHeight, lineWidth, transform) {
        function convertToPoints3(polygon) {
            var points = new Float64Array(polygon.length * 3);
            var offset = 0;
            var pos = [];
            for (var i = 0; i < polygon.length; i++) {
                pos[0] = polygon[i][0];
                // Add a offset to avoid z-fighting
                pos[1] = regionHeight + 0.1;
                pos[2] = polygon[i][1];

                if (transform) {
                    vec3.transformMat4(pos, pos, transform);
                }

                points[offset++] = pos[0];
                points[offset++] = pos[1];
                points[offset++] = pos[2];
            }
            return points;
        }

        var whiteColor = [1, 1, 1, 1];
        var coords = componentModel.getRegionPolygonCoords(dataIndex);
        coords.forEach(function (geo) {
            var exterior = geo.exterior;
            var interiors = geo.interiors;

            geometry.addPolyline(convertToPoints3(exterior), whiteColor, lineWidth);

            for (var i = 0; i < interiors.length; i++) {
                geometry.addPolyline(convertToPoints3(interiors[i]), whiteColor, lineWidth);
            }
        });
    },

    highlight: function (dataIndex) {
        var data = this._data;
        if (!data) {
            return;
        }

        var itemModel = data.getItemModel(dataIndex);
        var emphasisItemStyleModel = itemModel.getModel('emphasis.itemStyle');
        var emphasisColor = emphasisItemStyleModel.get('color');
        var emphasisOpacity = __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(
            emphasisItemStyleModel.get('opacity'),
            data.getItemVisual(dataIndex, 'opacity'),
            1
        );
        if (emphasisColor == null) {
            var color = data.getItemVisual(dataIndex, 'color');
            emphasisColor = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.color.lift(color, -0.4);
        }
        if (emphasisOpacity == null) {
            emphasisOpacity = data.getItemVisual(dataIndex, 'opacity');
        }
        var colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(emphasisColor);
        colorArr[3] *= emphasisOpacity;

        this._setColorOfDataIndex(data, dataIndex, colorArr);
    },

    downplay: function (dataIndex) {

        var data = this._data;
        if (!data) {
            return;
        }

        var color = data.getItemVisual(dataIndex, 'color');
        var opacity = __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(data.getItemVisual(dataIndex, 'opacity'), 1);

        var colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color);
        colorArr[3] *= opacity;

        this._setColorOfDataIndex(data, dataIndex, colorArr);
    },

    _setColorOfDataIndex: function (data, dataIndex, colorArr) {
        if (dataIndex < this._startIndex && dataIndex > this._endIndex) {
            return;
        }
        dataIndex -= this._startIndex;
        for (var i = this._vertexRangeOfDataIndex[dataIndex * 2]; i < this._vertexRangeOfDataIndex[dataIndex * 2 + 1]; i++) {
            this._polygonMesh.geometry.attributes.color.set(i, colorArr);
        }
        this._polygonMesh.geometry.dirty();
        this._api.getZr().refresh();
    }
};

/* harmony default export */ __webpack_exports__["a"] = (Geo3DBuilder);

/***/ }),
/* 65 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__ProgressiveQuickSort__ = __webpack_require__(97);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__ = __webpack_require__(6);


var vec3 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__["a" /* default */].vec3;

var p0 = vec3.create();
var p1 = vec3.create();
var p2 = vec3.create();
// var cp = vec3.create();

/* harmony default export */ __webpack_exports__["a"] = ({

    needsSortTriangles: function () {
        return this.indices && this.sortTriangles;
    },

    needsSortTrianglesProgressively: function () {
        return this.needsSortTriangles() && this.triangleCount >= 2e4;
    },

    doSortTriangles: function (cameraPos, frame) {
        var indices = this.indices;
        // Do progressive quick sort.
        if (frame === 0) {
            var posAttr = this.attributes.position;
            var cameraPos = cameraPos.array;

            if (!this._triangleZList || this._triangleZList.length !== this.triangleCount) {
                this._triangleZList = new Float32Array(this.triangleCount);
                this._sortedTriangleIndices = new Uint32Array(this.triangleCount);

                this._indicesTmp = new indices.constructor(indices.length);
                this._triangleZListTmp = new Float32Array(this.triangleCount);
            }

            var cursor = 0;
            var firstZ;
            for (var i = 0; i < indices.length;) {
                posAttr.get(indices[i++], p0);
                posAttr.get(indices[i++], p1);
                posAttr.get(indices[i++], p2);

                // FIXME If use center ?
                // cp[0] = (p0[0] + p1[0] + p2[0]) / 3;
                // cp[1] = (p0[1] + p1[1] + p2[1]) / 3;
                // cp[2] = (p0[2] + p1[2] + p2[2]) / 3;
                // Camera position is in object space

                // Use max of three points, PENDING
                var z0 = vec3.sqrDist(p0, cameraPos);
                var z1 = vec3.sqrDist(p1, cameraPos);
                var z2 = vec3.sqrDist(p2, cameraPos);
                var zMax = Math.min(z0, z1);
                zMax = Math.min(zMax, z2);
                if (i === 3) {
                    firstZ = zMax;
                    zMax = 0;
                }
                else {
                    // Only store the difference to avoid the precision issue.
                    zMax = zMax - firstZ;
                }
                this._triangleZList[cursor++] = zMax;
            }
        }


        var sortedTriangleIndices = this._sortedTriangleIndices;
        for (var i = 0; i < sortedTriangleIndices.length; i++) {
            sortedTriangleIndices[i] = i;
        }

        if (this.triangleCount < 2e4) {
            // Use simple timsort for simple geometries.
            if (frame === 0) {
                // Use native sort temporary.
                this._simpleSort(true);
            }
        }
        else {
            for (var i = 0; i < 3; i++) {
                this._progressiveQuickSort(frame * 3 + i);
            }
        }

        var targetIndices = this._indicesTmp;
        var targetTriangleZList = this._triangleZListTmp;
        var faceZList = this._triangleZList;
        for (var i = 0; i < this.triangleCount; i++) {
            var fromIdx3 = sortedTriangleIndices[i] * 3;
            var toIdx3 = i * 3;
            targetIndices[toIdx3++] = indices[fromIdx3++];
            targetIndices[toIdx3++] = indices[fromIdx3++];
            targetIndices[toIdx3] = indices[fromIdx3];

            targetTriangleZList[i] = faceZList[sortedTriangleIndices[i]];
        }

        // Swap indices.
        var tmp = this._indicesTmp;
        this._indicesTmp = this.indices;
        this.indices = tmp;
        var tmp = this._triangleZListTmp;
        this._triangleZListTmp = this._triangleZList;
        this._triangleZList = tmp;

        this.dirtyIndices();
    },

    _simpleSort: function (useNativeQuickSort) {
        var faceZList = this._triangleZList;
        var sortedTriangleIndices = this._sortedTriangleIndices;

        function compare(a, b) {
            // Sort from far to near. which is descending order
            return faceZList[b] - faceZList[a];
        }
        if (useNativeQuickSort) {
            Array.prototype.sort.call(sortedTriangleIndices, compare);
        }
        else {
            __WEBPACK_IMPORTED_MODULE_0__ProgressiveQuickSort__["a" /* default */].sort(sortedTriangleIndices, compare, 0, sortedTriangleIndices.length - 1);
        }
    },

    _progressiveQuickSort: function (frame) {
        var faceZList = this._triangleZList;
        var sortedTriangleIndices = this._sortedTriangleIndices;

        this._quickSort = this._quickSort || new __WEBPACK_IMPORTED_MODULE_0__ProgressiveQuickSort__["a" /* default */]();

        this._quickSort.step(sortedTriangleIndices, function (a, b) {
            return faceZList[b] - faceZList[a];
        }, frame);
    }
});

/***/ }),
/* 66 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_ZRTextureAtlasSurface__ = __webpack_require__(81);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_mesh_LabelsMesh__ = __webpack_require__(63);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_retrieve__ = __webpack_require__(2);





var LABEL_NORMAL_SHOW_BIT = 1;
var LABEL_EMPHASIS_SHOW_BIT = 2;

function LabelsBuilder(width, height, api) {

    this._labelsMesh = new __WEBPACK_IMPORTED_MODULE_2__util_mesh_LabelsMesh__["a" /* default */]();

    this._labelTextureSurface = new __WEBPACK_IMPORTED_MODULE_1__util_ZRTextureAtlasSurface__["a" /* default */]({
        width: 512,
        height: 512,
        devicePixelRatio: api.getDevicePixelRatio(),
        onupdate: function () {
            api.getZr().refresh();
        }
    });
    this._api = api;

    this._labelsMesh.material.set('textureAtlas', this._labelTextureSurface.getTexture());
}

LabelsBuilder.prototype.getLabelPosition = function (dataIndex, positionDesc, distance) {
    return [0, 0, 0];
};

LabelsBuilder.prototype.getLabelDistance = function (dataIndex, positionDesc, distance) {
    return 0;
};

LabelsBuilder.prototype.getMesh = function () {
    return this._labelsMesh;
};

LabelsBuilder.prototype.updateData = function (data, start, end) {
    if (start == null) {
        start = 0;
    }
    if (end == null) {
        end = data.count();
    }

    if (!this._labelsVisibilitiesBits || this._labelsVisibilitiesBits.length !== (end - start)) {
        this._labelsVisibilitiesBits = new Uint8Array(end - start);
    }
    var normalLabelVisibilityQuery = ['label', 'show'];
    var emphasisLabelVisibilityQuery = ['emphasis', 'label', 'show'];

    for (var idx = start; idx < end; idx++) {
        var itemModel = data.getItemModel(idx);
        var normalVisibility = itemModel.get(normalLabelVisibilityQuery);
        var emphasisVisibility = itemModel.get(emphasisLabelVisibilityQuery);
        if (emphasisVisibility == null) {
            emphasisVisibility = normalVisibility;
        }
        var bit = (normalVisibility ? LABEL_NORMAL_SHOW_BIT : 0)
            | (emphasisVisibility ? LABEL_EMPHASIS_SHOW_BIT : 0);
        this._labelsVisibilitiesBits[idx - start] = bit;
    }

    this._start = start;
    this._end = end;

    this._data = data;
};

LabelsBuilder.prototype.updateLabels = function (highlightDataIndices) {

    if (!this._data) {
        return;
    }

    highlightDataIndices = highlightDataIndices || [];

    var hasHighlightData = highlightDataIndices.length > 0;
    var highlightDataIndicesMap = {};
    for (var i = 0; i < highlightDataIndices.length; i++) {
        highlightDataIndicesMap[highlightDataIndices[i]] = true;
    }

    this._labelsMesh.geometry.convertToDynamicArray(true);
    this._labelTextureSurface.clear();

    var normalLabelQuery = ['label'];
    var emphasisLabelQuery = ['emphasis', 'label'];
    var seriesModel = this._data.hostModel;
    var data = this._data;

    var seriesLabelModel = seriesModel.getModel(normalLabelQuery);
    var seriesLabelEmphasisModel = seriesModel.getModel(emphasisLabelQuery, seriesLabelModel);

    var textAlignMap = {
        left: 'right',
        right: 'left',
        top: 'center',
        bottom: 'center'
    };
    var textVerticalAlignMap = {
        left: 'middle',
        right: 'middle',
        top: 'bottom',
        bottom: 'top'
    };

    for (var dataIndex = this._start; dataIndex < this._end; dataIndex++) {
        var isEmphasis = false;
        if (hasHighlightData && highlightDataIndicesMap[dataIndex]) {
            isEmphasis = true;
        }
        var ifShow = this._labelsVisibilitiesBits[dataIndex - this._start]
            & (isEmphasis ? LABEL_EMPHASIS_SHOW_BIT : LABEL_NORMAL_SHOW_BIT);
        if (!ifShow) {
            continue;
        }

        var itemModel = data.getItemModel(dataIndex);
        var labelModel = itemModel.getModel(
            isEmphasis ? emphasisLabelQuery : normalLabelQuery,
            isEmphasis ? seriesLabelEmphasisModel : seriesLabelModel
        );
        var distance = labelModel.get('distance') || 0;
        var position = labelModel.get('position');
        var textStyleModel = labelModel.getModel('textStyle');

        var dpr = this._api.getDevicePixelRatio();
        var text = seriesModel.getFormattedLabel(dataIndex, isEmphasis ? 'emphasis' : 'normal');
        if (text == null || text === '') {
            return;
        }

        // TODO Background.
        var textEl = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.Text();
        __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.setTextStyle(textEl.style, textStyleModel, {
            text: text,
            textFill: textStyleModel.get('color') || data.getItemVisual(dataIndex, 'color') || '#000',
            textAlign: 'left',
            textVerticalAlign: 'top',
            opacity: __WEBPACK_IMPORTED_MODULE_3__util_retrieve__["a" /* default */].firstNotNull(textStyleModel.get('opacity'), data.getItemVisual(dataIndex, 'opacity'), 1)
        });
        var rect = textEl.getBoundingRect();
        var lineHeight = 1.2;
        rect.height *= lineHeight;

        var coords = this._labelTextureSurface.add(textEl);

        var textAlign = textAlignMap[position] || 'center';
        var textVerticalAlign = textVerticalAlignMap[position] || 'bottom';

        this._labelsMesh.geometry.addSprite(
            this.getLabelPosition(dataIndex, position, distance),
            [rect.width * dpr, rect.height * dpr], coords,
            textAlign, textVerticalAlign,
            this.getLabelDistance(dataIndex, position, distance) * dpr
        );
    }

    this._labelsMesh.material.set('uvScale', this._labelTextureSurface.getCoordsScale());

    // var canvas = this._labelTextureSurface.getTexture().image;
    // document.body.appendChild(canvas);
    // canvas.style.cssText = 'position:absolute;z-index: 1000';

    // Update image.
    this._labelTextureSurface.getZr().refreshImmediately();
    this._labelsMesh.geometry.convertToTypedArray();
    this._labelsMesh.geometry.dirty();
};

/* harmony default export */ __webpack_exports__["a"] = (LabelsBuilder);

/***/ }),
/* 67 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_sprite__ = __webpack_require__(239);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__PointsMesh__ = __webpack_require__(240);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__component_common_LabelsBuilder__ = __webpack_require__(66);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__util_retrieve__ = __webpack_require__(2);








var SDF_RANGE = 20;

var Z_2D = -10;

function isSymbolSizeSame(a, b) {
    return a && b && a[0] === b[0] && a[1] === b[1];
}
// TODO gl_PointSize has max value.
function PointsBuilder(is2D, api) {
    this.rootNode = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();

    /**
     * @type {boolean}
     */
    this.is2D = is2D;

    this._labelsBuilder = new __WEBPACK_IMPORTED_MODULE_4__component_common_LabelsBuilder__["a" /* default */](256, 256, api);

    // Give a large render order.
    this._labelsBuilder.getMesh().renderOrder = 100;
    this.rootNode.add(this._labelsBuilder.getMesh());

    this._api = api;

    this._spriteImageCanvas = document.createElement('canvas');

    this._startDataIndex = 0;
    this._endDataIndex = 0;

    this._sizeScale = 1;
}

PointsBuilder.prototype = {

    constructor: PointsBuilder,

    /**
     * If highlight on over
     */
    highlightOnMouseover: true,

    update: function (seriesModel, ecModel, api, start, end) {
        // Swap barMesh
        var tmp = this._prevMesh;
        this._prevMesh = this._mesh;
        this._mesh = tmp;

        var data = seriesModel.getData();

        if (start == null) {
            start = 0;
        }
        if (end == null) {
            end = data.count();
        }
        this._startDataIndex = start;
        this._endDataIndex = end - 1;

        if (!this._mesh) {
            var material = this._prevMesh && this._prevMesh.material;
            this._mesh = new __WEBPACK_IMPORTED_MODULE_3__PointsMesh__["a" /* default */]({
                // Render after axes
                renderOrder: 10,
                // FIXME
                frustumCulling: false
            });
            if (material) {
                this._mesh.material = material;
            }
        }
        var material = this._mesh.material;
        var geometry = this._mesh.geometry;
        var attributes = geometry.attributes;

        this.rootNode.remove(this._prevMesh);
        this.rootNode.add(this._mesh);

        this._setPositionTextureToMesh(this._mesh, this._positionTexture);

        var symbolInfo = this._getSymbolInfo(seriesModel, start, end);
        var dpr = api.getDevicePixelRatio();

        // TODO image symbol
        var itemStyle = seriesModel.getModel('itemStyle').getItemStyle();
        var largeMode = seriesModel.get('large');

        var pointSizeScale = 1;
        if (symbolInfo.maxSize > 2) {
            pointSizeScale = this._updateSymbolSprite(seriesModel, itemStyle, symbolInfo, dpr);
            material.enableTexture('sprite');
        }
        else {
            material.disableTexture('sprite');
        }

        attributes.position.init(end - start);
        var rgbaArr = [];
        if (largeMode) {
            material.undefine('VERTEX_SIZE');
            material.undefine('VERTEX_COLOR');

            var color = data.getVisual('color');
            var opacity = data.getVisual('opacity');
            __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color, rgbaArr);
            rgbaArr[3] *= opacity;

            material.set({
                color: rgbaArr,
                'u_Size': symbolInfo.maxSize * this._sizeScale
            });
        }
        else {
            material.set({
                color: [1, 1, 1, 1]
            });
            material.define('VERTEX_SIZE');
            material.define('VERTEX_COLOR');
            attributes.size.init(end - start);
            attributes.color.init(end - start);
            this._originalOpacity = new Float32Array(end - start);
        }

        var points = data.getLayout('points');

        var positionArr = attributes.position.value;

        var hasTransparentPoint = false;

        for (var i = 0; i < end - start; i++) {
            var i3 = i * 3;
            var i2 = i * 2;
            if (this.is2D) {
                positionArr[i3] = points[i2];
                positionArr[i3 + 1] = points[i2 + 1];
                positionArr[i3 + 2] = Z_2D;
            }
            else {
                positionArr[i3] = points[i3];
                positionArr[i3 + 1] = points[i3 + 1];
                positionArr[i3 + 2] = points[i3 + 2];
            }

            if (!largeMode) {
                var color = data.getItemVisual(i, 'color');
                var opacity = data.getItemVisual(i, 'opacity');
                __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color, rgbaArr);
                rgbaArr[3] *= opacity;
                attributes.color.set(i, rgbaArr);
                if (rgbaArr[3] < 0.99) {
                    hasTransparentPoint = true;
                }
                var symbolSize = data.getItemVisual(i, 'symbolSize');
                symbolSize = (symbolSize instanceof Array
                    ? Math.max(symbolSize[0], symbolSize[1]) : symbolSize);

                // NaN pointSize may have strange result.
                if (isNaN(symbolSize)) {
                    symbolSize = 0;
                }
                // Scale point size because canvas has margin.
                attributes.size.value[i] = symbolSize * pointSizeScale * this._sizeScale;

                // Save the original opacity for recover from fadeIn.
                this._originalOpacity[i] = rgbaArr[3];
            }

        }

        this._mesh.sizeScale = pointSizeScale;

        geometry.updateBoundingBox();
        geometry.dirty();

        // Update material.
        this._updateMaterial(seriesModel, itemStyle);

        var coordSys = seriesModel.coordinateSystem;
        if (coordSys && coordSys.viewGL) {
            var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
            material[methodName]('fragment', 'SRGB_DECODE');
        }

        if (!largeMode) {
            this._updateLabelBuilder(seriesModel, start, end);
        }

        this._updateHandler(seriesModel, ecModel, api);

        this._updateAnimation(seriesModel);

        this._api = api;
    },

    getPointsMesh: function () {
        return this._mesh;
    },

    updateLabels: function (highlightDataIndices) {
        this._labelsBuilder.updateLabels(highlightDataIndices);
    },

    hideLabels: function () {
        this.rootNode.remove(this._labelsBuilder.getMesh());
    },

    showLabels: function () {
        this.rootNode.add(this._labelsBuilder.getMesh());
    },

    _updateSymbolSprite: function (seriesModel, itemStyle, symbolInfo, dpr) {
        symbolInfo.maxSize = Math.min(symbolInfo.maxSize * 2, 200);
        var symbolSize = [];
        if (symbolInfo.aspect > 1) {
            symbolSize[0] = symbolInfo.maxSize;
            symbolSize[1] = symbolInfo.maxSize / symbolInfo.aspect;
        }
        else {
            symbolSize[1] = symbolInfo.maxSize;
            symbolSize[0] = symbolInfo.maxSize * symbolInfo.aspect;
        }

        // In case invalid data.
        symbolSize[0] = symbolSize[0] || 1;
        symbolSize[1] = symbolSize[1] || 1;

        if (this._symbolType !== symbolInfo.type
            || !isSymbolSizeSame(this._symbolSize, symbolSize)
            || this._lineWidth !== itemStyle.lineWidth
        ) {
            __WEBPACK_IMPORTED_MODULE_2__util_sprite__["a" /* default */].createSymbolSprite(symbolInfo.type, symbolSize, {
                fill: '#fff',
                lineWidth: itemStyle.lineWidth,
                stroke: 'transparent',
                shadowColor: 'transparent',
                minMargin: Math.min(symbolSize[0] / 2, 10)
            }, this._spriteImageCanvas);

            __WEBPACK_IMPORTED_MODULE_2__util_sprite__["a" /* default */].createSDFFromCanvas(
                this._spriteImageCanvas, Math.min(this._spriteImageCanvas.width, 32), SDF_RANGE,
                this._mesh.material.get('sprite').image
            );

            this._symbolType = symbolInfo.type;
            this._symbolSize = symbolSize;
            this._lineWidth = itemStyle.lineWidth;
        }
        return this._spriteImageCanvas.width / symbolInfo.maxSize * dpr;

    },

    _updateMaterial: function (seriesModel, itemStyle) {
        var blendFunc = seriesModel.get('blendMode') === 'lighter'
            ? __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].additiveBlend : null;
        var material = this._mesh.material;
        material.blend = blendFunc;

        material.set('lineWidth', itemStyle.lineWidth / SDF_RANGE);

        var strokeColor = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(itemStyle.stroke);
        material.set('strokeColor', strokeColor);

        // Because of symbol texture, we always needs it be transparent.
        material.transparent = true;
        material.depthMask = false;
        material.depthTest = !this.is2D;
        material.sortVertices = !this.is2D;
    },

    _updateLabelBuilder: function (seriesModel, start, end) {
        var data =seriesModel.getData();
        var geometry = this._mesh.geometry;
        var positionArr = geometry.attributes.position.value;
        var start = this._startDataIndex;
        var pointSizeScale = this._mesh.sizeScale;
        this._labelsBuilder.updateData(data, start, end);

        this._labelsBuilder.getLabelPosition = function (dataIndex, positionDesc, distance) {
            var idx3 = (dataIndex - start) * 3;
            return [positionArr[idx3], positionArr[idx3 + 1], positionArr[idx3 + 2]];
        };

        this._labelsBuilder.getLabelDistance = function (dataIndex, positionDesc, distance) {
            var size = geometry.attributes.size.get(dataIndex - start) / pointSizeScale;
            return size / 2 + distance;
        };
        this._labelsBuilder.updateLabels();

    },

    _updateAnimation: function (seriesModel) {
        __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].updateVertexAnimation(
            [['prevPosition', 'position'],
            ['prevSize', 'size']],
            this._prevMesh,
            this._mesh,
            seriesModel
        );
    },

    _updateHandler: function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();
        var pointsMesh = this._mesh;
        var self = this;

        var lastDataIndex = -1;
        var isCartesian3D = seriesModel.coordinateSystem
            && seriesModel.coordinateSystem.type === 'cartesian3D';

        var grid3DModel;
        if (isCartesian3D) {
            grid3DModel = seriesModel.coordinateSystem.model;
        }

        pointsMesh.seriesIndex = seriesModel.seriesIndex;

        pointsMesh.off('mousemove');
        pointsMesh.off('mouseout');

        pointsMesh.on('mousemove', function (e) {
            var dataIndex = e.vertexIndex + self._startDataIndex;
            if (dataIndex !== lastDataIndex) {
                if (this.highlightOnMouseover) {
                    this.downplay(data, lastDataIndex);
                    this.highlight(data, dataIndex);
                    this._labelsBuilder.updateLabels([dataIndex]);
                }

                if (isCartesian3D) {
                    api.dispatchAction({
                        type: 'grid3DShowAxisPointer',
                        value: [
                            data.get(seriesModel.coordDimToDataDim('x')[0], dataIndex),
                            data.get(seriesModel.coordDimToDataDim('y')[0], dataIndex),
                            data.get(seriesModel.coordDimToDataDim('z')[0], dataIndex)
                        ],
                        grid3DIndex: grid3DModel.componentIndex
                    });
                }
            }

            pointsMesh.dataIndex = dataIndex;
            lastDataIndex = dataIndex;
        }, this);
        pointsMesh.on('mouseout', function (e) {
            var dataIndex = e.vertexIndex + self._startDataIndex;
            if (this.highlightOnMouseover) {
                this.downplay(data, dataIndex);
                this._labelsBuilder.updateLabels();
            }
            lastDataIndex = -1;
            pointsMesh.dataIndex = -1;

            if (isCartesian3D) {
                api.dispatchAction({
                    type: 'grid3DHideAxisPointer',
                    grid3DIndex: grid3DModel.componentIndex
                });
            }
        }, this);
    },

    updateLayout: function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();
        if (!this._mesh) {
            return;
        }

        var positionArr = this._mesh.geometry.attributes.position.value;
        var points = data.getLayout('points');
        if (this.is2D) {
            for (var i = 0; i < points.length / 2; i++) {
                var i3 = i * 3;
                var i2 = i * 2;
                positionArr[i3] = points[i2];
                positionArr[i3 + 1] = points[i2 + 1];
                positionArr[i3 + 2] = Z_2D;
            }
        }
        else {
            for (var i = 0; i < points.length; i++) {
                positionArr[i] = points[i];
            }
        }
        this._mesh.geometry.dirty();

        api.getZr().refresh();
    },

    updateView: function (camera) {
        if (!this._mesh) {
            return;
        }

        var worldViewProjection = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */]();
        __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */].mul(worldViewProjection, camera.viewMatrix, this._mesh.worldTransform);
        __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */].mul(worldViewProjection, camera.projectionMatrix, worldViewProjection);

        this._mesh.updateNDCPosition(worldViewProjection, this.is2D, this._api);
    },

    highlight: function (data, dataIndex) {
        if (dataIndex > this._endDataIndex || dataIndex < this._startDataIndex) {
            return;
        }
        var itemModel = data.getItemModel(dataIndex);
        var emphasisItemStyleModel = itemModel.getModel('emphasis.itemStyle');
        var emphasisColor = emphasisItemStyleModel.get('color');
        var emphasisOpacity = emphasisItemStyleModel.get('opacity');
        if (emphasisColor == null) {
            var color = data.getItemVisual(dataIndex, 'color');
            emphasisColor = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.color.lift(color, -0.4);
        }
        if (emphasisOpacity == null) {
            emphasisOpacity = data.getItemVisual(dataIndex, 'opacity');
        }
        var colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(emphasisColor);
        colorArr[3] *= emphasisOpacity;

        this._mesh.geometry.attributes.color.set(dataIndex - this._startDataIndex, colorArr);
        this._mesh.geometry.dirtyAttribute('color');

        this._api.getZr().refresh();
    },

    downplay: function (data, dataIndex) {
        if (dataIndex > this._endDataIndex || dataIndex < this._startDataIndex) {
            return;
        }
        var color = data.getItemVisual(dataIndex, 'color');
        var opacity = data.getItemVisual(dataIndex, 'opacity');

        var colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color);
        colorArr[3] *= opacity;

        this._mesh.geometry.attributes.color.set(dataIndex - this._startDataIndex, colorArr);
        this._mesh.geometry.dirtyAttribute('color');

        this._api.getZr().refresh();
    },

    fadeOutAll: function (fadeOutPercent) {
        if (this._originalOpacity) {
            var geo = this._mesh.geometry;
            for (var i = 0; i < geo.vertexCount; i++) {
                var fadeOutOpacity = this._originalOpacity[i] * fadeOutPercent;
                geo.attributes.color.value[i * 4 + 3] = fadeOutOpacity;
            }
            geo.dirtyAttribute('color');

            this._api.getZr().refresh();
        }
    },

    fadeInAll: function () {
        this.fadeOutAll(1);
    },

    setPositionTexture: function (texture) {
        if (this._mesh) {
            this._setPositionTextureToMesh(this._mesh, texture);
        }

        this._positionTexture = texture;
    },

    removePositionTexture: function () {
        this._positionTexture = null;
        if (this._mesh) {
            this._setPositionTextureToMesh(this._mesh, null);
        }
    },

    setSizeScale: function (sizeScale) {
        if (sizeScale !== this._sizeScale) {
            if (this._mesh) {
                var originalSize = this._mesh.material.get('u_Size');
                this._mesh.material.set('u_Size', originalSize / this._sizeScale * sizeScale);

                var attributes = this._mesh.geometry.attributes;
                if (attributes.size.value) {
                    for (var i = 0; i < attributes.size.value.length; i++) {
                        attributes.size.value[i] = attributes.size.value[i] / this._sizeScale * sizeScale;
                    }
                }
            }
            this._sizeScale = sizeScale;
        }
    },

    _setPositionTextureToMesh: function (mesh, texture) {
        if (texture) {
            mesh.material.set('positionTexture', texture);
        }
        mesh.material[
            texture ? 'enableTexture' : 'disableTexture'
        ]('positionTexture');
    },

    _getSymbolInfo: function (seriesModel, start, end) {
        if (seriesModel.get('large')) {
            var symbolSize = __WEBPACK_IMPORTED_MODULE_6__util_retrieve__["a" /* default */].firstNotNull(seriesModel.get('symbolSize'), 1);
            var maxSymbolSize;
            var symbolAspect;
            if (symbolSize instanceof Array) {
                maxSymbolSize = Math.max(symbolSize[0], symbolSize[1]);
                symbolAspect = symbolSize[0] / symbolSize[1];
            }
            else {
                maxSymbolSize = symbolSize;
                symbolAspect = 1;
            }
            return {
                maxSize: symbolSize,
                type: seriesModel.get('symbol'),
                aspect: symbolAspect
            }
        }
        var data = seriesModel.getData();
        var symbolAspect;
        var differentSymbolAspect = false;
        var symbolType = data.getItemVisual(0, 'symbol') || 'circle';
        var differentSymbolType = false;
        var maxSymbolSize = 0;

        for (var idx = start; idx < end; idx++) {
            var symbolSize = data.getItemVisual(idx, 'symbolSize');
            var currentSymbolType = data.getItemVisual(idx, 'symbol');
            var currentSymbolAspect;
            if (!(symbolSize instanceof Array)) {
                // Ignore NaN value.
                if (isNaN(symbolSize)) {
                    return;
                }

                currentSymbolAspect = 1;
                maxSymbolSize = Math.max(symbolSize, maxSymbolSize);
            }
            else {
                currentSymbolAspect = symbolSize[0] / symbolSize[1];
                maxSymbolSize = Math.max(Math.max(symbolSize[0], symbolSize[1]), maxSymbolSize);
            }
            if (true) {
                if (symbolAspect != null && Math.abs(currentSymbolAspect - symbolAspect) > 0.05) {
                    differentSymbolAspect = true;
                }
                if (currentSymbolType !== symbolType) {
                    differentSymbolType = true;
                }
            }
            symbolType = currentSymbolType;
            symbolAspect = currentSymbolAspect;
        }

        if (true) {
            if (differentSymbolAspect) {
                console.warn('Different symbol width / height ratio will be ignored.');
            }
            if (differentSymbolType) {
                console.warn('Different symbol type will be ignored.');
            }
        }

        return {
            maxSize: maxSymbolSize,
            type: symbolType,
            aspect: symbolAspect
        };
    }
};

/* harmony default export */ __webpack_exports__["a"] = (PointsBuilder);


/***/ }),
/* 68 */
/***/ (function(module, exports) {

var g;

// This works in non-strict mode
g = (function() {
	return this;
})();

try {
	// This works if eval is allowed (see CSP)
	g = g || Function("return this")() || (1,eval)("this");
} catch(e) {
	// This works if the window reference is available
	if(typeof window === "object")
		g = window;
}

// g can still be undefined, but nothing to do about it...
// We return undefined, instead of nothing here, so it's
// easier to handle this case. if(!global) { ...}

module.exports = g;


/***/ }),
/* 69 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__LinkedList__ = __webpack_require__(114);


/**
 * LRU Cache
 * @constructor
 * @alias clay.core.LRU
 */
var LRU = function (maxSize) {

    this._list = new __WEBPACK_IMPORTED_MODULE_0__LinkedList__["a" /* default */]();

    this._map = {};

    this._maxSize = maxSize || 10;
};

/**
 * Set cache max size
 * @param {number} size
 */
LRU.prototype.setMaxSize = function (size) {
    this._maxSize = size;
};

/**
 * @param  {string} key
 * @param  {} value
 */
LRU.prototype.put = function (key, value) {
    if (!this._map.hasOwnProperty(key)) {
        var len = this._list.length();
        if (len >= this._maxSize && len > 0) {
            // Remove the least recently used
            var leastUsedEntry = this._list.head;
            this._list.remove(leastUsedEntry);
            delete this._map[leastUsedEntry.key];
        }

        var entry = this._list.insert(value);
        entry.key = key;
        this._map[key] = entry;
    }
};

/**
 * @param  {string} key
 * @return {}
 */
LRU.prototype.get = function (key) {
    var entry = this._map[key];
    if (this._map.hasOwnProperty(key)) {
        // Put the latest used entry in the tail
        if (entry !== this._list.tail) {
            this._list.remove(entry);
            this._list.insertEntry(entry);
        }

        return entry.value;
    }
};

/**
 * @param {string} key
 */
LRU.prototype.remove = function (key) {
    var entry = this._map[key];
    if (typeof(entry) !== 'undefined') {
        delete this._map[key];
        this._list.remove(entry);
    }
};

/**
 * Clear the cache
 */
LRU.prototype.clear = function () {
    this._list.clear();
    this._map = {};
};

/* harmony default export */ __webpack_exports__["a"] = (LRU);


/***/ }),
/* 70 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common__ = __webpack_require__(20);

/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */



/**
 * @class 2 Dimensional Vector
 * @name vec2
 */

var vec2 = {};

/**
 * Creates a new, empty vec2
 *
 * @returns {vec2} a new 2D vector
 */
vec2.create = function() {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](2);
    out[0] = 0;
    out[1] = 0;
    return out;
};

/**
 * Creates a new vec2 initialized with values from an existing vector
 *
 * @param {vec2} a vector to clone
 * @returns {vec2} a new 2D vector
 */
vec2.clone = function(a) {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](2);
    out[0] = a[0];
    out[1] = a[1];
    return out;
};

/**
 * Creates a new vec2 initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @returns {vec2} a new 2D vector
 */
vec2.fromValues = function(x, y) {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](2);
    out[0] = x;
    out[1] = y;
    return out;
};

/**
 * Copy the values from one vec2 to another
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the source vector
 * @returns {vec2} out
 */
vec2.copy = function(out, a) {
    out[0] = a[0];
    out[1] = a[1];
    return out;
};

/**
 * Set the components of a vec2 to the given values
 *
 * @param {vec2} out the receiving vector
 * @param {Number} x X component
 * @param {Number} y Y component
 * @returns {vec2} out
 */
vec2.set = function(out, x, y) {
    out[0] = x;
    out[1] = y;
    return out;
};

/**
 * Adds two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec2} out
 */
vec2.add = function(out, a, b) {
    out[0] = a[0] + b[0];
    out[1] = a[1] + b[1];
    return out;
};

/**
 * Subtracts vector b from vector a
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec2} out
 */
vec2.subtract = function(out, a, b) {
    out[0] = a[0] - b[0];
    out[1] = a[1] - b[1];
    return out;
};

/**
 * Alias for {@link vec2.subtract}
 * @function
 */
vec2.sub = vec2.subtract;

/**
 * Multiplies two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec2} out
 */
vec2.multiply = function(out, a, b) {
    out[0] = a[0] * b[0];
    out[1] = a[1] * b[1];
    return out;
};

/**
 * Alias for {@link vec2.multiply}
 * @function
 */
vec2.mul = vec2.multiply;

/**
 * Divides two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec2} out
 */
vec2.divide = function(out, a, b) {
    out[0] = a[0] / b[0];
    out[1] = a[1] / b[1];
    return out;
};

/**
 * Alias for {@link vec2.divide}
 * @function
 */
vec2.div = vec2.divide;

/**
 * Returns the minimum of two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec2} out
 */
vec2.min = function(out, a, b) {
    out[0] = Math.min(a[0], b[0]);
    out[1] = Math.min(a[1], b[1]);
    return out;
};

/**
 * Returns the maximum of two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec2} out
 */
vec2.max = function(out, a, b) {
    out[0] = Math.max(a[0], b[0]);
    out[1] = Math.max(a[1], b[1]);
    return out;
};

/**
 * Scales a vec2 by a scalar number
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {vec2} out
 */
vec2.scale = function(out, a, b) {
    out[0] = a[0] * b;
    out[1] = a[1] * b;
    return out;
};

/**
 * Adds two vec2's after scaling the second operand by a scalar value
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @param {Number} scale the amount to scale b by before adding
 * @returns {vec2} out
 */
vec2.scaleAndAdd = function(out, a, b, scale) {
    out[0] = a[0] + (b[0] * scale);
    out[1] = a[1] + (b[1] * scale);
    return out;
};

/**
 * Calculates the euclidian distance between two vec2's
 *
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {Number} distance between a and b
 */
vec2.distance = function(a, b) {
    var x = b[0] - a[0],
        y = b[1] - a[1];
    return Math.sqrt(x*x + y*y);
};

/**
 * Alias for {@link vec2.distance}
 * @function
 */
vec2.dist = vec2.distance;

/**
 * Calculates the squared euclidian distance between two vec2's
 *
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {Number} squared distance between a and b
 */
vec2.squaredDistance = function(a, b) {
    var x = b[0] - a[0],
        y = b[1] - a[1];
    return x*x + y*y;
};

/**
 * Alias for {@link vec2.squaredDistance}
 * @function
 */
vec2.sqrDist = vec2.squaredDistance;

/**
 * Calculates the length of a vec2
 *
 * @param {vec2} a vector to calculate length of
 * @returns {Number} length of a
 */
vec2.length = function (a) {
    var x = a[0],
        y = a[1];
    return Math.sqrt(x*x + y*y);
};

/**
 * Alias for {@link vec2.length}
 * @function
 */
vec2.len = vec2.length;

/**
 * Calculates the squared length of a vec2
 *
 * @param {vec2} a vector to calculate squared length of
 * @returns {Number} squared length of a
 */
vec2.squaredLength = function (a) {
    var x = a[0],
        y = a[1];
    return x*x + y*y;
};

/**
 * Alias for {@link vec2.squaredLength}
 * @function
 */
vec2.sqrLen = vec2.squaredLength;

/**
 * Negates the components of a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a vector to negate
 * @returns {vec2} out
 */
vec2.negate = function(out, a) {
    out[0] = -a[0];
    out[1] = -a[1];
    return out;
};

/**
 * Returns the inverse of the components of a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a vector to invert
 * @returns {vec2} out
 */
vec2.inverse = function(out, a) {
  out[0] = 1.0 / a[0];
  out[1] = 1.0 / a[1];
  return out;
};

/**
 * Normalize a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a vector to normalize
 * @returns {vec2} out
 */
vec2.normalize = function(out, a) {
    var x = a[0],
        y = a[1];
    var len = x*x + y*y;
    if (len > 0) {
        //TODO: evaluate use of glm_invsqrt here?
        len = 1 / Math.sqrt(len);
        out[0] = a[0] * len;
        out[1] = a[1] * len;
    }
    return out;
};

/**
 * Calculates the dot product of two vec2's
 *
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {Number} dot product of a and b
 */
vec2.dot = function (a, b) {
    return a[0] * b[0] + a[1] * b[1];
};

/**
 * Computes the cross product of two vec2's
 * Note that the cross product must by definition produce a 3D vector
 *
 * @param {vec3} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec3} out
 */
vec2.cross = function(out, a, b) {
    var z = a[0] * b[1] - a[1] * b[0];
    out[0] = out[1] = 0;
    out[2] = z;
    return out;
};

/**
 * Performs a linear interpolation between two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @param {Number} t interpolation amount between the two inputs
 * @returns {vec2} out
 */
vec2.lerp = function (out, a, b, t) {
    var ax = a[0],
        ay = a[1];
    out[0] = ax + t * (b[0] - ax);
    out[1] = ay + t * (b[1] - ay);
    return out;
};

/**
 * Generates a random vector with the given scale
 *
 * @param {vec2} out the receiving vector
 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
 * @returns {vec2} out
 */
vec2.random = function (out, scale) {
    scale = scale || 1.0;
    var r = GLMAT_RANDOM() * 2.0 * Math.PI;
    out[0] = Math.cos(r) * scale;
    out[1] = Math.sin(r) * scale;
    return out;
};

/**
 * Transforms the vec2 with a mat2
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the vector to transform
 * @param {mat2} m matrix to transform with
 * @returns {vec2} out
 */
vec2.transformMat2 = function(out, a, m) {
    var x = a[0],
        y = a[1];
    out[0] = m[0] * x + m[2] * y;
    out[1] = m[1] * x + m[3] * y;
    return out;
};

/**
 * Transforms the vec2 with a mat2d
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the vector to transform
 * @param {mat2d} m matrix to transform with
 * @returns {vec2} out
 */
vec2.transformMat2d = function(out, a, m) {
    var x = a[0],
        y = a[1];
    out[0] = m[0] * x + m[2] * y + m[4];
    out[1] = m[1] * x + m[3] * y + m[5];
    return out;
};

/**
 * Transforms the vec2 with a mat3
 * 3rd vector component is implicitly '1'
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the vector to transform
 * @param {mat3} m matrix to transform with
 * @returns {vec2} out
 */
vec2.transformMat3 = function(out, a, m) {
    var x = a[0],
        y = a[1];
    out[0] = m[0] * x + m[3] * y + m[6];
    out[1] = m[1] * x + m[4] * y + m[7];
    return out;
};

/**
 * Transforms the vec2 with a mat4
 * 3rd vector component is implicitly '0'
 * 4th vector component is implicitly '1'
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the vector to transform
 * @param {mat4} m matrix to transform with
 * @returns {vec2} out
 */
vec2.transformMat4 = function(out, a, m) {
    var x = a[0],
        y = a[1];
    out[0] = m[0] * x + m[4] * y + m[12];
    out[1] = m[1] * x + m[5] * y + m[13];
    return out;
};

/**
 * Perform some operation over an array of vec2s.
 *
 * @param {Array} a the array of vectors to iterate over
 * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed
 * @param {Number} offset Number of elements to skip at the beginning of the array
 * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array
 * @param {Function} fn Function to call for each vector in the array
 * @param {Object} [arg] additional argument to pass to fn
 * @returns {Array} a
 * @function
 */
vec2.forEach = (function() {
    var vec = vec2.create();

    return function(a, stride, offset, count, fn, arg) {
        var i, l;
        if(!stride) {
            stride = 2;
        }

        if(!offset) {
            offset = 0;
        }

        if(count) {
            l = Math.min((count * stride) + offset, a.length);
        } else {
            l = a.length;
        }

        for(i = offset; i < l; i += stride) {
            vec[0] = a[i]; vec[1] = a[i+1];
            fn(vec, vec, arg);
            a[i] = vec[0]; a[i+1] = vec[1];
        }

        return a;
    };
})();

/* harmony default export */ __webpack_exports__["a"] = (vec2);

/***/ }),
/* 71 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.prez.vertex\nuniform mat4 WVP : WORLDVIEWPROJECTION;\nattribute vec3 pos : POSITION;\nattribute vec2 uv : TEXCOORD_0;\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvoid main()\n{\n vec3 P = pos;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n P = (skinMatrixWS * vec4(pos, 1.0)).xyz;\n#endif\n gl_Position = WVP * vec4(P, 1.0);\n v_Texcoord = uv;\n}\n@end\n@export clay.prez.fragment\nuniform sampler2D alphaMap;\nuniform float alphaCutoff: 0.0;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n if (alphaCutoff > 0.0) {\n if (texture2D(alphaMap, v_Texcoord).a <= alphaCutoff) {\n discard;\n }\n }\n gl_FragColor = vec4(0.0,0.0,0.0,1.0);\n}\n@end");


/***/ }),
/* 72 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Node__ = __webpack_require__(35);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);



/**
 * @constructor
 * @alias clay.Renderable
 * @extends clay.Node
 */
var Renderable = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].extend(/** @lends clay.Renderable# */ {
    /**
     * @type {clay.Material}
     */
    material: null,

    /**
     * @type {clay.Geometry}
     */
    geometry: null,

    /**
     * @type {number}
     */
    mode: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLES,

    _renderInfo: null
},
/** @lends clay.Renderable.prototype */
{

    __program: null,

    /**
     * Group of received light.
     */
    lightGroup: 0,
    /**
     * Render order, Nodes with smaller value renders before nodes with larger values.
     * @type {Number}
     */
    renderOrder: 0,

    /**
     * Used when mode is LINES, LINE_STRIP or LINE_LOOP
     * @type {number}
     */
    // lineWidth: 1,

    /**
     * If enable culling
     * @type {boolean}
     */
    culling: true,
    /**
     * Specify which side of polygon will be culled.
     * Possible values:
     *  + {@link clay.Renderable.BACK}
     *  + {@link clay.Renderable.FRONT}
     *  + {@link clay.Renderable.FRONT_AND_BACK}
     * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/cullFace
     * @type {number}
     */
    cullFace: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].BACK,
    /**
     * Specify which side is front face.
     * Possible values:
     *  + {@link clay.Renderable.CW}
     *  + {@link clay.Renderable.CCW}
     * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/frontFace
     * @type {number}
     */
    frontFace: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CCW,

    /**
     * If enable software frustum culling
     * @type {boolean}
     */
    frustumCulling: true,
    /**
     * @type {boolean}
     */
    receiveShadow: true,
    /**
     * @type {boolean}
     */
    castShadow: true,
    /**
     * @type {boolean}
     */
    ignorePicking: false,
    /**
     * @type {boolean}
     */
    ignorePreZ: false,

    /**
     * @type {boolean}
     */
    ignoreGBuffer: false,

    /**
     * @return {boolean}
     */
    isRenderable: function() {
        // TODO Shader ?
        return this.geometry && this.material && this.material.shader && !this.invisible
            && this.geometry.vertexCount > 0;
    },

    /**
     * Before render hook
     * @type {Function}
     */
    beforeRender: function (_gl) {},

    /**
     * Before render hook
     * @type {Function}
     */
    afterRender: function (_gl, renderStat) {},

    getBoundingBox: function (filter, out) {
        out = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].prototype.getBoundingBox.call(this, filter, out);
        if (this.geometry && this.geometry.boundingBox) {
            out.union(this.geometry.boundingBox);
        }

        return out;
    },

    /**
     * Clone a new renderable
     * @function
     * @return {clay.Renderable}
     */
    clone: (function() {
        var properties = [
            'castShadow', 'receiveShadow',
            'mode', 'culling', 'cullFace', 'frontFace',
            'frustumCulling',
            'renderOrder', 'lineWidth',
            'ignorePicking', 'ignorePreZ', 'ignoreGBuffer'
        ];
        return function() {
            var renderable = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].prototype.clone.call(this);

            renderable.geometry = this.geometry;
            renderable.material = this.material;

            for (var i = 0; i < properties.length; i++) {
                var name = properties[i];
                // Try not to overwrite the prototype property
                if (renderable[name] !== this[name]) {
                    renderable[name] = this[name];
                }
            }

            return renderable;
        };
    })()
});

/**
 * @type {number}
 */
Renderable.POINTS = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].POINTS;
/**
 * @type {number}
 */
Renderable.LINES = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINES;
/**
 * @type {number}
 */
Renderable.LINE_LOOP = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINE_LOOP;
/**
 * @type {number}
 */
Renderable.LINE_STRIP = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINE_STRIP;
/**
 * @type {number}
 */
Renderable.TRIANGLES = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLES;
/**
 * @type {number}
 */
Renderable.TRIANGLE_STRIP = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLE_STRIP;
/**
 * @type {number}
 */
Renderable.TRIANGLE_FAN = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLE_FAN;
/**
 * @type {number}
 */
Renderable.BACK = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].BACK;
/**
 * @type {number}
 */
Renderable.FRONT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FRONT;
/**
 * @type {number}
 */
Renderable.FRONT_AND_BACK = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FRONT_AND_BACK;
/**
 * @type {number}
 */
Renderable.CW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CW;
/**
 * @type {number}
 */
Renderable.CCW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CCW;

/* harmony default export */ __webpack_exports__["a"] = (Renderable);


/***/ }),
/* 73 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
var mathUtil = {};

mathUtil.isPowerOfTwo = function (value) {
    return (value & (value - 1)) === 0;
};

mathUtil.nextPowerOfTwo = function (value) {
    value --;
    value |= value >> 1;
    value |= value >> 2;
    value |= value >> 4;
    value |= value >> 8;
    value |= value >> 16;
    value ++;

    return value;
};

mathUtil.nearestPowerOfTwo = function (value) {
    return Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );
};

/* harmony default export */ __webpack_exports__["a"] = (mathUtil);


/***/ }),
/* 74 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__glmatrix_mat4__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__ = __webpack_require__(12);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__glmatrix_vec4__ = __webpack_require__(33);





/**
 * @constructor
 * @alias clay.Plane
 * @param {clay.Vector3} [normal]
 * @param {number} [distance]
 */
var Plane = function(normal, distance) {
    /**
     * Normal of the plane
     * @type {clay.Vector3}
     */
    this.normal = normal || new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */](0, 1, 0);

    /**
     * Constant of the plane equation, used as distance to the origin
     * @type {number}
     */
    this.distance = distance || 0;
};

Plane.prototype = {

    constructor: Plane,

    /**
     * Distance from a given point to the plane
     * @param  {clay.Vector3} point
     * @return {number}
     */
    distanceToPoint: function(point) {
        return __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].dot(point.array, this.normal.array) - this.distance;
    },

    /**
     * Calculate the projection point on the plane
     * @param  {clay.Vector3} point
     * @param  {clay.Vector3} out
     * @return {clay.Vector3}
     */
    projectPoint: function(point, out) {
        if (!out) {
            out = new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
        }
        var d = this.distanceToPoint(point);
        __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].scaleAndAdd(out.array, point.array, this.normal.array, -d);
        out._dirty = true;
        return out;
    },

    /**
     * Normalize the plane's normal and calculate the distance
     */
    normalize: function() {
        var invLen = 1 / __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].len(this.normal.array);
        __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].scale(this.normal.array, invLen);
        this.distance *= invLen;
    },

    /**
     * If the plane intersect a frustum
     * @param  {clay.Frustum} Frustum
     * @return {boolean}
     */
    intersectFrustum: function(frustum) {
        // Check if all coords of frustum is on plane all under plane
        var coords = frustum.vertices;
        var normal = this.normal.array;
        var onPlane = __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].dot(coords[0].array, normal) > this.distance;
        for (var i = 1; i < 8; i++) {
            if ((__WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].dot(coords[i].array, normal) > this.distance) != onPlane) {
                return true;
            }
        }
    },

    /**
     * Calculate the intersection point between plane and a given line
     * @function
     * @param {clay.Vector3} start start point of line
     * @param {clay.Vector3} end end point of line
     * @param {clay.Vector3} [out]
     * @return {clay.Vector3}
     */
    intersectLine: (function() {
        var rd = __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].create();
        return function(start, end, out) {
            var d0 = this.distanceToPoint(start);
            var d1 = this.distanceToPoint(end);
            if ((d0 > 0 && d1 > 0) || (d0 < 0 && d1 < 0)) {
                return null;
            }
            // Ray intersection
            var pn = this.normal.array;
            var d = this.distance;
            var ro = start.array;
            // direction
            __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].sub(rd, end.array, start.array);
            __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].normalize(rd, rd);

            var divider = __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].dot(pn, rd);
            // ray is parallel to the plane
            if (divider === 0) {
                return null;
            }
            if (!out) {
                out = new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
            }
            var t = (__WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].dot(pn, ro) - d) / divider;
            __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].scaleAndAdd(out.array, ro, rd, -t);
            out._dirty = true;
            return out;
        };
    })(),

    /**
     * Apply an affine transform matrix to plane
     * @function
     * @return {clay.Matrix4}
     */
    applyTransform: (function() {
        var inverseTranspose = __WEBPACK_IMPORTED_MODULE_1__glmatrix_mat4__["a" /* default */].create();
        var normalv4 = __WEBPACK_IMPORTED_MODULE_3__glmatrix_vec4__["a" /* default */].create();
        var pointv4 = __WEBPACK_IMPORTED_MODULE_3__glmatrix_vec4__["a" /* default */].create();
        pointv4[3] = 1;
        return function(m4) {
            m4 = m4.array;
            // Transform point on plane
            __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].scale(pointv4, this.normal.array, this.distance);
            __WEBPACK_IMPORTED_MODULE_3__glmatrix_vec4__["a" /* default */].transformMat4(pointv4, pointv4, m4);
            this.distance = __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].dot(pointv4, this.normal.array);
            // Transform plane normal
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_mat4__["a" /* default */].invert(inverseTranspose, m4);
            __WEBPACK_IMPORTED_MODULE_1__glmatrix_mat4__["a" /* default */].transpose(inverseTranspose, inverseTranspose);
            normalv4[3] = 0;
            __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].copy(normalv4, this.normal.array);
            __WEBPACK_IMPORTED_MODULE_3__glmatrix_vec4__["a" /* default */].transformMat4(normalv4, normalv4, inverseTranspose);
            __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].copy(this.normal.array, normalv4);
        };
    })(),

    /**
     * Copy from another plane
     * @param  {clay.Vector3} plane
     */
    copy: function(plane) {
        __WEBPACK_IMPORTED_MODULE_2__glmatrix_vec3__["a" /* default */].copy(this.normal.array, plane.normal.array);
        this.normal._dirty = true;
        this.distance = plane.distance;
    },

    /**
     * Clone a new plane
     * @return {clay.Plane}
     */
    clone: function() {
        var plane = new Plane();
        plane.copy(this);
        return plane;
    }
};

/* harmony default export */ __webpack_exports__["a"] = (Plane);


/***/ }),
/* 75 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Skybox__ = __webpack_require__(42);


/* harmony default export */ __webpack_exports__["a"] = (__WEBPACK_IMPORTED_MODULE_0__Skybox__["a" /* default */]);

/***/ }),
/* 76 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Geometry__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Plane__ = __webpack_require__(43);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__math_BoundingBox__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__core_vendor__ = __webpack_require__(14);







var planeMatrix = new __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */]();

/**
 * @constructor clay.geometry.Cube
 * @extends clay.Geometry
 * @param {Object} [opt]
 * @param {number} [opt.widthSegments]
 * @param {number} [opt.heightSegments]
 * @param {number} [opt.depthSegments]
 * @param {boolean} [opt.inside]
 */
var Cube = __WEBPACK_IMPORTED_MODULE_0__Geometry__["a" /* default */].extend(
/**@lends clay.geometry.Cube# */
{
    dynamic: false,
    /**
     * @type {number}
     */
    widthSegments: 1,
    /**
     * @type {number}
     */
    heightSegments: 1,
    /**
     * @type {number}
     */
    depthSegments: 1,
    /**
     * @type {boolean}
     */
    inside: false
}, function() {
    this.build();
},
/** @lends clay.geometry.Cube.prototype */
{
    /**
     * Build cube geometry
     */
    build: function() {

        var planes = {
            'px': createPlane('px', this.depthSegments, this.heightSegments),
            'nx': createPlane('nx', this.depthSegments, this.heightSegments),
            'py': createPlane('py', this.widthSegments, this.depthSegments),
            'ny': createPlane('ny', this.widthSegments, this.depthSegments),
            'pz': createPlane('pz', this.widthSegments, this.heightSegments),
            'nz': createPlane('nz', this.widthSegments, this.heightSegments),
        };

        var attrList = ['position', 'texcoord0', 'normal'];
        var vertexNumber = 0;
        var faceNumber = 0;
        for (var pos in planes) {
            vertexNumber += planes[pos].vertexCount;
            faceNumber += planes[pos].indices.length;
        }
        for (var k = 0; k < attrList.length; k++) {
            this.attributes[attrList[k]].init(vertexNumber);
        }
        this.indices = new __WEBPACK_IMPORTED_MODULE_5__core_vendor__["a" /* default */].Uint16Array(faceNumber);
        var faceOffset = 0;
        var vertexOffset = 0;
        for (var pos in planes) {
            var plane = planes[pos];
            for (var k = 0; k < attrList.length; k++) {
                var attrName = attrList[k];
                var attrArray = plane.attributes[attrName].value;
                var attrSize = plane.attributes[attrName].size;
                var isNormal = attrName === 'normal';
                for (var i = 0; i < attrArray.length; i++) {
                    var value = attrArray[i];
                    if (this.inside && isNormal) {
                        value = -value;
                    }
                    this.attributes[attrName].value[i + attrSize * vertexOffset] = value;
                }
            }
            var len = plane.indices.length;
            for (var i = 0; i < plane.indices.length; i++) {
                this.indices[i + faceOffset] = vertexOffset + plane.indices[this.inside ? (len - i - 1) : i];
            }
            faceOffset += plane.indices.length;
            vertexOffset += plane.vertexCount;
        }

        this.boundingBox = new __WEBPACK_IMPORTED_MODULE_4__math_BoundingBox__["a" /* default */]();
        this.boundingBox.max.set(1, 1, 1);
        this.boundingBox.min.set(-1, -1, -1);
    }
});

function createPlane(pos, widthSegments, heightSegments) {

    planeMatrix.identity();

    var plane = new __WEBPACK_IMPORTED_MODULE_1__Plane__["a" /* default */]({
        widthSegments: widthSegments,
        heightSegments: heightSegments
    });

    switch(pos) {
        case 'px':
            __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].translate(planeMatrix, planeMatrix, __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].POSITIVE_X);
            __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].rotateY(planeMatrix, planeMatrix, Math.PI / 2);
            break;
        case 'nx':
            __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].translate(planeMatrix, planeMatrix, __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].NEGATIVE_X);
            __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].rotateY(planeMatrix, planeMatrix, -Math.PI / 2);
            break;
        case 'py':
            __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].translate(planeMatrix, planeMatrix, __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].POSITIVE_Y);
            __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].rotateX(planeMatrix, planeMatrix, -Math.PI / 2);
            break;
        case 'ny':
            __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].translate(planeMatrix, planeMatrix, __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].NEGATIVE_Y);
            __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].rotateX(planeMatrix, planeMatrix, Math.PI / 2);
            break;
        case 'pz':
            __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].translate(planeMatrix, planeMatrix, __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].POSITIVE_Z);
            break;
        case 'nz':
            __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].translate(planeMatrix, planeMatrix, __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].NEGATIVE_Z);
            __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].rotateY(planeMatrix, planeMatrix, Math.PI);
            break;
    }
    plane.applyTransform(planeMatrix);
    return plane;
}

/* harmony default export */ __webpack_exports__["a"] = (Cube);


/***/ }),
/* 77 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__TextureCube__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__compositor_Pass__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Material__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__plugin_Skybox__ = __webpack_require__(42);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Scene__ = __webpack_require__(36);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__prePass_EnvironmentMap__ = __webpack_require__(62);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__core_vendor__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__texture__ = __webpack_require__(61);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__shader_integrateBRDF_glsl_js__ = __webpack_require__(127);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__shader_prefilter_glsl_js__ = __webpack_require__(128);
// Cubemap prefilter utility
// http://www.unrealengine.com/files/downloads/2013SiggraphPresentationsNotes.pdf
// http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html
















var cubemapUtil = {};

var targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz'];

// TODO Downsample
/**
 * @name clay.util.cubemap.prefilterEnvironmentMap
 * @param  {clay.Renderer} renderer
 * @param  {clay.Texture} envMap
 * @param  {Object} [textureOpts]
 * @param  {number} [textureOpts.width=64]
 * @param  {number} [textureOpts.height=64]
 * @param  {number} [textureOpts.type]
 * @param  {boolean} [textureOpts.encodeRGBM=false]
 * @param  {boolean} [textureOpts.decodeRGBM=false]
 * @param  {clay.Texture2D} [normalDistribution]
 * @param  {clay.Texture2D} [brdfLookup]
 */
cubemapUtil.prefilterEnvironmentMap = function (
    renderer, envMap, textureOpts, normalDistribution, brdfLookup
) {
    // Not create other renderer, it is easy having issue of cross reference of resources like framebuffer
    // PENDING preserveDrawingBuffer?
    if (!brdfLookup || !normalDistribution) {
        normalDistribution = cubemapUtil.generateNormalDistribution();
        brdfLookup = cubemapUtil.integrateBRDF(renderer, normalDistribution);
    }
    textureOpts = textureOpts || {};

    var width = textureOpts.width || 64;
    var height = textureOpts.height || 64;

    var textureType = textureOpts.type || envMap.type;

    // Use same type with given envMap
    var prefilteredCubeMap = new __WEBPACK_IMPORTED_MODULE_1__TextureCube__["a" /* default */]({
        width: width,
        height: height,
        type: textureType,
        flipY: false,
        mipmaps: []
    });

    if (!prefilteredCubeMap.isPowerOfTwo()) {
        console.warn('Width and height must be power of two to enable mipmap.');
    }

    var size = Math.min(width, height);
    var mipmapNum = Math.log(size) / Math.log(2) + 1;

    var prefilterMaterial = new __WEBPACK_IMPORTED_MODULE_5__Material__["a" /* default */]({
        shader: new __WEBPACK_IMPORTED_MODULE_6__Shader__["a" /* default */]({
            vertex: __WEBPACK_IMPORTED_MODULE_6__Shader__["a" /* default */].source('clay.skybox.vertex'),
            fragment: __WEBPACK_IMPORTED_MODULE_13__shader_prefilter_glsl_js__["a" /* default */]
        })
    });
    prefilterMaterial.set('normalDistribution', normalDistribution);

    textureOpts.encodeRGBM && prefilterMaterial.define('fragment', 'RGBM_ENCODE');
    textureOpts.decodeRGBM && prefilterMaterial.define('fragment', 'RGBM_DECODE');

    var dummyScene = new __WEBPACK_IMPORTED_MODULE_8__Scene__["a" /* default */]();
    var skyEnv;

    if (envMap.textureType === 'texture2D') {
        // Convert panorama to cubemap
        var envCubemap = new __WEBPACK_IMPORTED_MODULE_1__TextureCube__["a" /* default */]({
            width: width,
            height: height,
            // FIXME FLOAT type will cause GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT error on iOS
            type: textureType === __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].FLOAT ?
                __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].HALF_FLOAT : textureType
        });
        __WEBPACK_IMPORTED_MODULE_11__texture__["a" /* default */].panoramaToCubeMap(renderer, envMap, envCubemap, {
            // PENDING encodeRGBM so it can be decoded as RGBM
            encodeRGBM: textureOpts.decodeRGBM
        });
        envMap = envCubemap;
    }
    skyEnv = new __WEBPACK_IMPORTED_MODULE_7__plugin_Skybox__["a" /* default */]({
        scene: dummyScene,
        material: prefilterMaterial
    });
    skyEnv.material.set('environmentMap', envMap);

    var envMapPass = new __WEBPACK_IMPORTED_MODULE_9__prePass_EnvironmentMap__["a" /* default */]({
        texture: prefilteredCubeMap
    });

    // Force to be UNSIGNED_BYTE
    if (textureOpts.encodeRGBM) {
        textureType = prefilteredCubeMap.type = __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].UNSIGNED_BYTE;
    }

    var renderTargetTmp = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
        width: width,
        height: height,
        type: textureType
    });
    var frameBuffer = new __WEBPACK_IMPORTED_MODULE_3__FrameBuffer__["a" /* default */]({
        depthBuffer: false
    });
    var ArrayCtor = __WEBPACK_IMPORTED_MODULE_10__core_vendor__["a" /* default */][textureType === __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].UNSIGNED_BYTE ? 'Uint8Array' : 'Float32Array'];
    for (var i = 0; i < mipmapNum; i++) {
        // console.time('prefilter');
        prefilteredCubeMap.mipmaps[i] = {
            pixels: {}
        };
        skyEnv.material.set('roughness', i / (mipmapNum - 1));

        // Tweak fov
        // http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
        var n = renderTargetTmp.width;
        var fov = 2 * Math.atan(n / (n - 0.5)) / Math.PI * 180;

        for (var j = 0; j < targets.length; j++) {
            var pixels = new ArrayCtor(renderTargetTmp.width * renderTargetTmp.height * 4);
            frameBuffer.attach(renderTargetTmp);
            frameBuffer.bind(renderer);

            var camera = envMapPass.getCamera(targets[j]);
            camera.fov = fov;
            renderer.render(dummyScene, camera);
            renderer.gl.readPixels(
                0, 0, renderTargetTmp.width, renderTargetTmp.height,
                __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].RGBA, textureType, pixels
            );

            // var canvas = document.createElement('canvas');
            // var ctx = canvas.getContext('2d');
            // canvas.width = renderTargetTmp.width;
            // canvas.height = renderTargetTmp.height;
            // var imageData = ctx.createImageData(renderTargetTmp.width, renderTargetTmp.height);
            // for (var k = 0; k < pixels.length; k++) {
            //     imageData.data[k] = pixels[k];
            // }
            // ctx.putImageData(imageData, 0, 0);
            // document.body.appendChild(canvas);

            frameBuffer.unbind(renderer);
            prefilteredCubeMap.mipmaps[i].pixels[targets[j]] = pixels;
        }

        renderTargetTmp.width /= 2;
        renderTargetTmp.height /= 2;
        renderTargetTmp.dirty();
        // console.timeEnd('prefilter');
    }

    frameBuffer.dispose(renderer);
    renderTargetTmp.dispose(renderer);
    skyEnv.dispose(renderer);
    // Remove gpu resource allucated in renderer
    normalDistribution.dispose(renderer);

    // renderer.dispose();

    return {
        environmentMap: prefilteredCubeMap,
        brdfLookup: brdfLookup,
        normalDistribution: normalDistribution,
        maxMipmapLevel: mipmapNum
    };
};

cubemapUtil.integrateBRDF = function (renderer, normalDistribution) {
    normalDistribution = normalDistribution || cubemapUtil.generateNormalDistribution();
    var framebuffer = new __WEBPACK_IMPORTED_MODULE_3__FrameBuffer__["a" /* default */]({
        depthBuffer: false
    });
    var pass = new __WEBPACK_IMPORTED_MODULE_4__compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_12__shader_integrateBRDF_glsl_js__["a" /* default */]
    });

    var texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
        width: 512,
        height: 256,
        type: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].HALF_FLOAT,
        wrapS: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].CLAMP_TO_EDGE,
        wrapT: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].CLAMP_TO_EDGE,
        minFilter: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].NEAREST,
        magFilter: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].NEAREST,
        useMipmap: false
    });
    pass.setUniform('normalDistribution', normalDistribution);
    pass.setUniform('viewportSize', [512, 256]);
    pass.attachOutput(texture);
    pass.render(renderer, framebuffer);

    // FIXME Only chrome and firefox can readPixels with float type.
    // framebuffer.bind(renderer);
    // var pixels = new Float32Array(512 * 256 * 4);
    // renderer.gl.readPixels(
    //     0, 0, texture.width, texture.height,
    //     Texture.RGBA, Texture.FLOAT, pixels
    // );
    // texture.pixels = pixels;
    // texture.flipY = false;
    // texture.dirty();
    // framebuffer.unbind(renderer);

    framebuffer.dispose(renderer);

    return texture;
};

cubemapUtil.generateNormalDistribution = function (roughnessLevels, sampleSize) {

    // http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
    // GLSL not support bit operation, use lookup instead
    // V -> i / N, U -> roughness
    var roughnessLevels = roughnessLevels || 256;
    var sampleSize = sampleSize || 1024;

    var normalDistribution = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
        width: roughnessLevels,
        height: sampleSize,
        type: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].FLOAT,
        minFilter: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].NEAREST,
        magFilter: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].NEAREST,
        wrapS: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].CLAMP_TO_EDGE,
        wrapT: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].CLAMP_TO_EDGE,
        useMipmap: false
    });
    var pixels = new Float32Array(sampleSize * roughnessLevels * 4);
    var tmp = [];

    // function sortFunc(a, b) {
    //     return Math.abs(b) - Math.abs(a);
    // }
    for (var j = 0; j < roughnessLevels; j++) {
        var roughness = j / roughnessLevels;
        var a = roughness * roughness;

        for (var i = 0; i < sampleSize; i++) {
            // http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
            // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
            // http://stackoverflow.com/questions/1908492/unsigned-integer-in-javascript
            // http://stackoverflow.com/questions/1822350/what-is-the-javascript-operator-and-how-do-you-use-it
            var y = (i << 16 | i >>> 16) >>> 0;
            y = ((y & 1431655765) << 1 | (y & 2863311530) >>> 1) >>> 0;
            y = ((y & 858993459) << 2 | (y & 3435973836) >>> 2) >>> 0;
            y = ((y & 252645135) << 4 | (y & 4042322160) >>> 4) >>> 0;
            y = (((y & 16711935) << 8 | (y & 4278255360) >>> 8) >>> 0) / 4294967296;

            // CDF
            var cosTheta = Math.sqrt((1 - y) / (1 + (a * a - 1.0) * y));
            tmp[i] = cosTheta;
        }

        for (var i = 0; i < sampleSize; i++) {
            var offset = (i * roughnessLevels + j) * 4;
            var cosTheta = tmp[i];
            var sinTheta = Math.sqrt(1.0 - cosTheta * cosTheta);
            var x = i / sampleSize;
            var phi = 2.0 * Math.PI * x;
            pixels[offset] = sinTheta * Math.cos(phi);
            pixels[offset + 1] = cosTheta;
            pixels[offset + 2] = sinTheta * Math.sin(phi);
            pixels[offset + 3] = 1.0;
        }
    }
    normalDistribution.pixels = pixels;

    return normalDistribution;
};

/* harmony default export */ __webpack_exports__["a"] = (cubemapUtil);


/***/ }),
/* 78 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common__ = __webpack_require__(20);


/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */



/**
 * @class 2x2 Matrix
 * @name mat2
 */

var mat2 = {};

/**
 * Creates a new identity mat2
 *
 * @returns {mat2} a new 2x2 matrix
 */
mat2.create = function() {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](4);
    out[0] = 1;
    out[1] = 0;
    out[2] = 0;
    out[3] = 1;
    return out;
};

/**
 * Creates a new mat2 initialized with values from an existing matrix
 *
 * @param {mat2} a matrix to clone
 * @returns {mat2} a new 2x2 matrix
 */
mat2.clone = function(a) {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](4);
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    return out;
};

/**
 * Copy the values from one mat2 to another
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the source matrix
 * @returns {mat2} out
 */
mat2.copy = function(out, a) {
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    return out;
};

/**
 * Set a mat2 to the identity matrix
 *
 * @param {mat2} out the receiving matrix
 * @returns {mat2} out
 */
mat2.identity = function(out) {
    out[0] = 1;
    out[1] = 0;
    out[2] = 0;
    out[3] = 1;
    return out;
};

/**
 * Transpose the values of a mat2
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the source matrix
 * @returns {mat2} out
 */
mat2.transpose = function(out, a) {
    // If we are transposing ourselves we can skip a few steps but have to cache some values
    if (out === a) {
        var a1 = a[1];
        out[1] = a[2];
        out[2] = a1;
    } else {
        out[0] = a[0];
        out[1] = a[2];
        out[2] = a[1];
        out[3] = a[3];
    }

    return out;
};

/**
 * Inverts a mat2
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the source matrix
 * @returns {mat2} out
 */
mat2.invert = function(out, a) {
    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],

        // Calculate the determinant
        det = a0 * a3 - a2 * a1;

    if (!det) {
        return null;
    }
    det = 1.0 / det;

    out[0] =  a3 * det;
    out[1] = -a1 * det;
    out[2] = -a2 * det;
    out[3] =  a0 * det;

    return out;
};

/**
 * Calculates the adjugate of a mat2
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the source matrix
 * @returns {mat2} out
 */
mat2.adjoint = function(out, a) {
    // Caching this value is nessecary if out == a
    var a0 = a[0];
    out[0] =  a[3];
    out[1] = -a[1];
    out[2] = -a[2];
    out[3] =  a0;

    return out;
};

/**
 * Calculates the determinant of a mat2
 *
 * @param {mat2} a the source matrix
 * @returns {Number} determinant of a
 */
mat2.determinant = function (a) {
    return a[0] * a[3] - a[2] * a[1];
};

/**
 * Multiplies two mat2's
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the first operand
 * @param {mat2} b the second operand
 * @returns {mat2} out
 */
mat2.multiply = function (out, a, b) {
    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
    var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
    out[0] = a0 * b0 + a2 * b1;
    out[1] = a1 * b0 + a3 * b1;
    out[2] = a0 * b2 + a2 * b3;
    out[3] = a1 * b2 + a3 * b3;
    return out;
};

/**
 * Alias for {@link mat2.multiply}
 * @function
 */
mat2.mul = mat2.multiply;

/**
 * Rotates a mat2 by the given angle
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat2} out
 */
mat2.rotate = function (out, a, rad) {
    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
        s = Math.sin(rad),
        c = Math.cos(rad);
    out[0] = a0 *  c + a2 * s;
    out[1] = a1 *  c + a3 * s;
    out[2] = a0 * -s + a2 * c;
    out[3] = a1 * -s + a3 * c;
    return out;
};

/**
 * Scales the mat2 by the dimensions in the given vec2
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the matrix to rotate
 * @param {vec2} v the vec2 to scale the matrix by
 * @returns {mat2} out
 **/
mat2.scale = function(out, a, v) {
    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
        v0 = v[0], v1 = v[1];
    out[0] = a0 * v0;
    out[1] = a1 * v0;
    out[2] = a2 * v1;
    out[3] = a3 * v1;
    return out;
};

/**
 * Returns Frobenius norm of a mat2
 *
 * @param {mat2} a the matrix to calculate Frobenius norm of
 * @returns {Number} Frobenius norm
 */
mat2.frob = function (a) {
    return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2)))
};

/**
 * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix
 * @param {mat2} L the lower triangular matrix
 * @param {mat2} D the diagonal matrix
 * @param {mat2} U the upper triangular matrix
 * @param {mat2} a the input matrix to factorize
 */

mat2.LDU = function (L, D, U, a) {
    L[2] = a[2]/a[0];
    U[0] = a[0];
    U[1] = a[1];
    U[3] = a[3] - L[2] * U[1];
    return [L, D, U];
};


/* harmony default export */ __webpack_exports__["a"] = (mat2);

/***/ }),
/* 79 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common__ = __webpack_require__(20);

/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */



/**
 * @class 2x3 Matrix
 * @name mat2d
 *
 * @description
 * A mat2d contains six elements defined as:
 * <pre>
 * [a, c, tx,
 *  b, d, ty]
 * </pre>
 * This is a short form for the 3x3 matrix:
 * <pre>
 * [a, c, tx,
 *  b, d, ty,
 *  0, 0, 1]
 * </pre>
 * The last row is ignored so the array is shorter and operations are faster.
 */

var mat2d = {};

/**
 * Creates a new identity mat2d
 *
 * @returns {mat2d} a new 2x3 matrix
 */
mat2d.create = function() {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](6);
    out[0] = 1;
    out[1] = 0;
    out[2] = 0;
    out[3] = 1;
    out[4] = 0;
    out[5] = 0;
    return out;
};

/**
 * Creates a new mat2d initialized with values from an existing matrix
 *
 * @param {mat2d} a matrix to clone
 * @returns {mat2d} a new 2x3 matrix
 */
mat2d.clone = function(a) {
    var out = new __WEBPACK_IMPORTED_MODULE_0__common__["a" /* GLMAT_ARRAY_TYPE */](6);
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    out[4] = a[4];
    out[5] = a[5];
    return out;
};

/**
 * Copy the values from one mat2d to another
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the source matrix
 * @returns {mat2d} out
 */
mat2d.copy = function(out, a) {
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    out[4] = a[4];
    out[5] = a[5];
    return out;
};

/**
 * Set a mat2d to the identity matrix
 *
 * @param {mat2d} out the receiving matrix
 * @returns {mat2d} out
 */
mat2d.identity = function(out) {
    out[0] = 1;
    out[1] = 0;
    out[2] = 0;
    out[3] = 1;
    out[4] = 0;
    out[5] = 0;
    return out;
};

/**
 * Inverts a mat2d
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the source matrix
 * @returns {mat2d} out
 */
mat2d.invert = function(out, a) {
    var aa = a[0], ab = a[1], ac = a[2], ad = a[3],
        atx = a[4], aty = a[5];

    var det = aa * ad - ab * ac;
    if(!det){
        return null;
    }
    det = 1.0 / det;

    out[0] = ad * det;
    out[1] = -ab * det;
    out[2] = -ac * det;
    out[3] = aa * det;
    out[4] = (ac * aty - ad * atx) * det;
    out[5] = (ab * atx - aa * aty) * det;
    return out;
};

/**
 * Calculates the determinant of a mat2d
 *
 * @param {mat2d} a the source matrix
 * @returns {Number} determinant of a
 */
mat2d.determinant = function (a) {
    return a[0] * a[3] - a[1] * a[2];
};

/**
 * Multiplies two mat2d's
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the first operand
 * @param {mat2d} b the second operand
 * @returns {mat2d} out
 */
mat2d.multiply = function (out, a, b) {
    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
        b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5];
    out[0] = a0 * b0 + a2 * b1;
    out[1] = a1 * b0 + a3 * b1;
    out[2] = a0 * b2 + a2 * b3;
    out[3] = a1 * b2 + a3 * b3;
    out[4] = a0 * b4 + a2 * b5 + a4;
    out[5] = a1 * b4 + a3 * b5 + a5;
    return out;
};

/**
 * Alias for {@link mat2d.multiply}
 * @function
 */
mat2d.mul = mat2d.multiply;


/**
 * Rotates a mat2d by the given angle
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat2d} out
 */
mat2d.rotate = function (out, a, rad) {
    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
        s = Math.sin(rad),
        c = Math.cos(rad);
    out[0] = a0 *  c + a2 * s;
    out[1] = a1 *  c + a3 * s;
    out[2] = a0 * -s + a2 * c;
    out[3] = a1 * -s + a3 * c;
    out[4] = a4;
    out[5] = a5;
    return out;
};

/**
 * Scales the mat2d by the dimensions in the given vec2
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the matrix to translate
 * @param {vec2} v the vec2 to scale the matrix by
 * @returns {mat2d} out
 **/
mat2d.scale = function(out, a, v) {
    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
        v0 = v[0], v1 = v[1];
    out[0] = a0 * v0;
    out[1] = a1 * v0;
    out[2] = a2 * v1;
    out[3] = a3 * v1;
    out[4] = a4;
    out[5] = a5;
    return out;
};

/**
 * Translates the mat2d by the dimensions in the given vec2
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the matrix to translate
 * @param {vec2} v the vec2 to translate the matrix by
 * @returns {mat2d} out
 **/
mat2d.translate = function(out, a, v) {
    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
        v0 = v[0], v1 = v[1];
    out[0] = a0;
    out[1] = a1;
    out[2] = a2;
    out[3] = a3;
    out[4] = a0 * v0 + a2 * v1 + a4;
    out[5] = a1 * v0 + a3 * v1 + a5;
    return out;
};

/**
 * Returns Frobenius norm of a mat2d
 *
 * @param {mat2d} a the matrix to calculate Frobenius norm of
 * @returns {Number} Frobenius norm
 */
mat2d.frob = function (a) {
    return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + 1))
};


/* harmony default export */ __webpack_exports__["a"] = (mat2d);

/***/ }),
/* 80 */
/***/ (function(module, exports) {

var _default = typeof window !== 'undefined' && (window.requestAnimationFrame && window.requestAnimationFrame.bind(window) || // https://github.com/ecomfe/zrender/issues/189#issuecomment-224919809
window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window) || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame) || function (func) {
  setTimeout(func, 16);
};

module.exports = _default;

/***/ }),
/* 81 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture2D__ = __webpack_require__(5);
/**
 * Texture Atlas for the sprites.
 * It uses zrender for 2d element management and rendering
 * @module echarts-gl/util/ZRTextureAtlasSurface
 */

// TODO Expand.



function ZRTextureAtlasSurfaceNode(zr, offsetX, offsetY, width, height, gap, dpr) {
    this._zr = zr;

    /**
     * Current cursor x
     * @type {number}
     * @private
     */
    this._x = 0;

    /**
     * Current cursor y
     * @type {number}
     */
    this._y = 0;

    this._rowHeight = 0;
    /**
     * width without dpr.
     * @type {number}
     * @private
     */
    this.width = width;

    /**
     * height without dpr.
     * @type {number}
     * @private
     */
    this.height = height;

    /**
     * offsetX without dpr
     * @type {number}
     */
    this.offsetX = offsetX;
    /**
     * offsetY without dpr
     * @type {number}
     */
    this.offsetY = offsetY;

    this.dpr = dpr;

    this.gap = gap;
}

ZRTextureAtlasSurfaceNode.prototype = {

    constructor: ZRTextureAtlasSurfaceNode,

    clear: function () {
        this._x = 0;
        this._y = 0;
        this._rowHeight = 0;
    },

    /**
     * Add shape to atlas
     * @param {module:zrender/graphic/Displayable} shape
     * @param {number} width
     * @param {number} height
     * @return {Array}
     */
    add: function (el, width, height) {
        // FIXME Text element not consider textAlign and textVerticalAlign.

        // TODO, inner text, shadow
        var rect = el.getBoundingRect();

        // FIXME aspect ratio
        if (width == null) {
            width = rect.width;
        }
        if (height == null) {
            height = rect.height;
        }
        width *= this.dpr;
        height *= this.dpr;

        this._fitElement(el, width, height);

        // var aspect = el.scale[1] / el.scale[0];
        // Adjust aspect ratio to make the text more clearly
        // FIXME If height > width, width is useless ?
        // width = height * aspect;
        // el.position[0] *= aspect;
        // el.scale[0] = el.scale[1];

        var x = this._x;
        var y = this._y;

        var canvasWidth = this.width * this.dpr;
        var canvasHeight = this.height * this.dpr;
        var gap = this.gap;

        if (x + width + gap > canvasWidth) {
            // Change a new row
            x = this._x = 0;
            y += this._rowHeight + gap;
            this._y = y;
            // Reset row height
            this._rowHeight = 0;
        }

        this._x += width + gap;

        this._rowHeight = Math.max(this._rowHeight, height);

        if (y + height + gap > canvasHeight) {
            // There is no space anymore
            return null;
        }

        // Shift the el
        el.position[0] += this.offsetX * this.dpr + x;
        el.position[1] += this.offsetY * this.dpr + y;

        this._zr.add(el);

        var coordsOffset = [
            this.offsetX / this.width,
            this.offsetY / this.height
        ];
        var coords = [
            [x / canvasWidth + coordsOffset[0], y / canvasHeight + coordsOffset[1]],
            [(x + width) / canvasWidth + coordsOffset[0], (y + height) / canvasHeight + coordsOffset[1]]
        ];

        return coords;
    },

    /**
     * Fit element size by correct its position and scaling
     * @param {module:zrender/graphic/Displayable} el
     * @param {number} spriteWidth
     * @param {number} spriteHeight
     */
    _fitElement: function (el, spriteWidth, spriteHeight) {
        // TODO, inner text, shadow
        var rect = el.getBoundingRect();

        var scaleX = spriteWidth / rect.width;
        var scaleY = spriteHeight / rect.height;
        el.position = [-rect.x * scaleX, -rect.y * scaleY];
        el.scale = [scaleX, scaleY];
        el.update();
    }
}
/**
 * constructor
 * @alias module:echarts-gl/util/ZRTextureAtlasSurface
 * @param {number} opt.width
 * @param {number} opt.height
 * @param {number} opt.devicePixelRatio
 * @param {number} opt.gap Gap for safe.
 * @param {Function} opt.onupdate
 */
function ZRTextureAtlasSurface (opt) {

    opt = opt || {};
    opt.width = opt.width || 512;
    opt.height = opt.height || 512;
    opt.devicePixelRatio = opt.devicePixelRatio || 1;
    opt.gap = opt.gap == null ? 2 : opt.gap;

    var canvas = document.createElement('canvas');
    canvas.width = opt.width * opt.devicePixelRatio;
    canvas.height = opt.height * opt.devicePixelRatio;

    this._canvas = canvas;

    this._texture = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture2D__["a" /* default */]({
        image: canvas,
        flipY: false
    });

    var self = this;
    /**
     * zrender instance in the Chart
     * @type {zrender~ZRender}
     */
    this._zr = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.zrender.init(canvas);
    var oldRefreshImmediately = this._zr.refreshImmediately;
    this._zr.refreshImmediately = function () {
        oldRefreshImmediately.call(this);
        self._texture.dirty();
        self.onupdate && self.onupdate();
    };

    this._dpr = opt.devicePixelRatio;

    /**
     * Texture coords map for each sprite image
     * @type {Object}
     */
    this._coords = {};

    this.onupdate = opt.onupdate;

    this._gap = opt.gap;

    // Left sub atlas.
    this._textureAtlasNodes = [new ZRTextureAtlasSurfaceNode(
        this._zr, 0, 0, opt.width, opt.height, this._gap, this._dpr
    )];

    this._nodeWidth = opt.width;
    this._nodeHeight = opt.height;

    this._currentNodeIdx = 0;
}

ZRTextureAtlasSurface.prototype = {

    /**
     * Clear the texture atlas
     */
    clear: function () {

        for (var i = 0; i < this._textureAtlasNodes.length; i++) {
            this._textureAtlasNodes[i].clear();
        }

        this._currentNodeIdx = 0;

        this._zr.clear();
        this._coords = {};
    },

    /**
     * @return {number}
     */
    getWidth: function () {
        return this._width;
    },

    /**
     * @return {number}
     */
    getHeight: function () {
        return this._height;
    },

    /**
     * @return {number}
     */
    getTexture: function () {
        return this._texture;
    },

    /**
     * @return {number}
     */
    getDevicePixelRatio: function () {
        return this._dpr;
    },

    getZr: function () {
        return this._zr;
    },

    _getCurrentNode: function () {
        return this._textureAtlasNodes[this._currentNodeIdx];
    },

    _expand: function () {
        this._currentNodeIdx++;
        if (this._textureAtlasNodes[this._currentNodeIdx]) {
            // Use the node created previously.
            return this._textureAtlasNodes[this._currentNodeIdx];
        }

        var maxSize = 4096 / this._dpr;
        var textureAtlasNodes = this._textureAtlasNodes;
        var nodeLen = textureAtlasNodes.length;
        var offsetX = (nodeLen * this._nodeWidth) % maxSize;
        var offsetY = Math.floor(nodeLen * this._nodeWidth / maxSize) * this._nodeHeight;
        if (offsetY >= maxSize) {
            // Failed if image is too large.
            if (true) {
                console.error('Too much labels. Some will be ignored.');
            }
            return;
        }

        var width = (offsetX + this._nodeWidth) * this._dpr;
        var height = (offsetY + this._nodeHeight) * this._dpr;
        try {
            // Resize will error in node.
            this._zr.resize({
                width: width,
                height: height
            });
        }
        catch (e) {
            this._canvas.width = width;
            this._canvas.height = height;
        }

        var newNode = new ZRTextureAtlasSurfaceNode(
            this._zr, offsetX, offsetY, this._nodeWidth, this._nodeHeight, this._gap, this._dpr
        );
        this._textureAtlasNodes.push(newNode);

        return newNode;
    },

    add: function (el, width, height) {
        if (this._coords[el.id]) {
            if (true) {
                console.warn('Element already been add');
            }
            return this._coords[el.id];
        }
        var coords = this._getCurrentNode().add(el, width, height);
        if (!coords) {
            var newNode = this._expand();
            if (!newNode) {
                // To maximum
                return;
            }
            coords = newNode.add(el, width, height);
        }

        this._coords[el.id] = coords;

        return coords;
    },

    /**
     * Get coord scale after texture atlas is expanded.
     * @return {Array.<number>}
     */
    getCoordsScale: function () {
        var dpr = this._dpr;
        return [this._nodeWidth / this._canvas.width * dpr, this._nodeHeight / this._canvas.height * dpr];
    },

    /**
     * Get texture coords of sprite image
     * @param  {string} id Image id
     * @return {Array}
     */
    getCoords: function (id) {
        return this._coords[id];
    }
};

/* harmony default export */ __webpack_exports__["a"] = (ZRTextureAtlasSurface);

/***/ }),
/* 82 */
/***/ (function(module, exports, __webpack_require__) {

var vec2 = __webpack_require__(83);

var matrix = __webpack_require__(84);

/**
 * @module echarts/core/BoundingRect
 */
var v2ApplyTransform = vec2.applyTransform;
var mathMin = Math.min;
var mathMax = Math.max;
/**
 * @alias module:echarts/core/BoundingRect
 */

function BoundingRect(x, y, width, height) {
  if (width < 0) {
    x = x + width;
    width = -width;
  }

  if (height < 0) {
    y = y + height;
    height = -height;
  }
  /**
   * @type {number}
   */


  this.x = x;
  /**
   * @type {number}
   */

  this.y = y;
  /**
   * @type {number}
   */

  this.width = width;
  /**
   * @type {number}
   */

  this.height = height;
}

BoundingRect.prototype = {
  constructor: BoundingRect,

  /**
   * @param {module:echarts/core/BoundingRect} other
   */
  union: function (other) {
    var x = mathMin(other.x, this.x);
    var y = mathMin(other.y, this.y);
    this.width = mathMax(other.x + other.width, this.x + this.width) - x;
    this.height = mathMax(other.y + other.height, this.y + this.height) - y;
    this.x = x;
    this.y = y;
  },

  /**
   * @param {Array.<number>} m
   * @methods
   */
  applyTransform: function () {
    var lt = [];
    var rb = [];
    var lb = [];
    var rt = [];
    return function (m) {
      // In case usage like this
      // el.getBoundingRect().applyTransform(el.transform)
      // And element has no transform
      if (!m) {
        return;
      }

      lt[0] = lb[0] = this.x;
      lt[1] = rt[1] = this.y;
      rb[0] = rt[0] = this.x + this.width;
      rb[1] = lb[1] = this.y + this.height;
      v2ApplyTransform(lt, lt, m);
      v2ApplyTransform(rb, rb, m);
      v2ApplyTransform(lb, lb, m);
      v2ApplyTransform(rt, rt, m);
      this.x = mathMin(lt[0], rb[0], lb[0], rt[0]);
      this.y = mathMin(lt[1], rb[1], lb[1], rt[1]);
      var maxX = mathMax(lt[0], rb[0], lb[0], rt[0]);
      var maxY = mathMax(lt[1], rb[1], lb[1], rt[1]);
      this.width = maxX - this.x;
      this.height = maxY - this.y;
    };
  }(),

  /**
   * Calculate matrix of transforming from self to target rect
   * @param  {module:zrender/core/BoundingRect} b
   * @return {Array.<number>}
   */
  calculateTransform: function (b) {
    var a = this;
    var sx = b.width / a.width;
    var sy = b.height / a.height;
    var m = matrix.create(); // 矩阵右乘

    matrix.translate(m, m, [-a.x, -a.y]);
    matrix.scale(m, m, [sx, sy]);
    matrix.translate(m, m, [b.x, b.y]);
    return m;
  },

  /**
   * @param {(module:echarts/core/BoundingRect|Object)} b
   * @return {boolean}
   */
  intersect: function (b) {
    if (!b) {
      return false;
    }

    if (!(b instanceof BoundingRect)) {
      // Normalize negative width/height.
      b = BoundingRect.create(b);
    }

    var a = this;
    var ax0 = a.x;
    var ax1 = a.x + a.width;
    var ay0 = a.y;
    var ay1 = a.y + a.height;
    var bx0 = b.x;
    var bx1 = b.x + b.width;
    var by0 = b.y;
    var by1 = b.y + b.height;
    return !(ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0);
  },
  contain: function (x, y) {
    var rect = this;
    return x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height;
  },

  /**
   * @return {module:echarts/core/BoundingRect}
   */
  clone: function () {
    return new BoundingRect(this.x, this.y, this.width, this.height);
  },

  /**
   * Copy from another rect
   */
  copy: function (other) {
    this.x = other.x;
    this.y = other.y;
    this.width = other.width;
    this.height = other.height;
  },
  plain: function () {
    return {
      x: this.x,
      y: this.y,
      width: this.width,
      height: this.height
    };
  }
};
/**
 * @param {Object|module:zrender/core/BoundingRect} rect
 * @param {number} rect.x
 * @param {number} rect.y
 * @param {number} rect.width
 * @param {number} rect.height
 * @return {module:zrender/core/BoundingRect}
 */

BoundingRect.create = function (rect) {
  return new BoundingRect(rect.x, rect.y, rect.width, rect.height);
};

var _default = BoundingRect;
module.exports = _default;

/***/ }),
/* 83 */
/***/ (function(module, exports) {

var ArrayCtor = typeof Float32Array === 'undefined' ? Array : Float32Array;
/**
 * 创建一个向量
 * @param {number} [x=0]
 * @param {number} [y=0]
 * @return {Vector2}
 */

function create(x, y) {
  var out = new ArrayCtor(2);

  if (x == null) {
    x = 0;
  }

  if (y == null) {
    y = 0;
  }

  out[0] = x;
  out[1] = y;
  return out;
}
/**
 * 复制向量数据
 * @param {Vector2} out
 * @param {Vector2} v
 * @return {Vector2}
 */


function copy(out, v) {
  out[0] = v[0];
  out[1] = v[1];
  return out;
}
/**
 * 克隆一个向量
 * @param {Vector2} v
 * @return {Vector2}
 */


function clone(v) {
  var out = new ArrayCtor(2);
  out[0] = v[0];
  out[1] = v[1];
  return out;
}
/**
 * 设置向量的两个项
 * @param {Vector2} out
 * @param {number} a
 * @param {number} b
 * @return {Vector2} 结果
 */


function set(out, a, b) {
  out[0] = a;
  out[1] = b;
  return out;
}
/**
 * 向量相加
 * @param {Vector2} out
 * @param {Vector2} v1
 * @param {Vector2} v2
 */


function add(out, v1, v2) {
  out[0] = v1[0] + v2[0];
  out[1] = v1[1] + v2[1];
  return out;
}
/**
 * 向量缩放后相加
 * @param {Vector2} out
 * @param {Vector2} v1
 * @param {Vector2} v2
 * @param {number} a
 */


function scaleAndAdd(out, v1, v2, a) {
  out[0] = v1[0] + v2[0] * a;
  out[1] = v1[1] + v2[1] * a;
  return out;
}
/**
 * 向量相减
 * @param {Vector2} out
 * @param {Vector2} v1
 * @param {Vector2} v2
 */


function sub(out, v1, v2) {
  out[0] = v1[0] - v2[0];
  out[1] = v1[1] - v2[1];
  return out;
}
/**
 * 向量长度
 * @param {Vector2} v
 * @return {number}
 */


function len(v) {
  return Math.sqrt(lenSquare(v));
}

var length = len; // jshint ignore:line

/**
 * 向量长度平方
 * @param {Vector2} v
 * @return {number}
 */

function lenSquare(v) {
  return v[0] * v[0] + v[1] * v[1];
}

var lengthSquare = lenSquare;
/**
 * 向量乘法
 * @param {Vector2} out
 * @param {Vector2} v1
 * @param {Vector2} v2
 */

function mul(out, v1, v2) {
  out[0] = v1[0] * v2[0];
  out[1] = v1[1] * v2[1];
  return out;
}
/**
 * 向量除法
 * @param {Vector2} out
 * @param {Vector2} v1
 * @param {Vector2} v2
 */


function div(out, v1, v2) {
  out[0] = v1[0] / v2[0];
  out[1] = v1[1] / v2[1];
  return out;
}
/**
 * 向量点乘
 * @param {Vector2} v1
 * @param {Vector2} v2
 * @return {number}
 */


function dot(v1, v2) {
  return v1[0] * v2[0] + v1[1] * v2[1];
}
/**
 * 向量缩放
 * @param {Vector2} out
 * @param {Vector2} v
 * @param {number} s
 */


function scale(out, v, s) {
  out[0] = v[0] * s;
  out[1] = v[1] * s;
  return out;
}
/**
 * 向量归一化
 * @param {Vector2} out
 * @param {Vector2} v
 */


function normalize(out, v) {
  var d = len(v);

  if (d === 0) {
    out[0] = 0;
    out[1] = 0;
  } else {
    out[0] = v[0] / d;
    out[1] = v[1] / d;
  }

  return out;
}
/**
 * 计算向量间距离
 * @param {Vector2} v1
 * @param {Vector2} v2
 * @return {number}
 */


function distance(v1, v2) {
  return Math.sqrt((v1[0] - v2[0]) * (v1[0] - v2[0]) + (v1[1] - v2[1]) * (v1[1] - v2[1]));
}

var dist = distance;
/**
 * 向量距离平方
 * @param {Vector2} v1
 * @param {Vector2} v2
 * @return {number}
 */

function distanceSquare(v1, v2) {
  return (v1[0] - v2[0]) * (v1[0] - v2[0]) + (v1[1] - v2[1]) * (v1[1] - v2[1]);
}

var distSquare = distanceSquare;
/**
 * 求负向量
 * @param {Vector2} out
 * @param {Vector2} v
 */

function negate(out, v) {
  out[0] = -v[0];
  out[1] = -v[1];
  return out;
}
/**
 * 插值两个点
 * @param {Vector2} out
 * @param {Vector2} v1
 * @param {Vector2} v2
 * @param {number} t
 */


function lerp(out, v1, v2, t) {
  out[0] = v1[0] + t * (v2[0] - v1[0]);
  out[1] = v1[1] + t * (v2[1] - v1[1]);
  return out;
}
/**
 * 矩阵左乘向量
 * @param {Vector2} out
 * @param {Vector2} v
 * @param {Vector2} m
 */


function applyTransform(out, v, m) {
  var x = v[0];
  var y = v[1];
  out[0] = m[0] * x + m[2] * y + m[4];
  out[1] = m[1] * x + m[3] * y + m[5];
  return out;
}
/**
 * 求两个向量最小值
 * @param  {Vector2} out
 * @param  {Vector2} v1
 * @param  {Vector2} v2
 */


function min(out, v1, v2) {
  out[0] = Math.min(v1[0], v2[0]);
  out[1] = Math.min(v1[1], v2[1]);
  return out;
}
/**
 * 求两个向量最大值
 * @param  {Vector2} out
 * @param  {Vector2} v1
 * @param  {Vector2} v2
 */


function max(out, v1, v2) {
  out[0] = Math.max(v1[0], v2[0]);
  out[1] = Math.max(v1[1], v2[1]);
  return out;
}

exports.create = create;
exports.copy = copy;
exports.clone = clone;
exports.set = set;
exports.add = add;
exports.scaleAndAdd = scaleAndAdd;
exports.sub = sub;
exports.len = len;
exports.length = length;
exports.lenSquare = lenSquare;
exports.lengthSquare = lengthSquare;
exports.mul = mul;
exports.div = div;
exports.dot = dot;
exports.scale = scale;
exports.normalize = normalize;
exports.distance = distance;
exports.dist = dist;
exports.distanceSquare = distanceSquare;
exports.distSquare = distSquare;
exports.negate = negate;
exports.lerp = lerp;
exports.applyTransform = applyTransform;
exports.min = min;
exports.max = max;

/***/ }),
/* 84 */
/***/ (function(module, exports) {

/**
 * 3x2矩阵操作类
 * @exports zrender/tool/matrix
 */
var ArrayCtor = typeof Float32Array === 'undefined' ? Array : Float32Array;
/**
 * Create a identity matrix.
 * @return {Float32Array|Array.<number>}
 */

function create() {
  var out = new ArrayCtor(6);
  identity(out);
  return out;
}
/**
 * 设置矩阵为单位矩阵
 * @param {Float32Array|Array.<number>} out
 */


function identity(out) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  out[4] = 0;
  out[5] = 0;
  return out;
}
/**
 * 复制矩阵
 * @param {Float32Array|Array.<number>} out
 * @param {Float32Array|Array.<number>} m
 */


function copy(out, m) {
  out[0] = m[0];
  out[1] = m[1];
  out[2] = m[2];
  out[3] = m[3];
  out[4] = m[4];
  out[5] = m[5];
  return out;
}
/**
 * 矩阵相乘
 * @param {Float32Array|Array.<number>} out
 * @param {Float32Array|Array.<number>} m1
 * @param {Float32Array|Array.<number>} m2
 */


function mul(out, m1, m2) {
  // Consider matrix.mul(m, m2, m);
  // where out is the same as m2.
  // So use temp variable to escape error.
  var out0 = m1[0] * m2[0] + m1[2] * m2[1];
  var out1 = m1[1] * m2[0] + m1[3] * m2[1];
  var out2 = m1[0] * m2[2] + m1[2] * m2[3];
  var out3 = m1[1] * m2[2] + m1[3] * m2[3];
  var out4 = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];
  var out5 = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];
  out[0] = out0;
  out[1] = out1;
  out[2] = out2;
  out[3] = out3;
  out[4] = out4;
  out[5] = out5;
  return out;
}
/**
 * 平移变换
 * @param {Float32Array|Array.<number>} out
 * @param {Float32Array|Array.<number>} a
 * @param {Float32Array|Array.<number>} v
 */


function translate(out, a, v) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4] + v[0];
  out[5] = a[5] + v[1];
  return out;
}
/**
 * 旋转变换
 * @param {Float32Array|Array.<number>} out
 * @param {Float32Array|Array.<number>} a
 * @param {number} rad
 */


function rotate(out, a, rad) {
  var aa = a[0];
  var ac = a[2];
  var atx = a[4];
  var ab = a[1];
  var ad = a[3];
  var aty = a[5];
  var st = Math.sin(rad);
  var ct = Math.cos(rad);
  out[0] = aa * ct + ab * st;
  out[1] = -aa * st + ab * ct;
  out[2] = ac * ct + ad * st;
  out[3] = -ac * st + ct * ad;
  out[4] = ct * atx + st * aty;
  out[5] = ct * aty - st * atx;
  return out;
}
/**
 * 缩放变换
 * @param {Float32Array|Array.<number>} out
 * @param {Float32Array|Array.<number>} a
 * @param {Float32Array|Array.<number>} v
 */


function scale(out, a, v) {
  var vx = v[0];
  var vy = v[1];
  out[0] = a[0] * vx;
  out[1] = a[1] * vy;
  out[2] = a[2] * vx;
  out[3] = a[3] * vy;
  out[4] = a[4] * vx;
  out[5] = a[5] * vy;
  return out;
}
/**
 * 求逆矩阵
 * @param {Float32Array|Array.<number>} out
 * @param {Float32Array|Array.<number>} a
 */


function invert(out, a) {
  var aa = a[0];
  var ac = a[2];
  var atx = a[4];
  var ab = a[1];
  var ad = a[3];
  var aty = a[5];
  var det = aa * ad - ab * ac;

  if (!det) {
    return null;
  }

  det = 1.0 / det;
  out[0] = ad * det;
  out[1] = -ab * det;
  out[2] = -ac * det;
  out[3] = aa * det;
  out[4] = (ac * aty - ad * atx) * det;
  out[5] = (ab * atx - aa * aty) * det;
  return out;
}
/**
 * Clone a new matrix.
 * @param {Float32Array|Array.<number>} a
 */


function clone(a) {
  var b = create();
  copy(b, a);
  return b;
}

exports.create = create;
exports.identity = identity;
exports.copy = copy;
exports.mul = mul;
exports.translate = translate;
exports.rotate = rotate;
exports.scale = scale;
exports.invert = invert;
exports.clone = clone;

/***/ }),
/* 85 */
/***/ (function(module, exports, __webpack_require__) {

var zrUtil = __webpack_require__(13);

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

function _trim(str) {
  return str.replace(/^\s+/, '').replace(/\s+$/, '');
}
/**
 * Linear mapping a value from domain to range
 * @memberOf module:echarts/util/number
 * @param  {(number|Array.<number>)} val
 * @param  {Array.<number>} domain Domain extent domain[0] can be bigger than domain[1]
 * @param  {Array.<number>} range  Range extent range[0] can be bigger than range[1]
 * @param  {boolean} clamp
 * @return {(number|Array.<number>}
 */


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

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


  if (clamp) {
    if (subDomain > 0) {
      if (val <= domain[0]) {
        return range[0];
      } else if (val >= domain[1]) {
        return range[1];
      }
    } else {
      if (val >= domain[0]) {
        return range[0];
      } else if (val <= domain[1]) {
        return range[1];
      }
    }
  } else {
    if (val === domain[0]) {
      return range[0];
    }

    if (val === domain[1]) {
      return range[1];
    }
  }

  return (val - domain[0]) / subDomain * subRange + range[0];
}
/**
 * Convert a percent string to absolute number.
 * Returns NaN if percent is not a valid string or number
 * @memberOf module:echarts/util/number
 * @param {string|number} percent
 * @param {number} all
 * @return {number}
 */


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

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

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

  if (typeof percent === 'string') {
    if (_trim(percent).match(/%$/)) {
      return parseFloat(percent) / 100 * all;
    }

    return parseFloat(percent);
  }

  return percent == null ? NaN : +percent;
}
/**
 * (1) Fix rounding error of float numbers.
 * (2) Support return string to avoid scientific notation like '3.5e-7'.
 *
 * @param {number} x
 * @param {number} [precision]
 * @param {boolean} [returnStr]
 * @return {number|string}
 */


function round(x, precision, returnStr) {
  if (precision == null) {
    precision = 10;
  } // Avoid range error


  precision = Math.min(Math.max(0, precision), 20);
  x = (+x).toFixed(precision);
  return returnStr ? x : +x;
}

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


function getPrecision(val) {
  val = +val;

  if (isNaN(val)) {
    return 0;
  } // It is much faster than methods converting number to string as follows
  //      var tmp = val.toString();
  //      return tmp.length - 1 - tmp.indexOf('.');
  // especially when precision is low


  var e = 1;
  var count = 0;

  while (Math.round(val * e) / e !== val) {
    e *= 10;
    count++;
  }

  return count;
}
/**
 * @param {string|number} val
 * @return {number}
 */


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

  var eIndex = str.indexOf('e');

  if (eIndex > 0) {
    var precision = +str.slice(eIndex + 1);
    return precision < 0 ? -precision : 0;
  } else {
    var dotIndex = str.indexOf('.');
    return dotIndex < 0 ? 0 : str.length - 1 - dotIndex;
  }
}
/**
 * Minimal dicernible data precisioin according to a single pixel.
 *
 * @param {Array.<number>} dataExtent
 * @param {Array.<number>} pixelExtent
 * @return {number} precision
 */


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

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


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

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

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

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

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

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


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

  return seats[idx] / digits;
} // Number.MAX_SAFE_INTEGER, ie do not support.


var MAX_SAFE_INTEGER = 9007199254740991;
/**
 * To 0 - 2 * PI, considering negative radian.
 * @param {number} radian
 * @return {number}
 */

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


function isRadianAroundZero(val) {
  return val > -RADIAN_EPSILON && val < RADIAN_EPSILON;
}

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

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

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

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


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

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

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

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


function quantity(val) {
  return Math.pow(10, quantityExponent(val));
}

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


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

  var nf;

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

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

  return exponent >= -20 ? +val.toFixed(exponent < 0 ? -exponent : 0) : val;
}
/**
 * Order intervals asc, and split them when overlap.
 * expect(numberUtil.reformIntervals([
 *     {interval: [18, 62], close: [1, 1]},
 *     {interval: [-Infinity, -70], close: [0, 0]},
 *     {interval: [-70, -26], close: [1, 1]},
 *     {interval: [-26, 18], close: [1, 1]},
 *     {interval: [62, 150], close: [1, 1]},
 *     {interval: [106, 150], close: [1, 1]},
 *     {interval: [150, Infinity], close: [0, 0]}
 * ])).toEqual([
 *     {interval: [-Infinity, -70], close: [0, 0]},
 *     {interval: [-70, -26], close: [1, 1]},
 *     {interval: [-26, 18], close: [0, 1]},
 *     {interval: [18, 62], close: [0, 1]},
 *     {interval: [62, 150], close: [0, 1]},
 *     {interval: [150, Infinity], close: [0, 0]}
 * ]);
 * @param {Array.<Object>} list, where `close` mean open or close
 *        of the interval, and Infinity can be used.
 * @return {Array.<Object>} The origin list, which has been reformed.
 */


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

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

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

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

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

  return list;

  function littleThan(a, b, lg) {
    return a.interval[lg] < b.interval[lg] || a.interval[lg] === b.interval[lg] && (a.close[lg] - b.close[lg] === (!lg ? 1 : -1) || !lg && littleThan(a, b, 1));
  }
}
/**
 * parseFloat NaNs numeric-cast false positives (null|true|false|"")
 * ...but misinterprets leading-number strings, particularly hex literals ("0x...")
 * subtraction forces infinities to NaN
 *
 * @param {*} v
 * @return {boolean}
 */


function isNumeric(v) {
  return v - parseFloat(v) >= 0;
}

exports.linearMap = linearMap;
exports.parsePercent = parsePercent;
exports.round = round;
exports.asc = asc;
exports.getPrecision = getPrecision;
exports.getPrecisionSafe = getPrecisionSafe;
exports.getPixelPrecision = getPixelPrecision;
exports.getPercentWithPrecision = getPercentWithPrecision;
exports.MAX_SAFE_INTEGER = MAX_SAFE_INTEGER;
exports.remRadian = remRadian;
exports.isRadianAroundZero = isRadianAroundZero;
exports.parseDate = parseDate;
exports.quantity = quantity;
exports.nice = nice;
exports.reformIntervals = reformIntervals;
exports.isNumeric = isNumeric;

/***/ }),
/* 86 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_util__ = __webpack_require__(23);




var TexturePool = function () {

    this._pool = {};

    this._allocatedTextures = [];
};

TexturePool.prototype = {

    constructor: TexturePool,

    get: function (parameters) {
        var key = generateKey(parameters);
        if (!this._pool.hasOwnProperty(key)) {
            this._pool[key] = [];
        }
        var list = this._pool[key];
        if (!list.length) {
            var texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */](parameters);
            this._allocatedTextures.push(texture);
            return texture;
        }
        return list.pop();
    },

    put: function (texture) {
        var key = generateKey(texture);
        if (!this._pool.hasOwnProperty(key)) {
            this._pool[key] = [];
        }
        var list = this._pool[key];
        list.push(texture);
    },

    clear: function (renderer) {
        for (var i = 0; i < this._allocatedTextures.length; i++) {
            this._allocatedTextures[i].dispose(renderer);
        }
        this._pool = {};
        this._allocatedTextures = [];
    }
};

var defaultParams = {
    width: 512,
    height: 512,
    type: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].UNSIGNED_BYTE,
    format: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].RGBA,
    wrapS: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE,
    wrapT: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE,
    minFilter: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_LINEAR,
    magFilter: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR,
    useMipmap: true,
    anisotropic: 1,
    flipY: true,
    unpackAlignment: 4,
    premultiplyAlpha: false
};

var defaultParamPropList = Object.keys(defaultParams);

function generateKey(parameters) {
    __WEBPACK_IMPORTED_MODULE_2__core_util__["a" /* default */].defaultsWithPropList(parameters, defaultParams, defaultParamPropList);
    fallBack(parameters);

    var key = '';
    for (var i = 0; i < defaultParamPropList.length; i++) {
        var name = defaultParamPropList[i];
        var chunk = parameters[name].toString();
        key += chunk;
    }
    return key;
}

function fallBack(target) {

    var IPOT = isPowerOfTwo(target.width, target.height);

    if (target.format === __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DEPTH_COMPONENT) {
        target.useMipmap = false;
    }

    if (!IPOT || !target.useMipmap) {
        if (target.minFilter == __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST_MIPMAP_NEAREST ||
            target.minFilter == __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST_MIPMAP_LINEAR) {
            target.minFilter = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST;
        } else if (
            target.minFilter == __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_LINEAR ||
            target.minFilter == __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_NEAREST
        ) {
            target.minFilter = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR;
        }
    }
    if (!IPOT) {
        target.wrapS = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE;
        target.wrapT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE;
    }
}

function isPowerOfTwo(width, height) {
    return (width & (width-1)) === 0 &&
            (height & (height-1)) === 0;
}

/* harmony default export */ __webpack_exports__["a"] = (TexturePool);


/***/ }),
/* 87 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.kernel.gaussian_9\nfloat gaussianKernel[9];\ngaussianKernel[0] = 0.07;\ngaussianKernel[1] = 0.09;\ngaussianKernel[2] = 0.12;\ngaussianKernel[3] = 0.14;\ngaussianKernel[4] = 0.16;\ngaussianKernel[5] = 0.14;\ngaussianKernel[6] = 0.12;\ngaussianKernel[7] = 0.09;\ngaussianKernel[8] = 0.07;\n@end\n@export clay.compositor.kernel.gaussian_13\nfloat gaussianKernel[13];\ngaussianKernel[0] = 0.02;\ngaussianKernel[1] = 0.03;\ngaussianKernel[2] = 0.06;\ngaussianKernel[3] = 0.08;\ngaussianKernel[4] = 0.11;\ngaussianKernel[5] = 0.13;\ngaussianKernel[6] = 0.14;\ngaussianKernel[7] = 0.13;\ngaussianKernel[8] = 0.11;\ngaussianKernel[9] = 0.08;\ngaussianKernel[10] = 0.06;\ngaussianKernel[11] = 0.03;\ngaussianKernel[12] = 0.02;\n@end\n@export clay.compositor.gaussian_blur\n#define SHADER_NAME gaussian_blur\nuniform sampler2D texture;varying vec2 v_Texcoord;\nuniform float blurSize : 2.0;\nuniform vec2 textureSize : [512.0, 512.0];\nuniform float blurDir : 0.0;\n@import clay.util.rgbm\n@import clay.util.clamp_sample\nvoid main (void)\n{\n @import clay.compositor.kernel.gaussian_9\n vec2 off = blurSize / textureSize;\n off *= vec2(1.0 - blurDir, blurDir);\n vec4 sum = vec4(0.0);\n float weightAll = 0.0;\n for (int i = 0; i < 9; i++) {\n float w = gaussianKernel[i];\n vec4 texel = decodeHDR(clampSample(texture, v_Texcoord + float(i - 4) * off));\n sum += texel * w;\n weightAll += w;\n }\n gl_FragColor = encodeHDR(sum / max(weightAll, 0.01));\n}\n@end\n");


/***/ }),
/* 88 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("\n@export clay.compositor.lut\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform sampler2D lookup;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n float blueColor = tex.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.g);\n vec4 newColor1 = texture2D(lookup, texPos1);\n vec4 newColor2 = texture2D(lookup, texPos2);\n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n gl_FragColor = vec4(newColor.rgb, tex.w);\n}\n@end");


/***/ }),
/* 89 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.output\n#define OUTPUT_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = decodeHDR(texture2D(texture, v_Texcoord));\n gl_FragColor.rgb = tex.rgb;\n#ifdef OUTPUT_ALPHA\n gl_FragColor.a = tex.a;\n#else\n gl_FragColor.a = 1.0;\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n#ifdef PREMULTIPLY_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n}\n@end");


/***/ }),
/* 90 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.bright\nuniform sampler2D texture;\nuniform float threshold : 1;\nuniform float scale : 1.0;\nuniform vec2 textureSize: [512, 512];\nvarying vec2 v_Texcoord;\nconst vec3 lumWeight = vec3(0.2125, 0.7154, 0.0721);\n@import clay.util.rgbm\nvec4 median(vec4 a, vec4 b, vec4 c)\n{\n return a + b + c - min(min(a, b), c) - max(max(a, b), c);\n}\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(texture, v_Texcoord));\n#ifdef ANTI_FLICKER\n vec3 d = 1.0 / textureSize.xyx * vec3(1.0, 1.0, 0.0);\n vec4 s1 = decodeHDR(texture2D(texture, v_Texcoord - d.xz));\n vec4 s2 = decodeHDR(texture2D(texture, v_Texcoord + d.xz));\n vec4 s3 = decodeHDR(texture2D(texture, v_Texcoord - d.zy));\n vec4 s4 = decodeHDR(texture2D(texture, v_Texcoord + d.zy));\n texel = median(median(texel, s1, s2), s3, s4);\n#endif\n float lum = dot(texel.rgb , lumWeight);\n vec4 color;\n if (lum > threshold && texel.a > 0.0)\n {\n color = vec4(texel.rgb * scale, texel.a * scale);\n }\n else\n {\n color = vec4(0.0);\n }\n gl_FragColor = encodeHDR(color);\n}\n@end\n");


/***/ }),
/* 91 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.downsample\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nfloat brightness(vec3 c)\n{\n return max(max(c.r, c.g), c.b);\n}\n@import clay.util.clamp_sample\nvoid main()\n{\n vec4 d = vec4(-1.0, -1.0, 1.0, 1.0) / textureSize.xyxy;\n#ifdef ANTI_FLICKER\n vec3 s1 = decodeHDR(clampSample(texture, v_Texcoord + d.xy)).rgb;\n vec3 s2 = decodeHDR(clampSample(texture, v_Texcoord + d.zy)).rgb;\n vec3 s3 = decodeHDR(clampSample(texture, v_Texcoord + d.xw)).rgb;\n vec3 s4 = decodeHDR(clampSample(texture, v_Texcoord + d.zw)).rgb;\n float s1w = 1.0 / (brightness(s1) + 1.0);\n float s2w = 1.0 / (brightness(s2) + 1.0);\n float s3w = 1.0 / (brightness(s3) + 1.0);\n float s4w = 1.0 / (brightness(s4) + 1.0);\n float oneDivideSum = 1.0 / (s1w + s2w + s3w + s4w);\n vec4 color = vec4(\n (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * oneDivideSum,\n 1.0\n );\n#else\n vec4 color = decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.xw));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.zw));\n color *= 0.25;\n#endif\n gl_FragColor = encodeHDR(color);\n}\n@end");


/***/ }),
/* 92 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("\n@export clay.compositor.upsample\n#define HIGH_QUALITY\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nuniform float sampleScale: 0.5;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\n@import clay.util.clamp_sample\nvoid main()\n{\n#ifdef HIGH_QUALITY\n vec4 d = vec4(1.0, 1.0, -1.0, 0.0) / textureSize.xyxy * sampleScale;\n vec4 s;\n s = decodeHDR(clampSample(texture, v_Texcoord - d.xy));\n s += decodeHDR(clampSample(texture, v_Texcoord - d.wy)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord - d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zw)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord )) * 4.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xw)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.wy)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n gl_FragColor = encodeHDR(s / 16.0);\n#else\n vec4 d = vec4(-1.0, -1.0, +1.0, +1.0) / textureSize.xyxy;\n vec4 s;\n s = decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xw));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zw));\n gl_FragColor = encodeHDR(s / 4.0);\n#endif\n}\n@end");


/***/ }),
/* 93 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.hdr.composite\n#define TONEMAPPING\nuniform sampler2D texture;\n#ifdef BLOOM_ENABLED\nuniform sampler2D bloom;\n#endif\n#ifdef LENSFLARE_ENABLED\nuniform sampler2D lensflare;\nuniform sampler2D lensdirt;\n#endif\n#ifdef LUM_ENABLED\nuniform sampler2D lum;\n#endif\n#ifdef LUT_ENABLED\nuniform sampler2D lut;\n#endif\n#ifdef COLOR_CORRECTION\nuniform float brightness : 0.0;\nuniform float contrast : 1.0;\nuniform float saturation : 1.0;\n#endif\n#ifdef VIGNETTE\nuniform float vignetteDarkness: 1.0;\nuniform float vignetteOffset: 1.0;\n#endif\nuniform float exposure : 1.0;\nuniform float bloomIntensity : 0.25;\nuniform float lensflareIntensity : 1;\nvarying vec2 v_Texcoord;\n@import clay.util.srgb\nvec3 ACESToneMapping(vec3 color)\n{\n const float A = 2.51;\n const float B = 0.03;\n const float C = 2.43;\n const float D = 0.59;\n const float E = 0.14;\n return (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nfloat eyeAdaption(float fLum)\n{\n return mix(0.2, fLum, 0.5);\n}\n#ifdef LUT_ENABLED\nvec3 lutTransform(vec3 color) {\n float blueColor = color.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);\n vec4 newColor1 = texture2D(lut, texPos1);\n vec4 newColor2 = texture2D(lut, texPos2);\n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n return newColor.rgb;\n}\n#endif\n@import clay.util.rgbm\nvoid main()\n{\n vec4 texel = vec4(0.0);\n vec4 originalTexel = vec4(0.0);\n#ifdef TEXTURE_ENABLED\n texel = decodeHDR(texture2D(texture, v_Texcoord));\n originalTexel = texel;\n#endif\n#ifdef BLOOM_ENABLED\n vec4 bloomTexel = decodeHDR(texture2D(bloom, v_Texcoord));\n texel.rgb += bloomTexel.rgb * bloomIntensity;\n texel.a += bloomTexel.a * bloomIntensity;\n#endif\n#ifdef LENSFLARE_ENABLED\n texel += decodeHDR(texture2D(lensflare, v_Texcoord)) * texture2D(lensdirt, v_Texcoord) * lensflareIntensity;\n#endif\n texel.a = min(texel.a, 1.0);\n#ifdef LUM_ENABLED\n float fLum = texture2D(lum, vec2(0.5, 0.5)).r;\n float adaptedLumDest = 3.0 / (max(0.1, 1.0 + 10.0*eyeAdaption(fLum)));\n float exposureBias = adaptedLumDest * exposure;\n#else\n float exposureBias = exposure;\n#endif\n#ifdef TONEMAPPING\n texel.rgb *= exposureBias;\n texel.rgb = ACESToneMapping(texel.rgb);\n#endif\n texel = linearTosRGB(texel);\n#ifdef LUT_ENABLED\n texel.rgb = lutTransform(clamp(texel.rgb,vec3(0.0),vec3(1.0)));\n#endif\n#ifdef COLOR_CORRECTION\n texel.rgb = clamp(texel.rgb + vec3(brightness), 0.0, 1.0);\n texel.rgb = clamp((texel.rgb - vec3(0.5))*contrast+vec3(0.5), 0.0, 1.0);\n float lum = dot(texel.rgb, vec3(0.2125, 0.7154, 0.0721));\n texel.rgb = mix(vec3(lum), texel.rgb, saturation);\n#endif\n#ifdef VIGNETTE\n vec2 uv = (v_Texcoord - vec2(0.5)) * vec2(vignetteOffset);\n texel.rgb = mix(texel.rgb, vec3(1.0 - vignetteDarkness), dot(uv, uv));\n#endif\n gl_FragColor = encodeHDR(texel);\n#ifdef DEBUG\n #if DEBUG == 1\n gl_FragColor = encodeHDR(decodeHDR(texture2D(texture, v_Texcoord)));\n #elif DEBUG == 2\n gl_FragColor = encodeHDR(decodeHDR(texture2D(bloom, v_Texcoord)) * bloomIntensity);\n #elif DEBUG == 3\n gl_FragColor = encodeHDR(decodeHDR(texture2D(lensflare, v_Texcoord) * lensflareIntensity));\n #endif\n#endif\n if (originalTexel.a <= 0.01 && gl_FragColor.a > 1e-5) {\n gl_FragColor.a = dot(gl_FragColor.rgb, vec3(0.2125, 0.7154, 0.0721));\n }\n#ifdef PREMULTIPLY_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n}\n@end");


/***/ }),
/* 94 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.blend\n#define SHADER_NAME blend\n#ifdef TEXTURE1_ENABLED\nuniform sampler2D texture1;\nuniform float weight1 : 1.0;\n#endif\n#ifdef TEXTURE2_ENABLED\nuniform sampler2D texture2;\nuniform float weight2 : 1.0;\n#endif\n#ifdef TEXTURE3_ENABLED\nuniform sampler2D texture3;\nuniform float weight3 : 1.0;\n#endif\n#ifdef TEXTURE4_ENABLED\nuniform sampler2D texture4;\nuniform float weight4 : 1.0;\n#endif\n#ifdef TEXTURE5_ENABLED\nuniform sampler2D texture5;\nuniform float weight5 : 1.0;\n#endif\n#ifdef TEXTURE6_ENABLED\nuniform sampler2D texture6;\nuniform float weight6 : 1.0;\n#endif\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = vec4(0.0);\n#ifdef TEXTURE1_ENABLED\n tex += decodeHDR(texture2D(texture1, v_Texcoord)) * weight1;\n#endif\n#ifdef TEXTURE2_ENABLED\n tex += decodeHDR(texture2D(texture2, v_Texcoord)) * weight2;\n#endif\n#ifdef TEXTURE3_ENABLED\n tex += decodeHDR(texture2D(texture3, v_Texcoord)) * weight3;\n#endif\n#ifdef TEXTURE4_ENABLED\n tex += decodeHDR(texture2D(texture4, v_Texcoord)) * weight4;\n#endif\n#ifdef TEXTURE5_ENABLED\n tex += decodeHDR(texture2D(texture5, v_Texcoord)) * weight5;\n#endif\n#ifdef TEXTURE6_ENABLED\n tex += decodeHDR(texture2D(texture6, v_Texcoord)) * weight6;\n#endif\n gl_FragColor = encodeHDR(tex);\n}\n@end");


/***/ }),
/* 95 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.fxaa\nuniform sampler2D texture;\nuniform vec4 viewport : VIEWPORT;\nvarying vec2 v_Texcoord;\n#define FXAA_REDUCE_MIN (1.0/128.0)\n#define FXAA_REDUCE_MUL (1.0/8.0)\n#define FXAA_SPAN_MAX 8.0\n@import clay.util.rgbm\nvoid main()\n{\n vec2 resolution = 1.0 / viewport.zw;\n vec3 rgbNW = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ) ).xyz;\n vec3 rgbNE = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ) ).xyz;\n vec3 rgbSW = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ) ).xyz;\n vec3 rgbSE = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ) ).xyz;\n vec4 rgbaM = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution ) );\n vec3 rgbM = rgbaM.xyz;\n float opacity = rgbaM.w;\n vec3 luma = vec3( 0.299, 0.587, 0.114 );\n float lumaNW = dot( rgbNW, luma );\n float lumaNE = dot( rgbNE, luma );\n float lumaSW = dot( rgbSW, luma );\n float lumaSE = dot( rgbSE, luma );\n float lumaM = dot( rgbM, luma );\n float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );\n float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );\n vec2 dir;\n dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );\n float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );\n dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),\n max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\n dir * rcpDirMin)) * resolution;\n vec3 rgbA = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * ( 1.0 / 3.0 - 0.5 ) ) ).xyz;\n rgbA += decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * ( 2.0 / 3.0 - 0.5 ) ) ).xyz;\n rgbA *= 0.5;\n vec3 rgbB = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * -0.5 ) ).xyz;\n rgbB += decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * 0.5 ) ).xyz;\n rgbB *= 0.25;\n rgbB += rgbA * 0.5;\n float lumaB = dot( rgbB, luma );\n if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) )\n {\n gl_FragColor = vec4( rgbA, opacity );\n }\n else {\n gl_FragColor = vec4( rgbB, opacity );\n }\n}\n@end");


/***/ }),
/* 96 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


/* harmony default export */ __webpack_exports__["a"] = ({

    getFilledRegions: function (regions, mapData) {
        var regionsArr = (regions || []).slice();

        var geoJson;
        if (typeof mapData === 'string') {
            mapData = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.getMap(mapData);
            geoJson = mapData && mapData.geoJson;
        }
        else {
            if (mapData && mapData.features) {
                geoJson = mapData;
            }
        }
        if (!geoJson) {
            if (true) {
                console.error('Map ' + mapData + ' not exists. You can download map file on http://echarts.baidu.com/download-map.html');
                if (!geoJson.features) {
                    console.error('Invalid GeoJSON for map3D');
                }
            }
            return [];
        }

        var dataNameMap = {};
        var features = geoJson.features;
        for (var i = 0; i < regionsArr.length; i++) {
            dataNameMap[regionsArr[i].name] = regionsArr[i];
        }

        for (var i = 0; i < features.length; i++) {
            var name = features[i].properties.name;
            if (!dataNameMap[name]) {
                regionsArr.push({
                    name: name
                });
            }
        }

        return regionsArr;
    },

    defaultOption: {
        show: true,

        zlevel: -10,

        // geoJson used by geo3D
        map: '',

        // Layout used for viewport
        left: 0,
        top: 0,
        width: '100%',
        height: '100%',

        boxWidth: 100,
        boxHeight: 10,
        boxDepth: 'auto',

        regionHeight: 3,

        environment: 'auto',

        groundPlane: {
            show: false,
            color: '#aaa'
        },

        shading: 'lambert',

        light: {
            main: {
                alpha: 40,
                beta: 30
            }
        },

        viewControl: {
            alpha: 40,
            beta: 0,
            distance: 100,
            orthographicSize: 60,

            minAlpha: 5,
            minBeta: -80,
            maxBeta: 80
        },

        label: {
            show: false,
            // Distance in 3d space.
            distance: 2,

            textStyle: {
                fontSize: 20,
                color: '#000',
                backgroundColor: 'rgba(255,255,255,0.7)',
                padding: 3,
                borderRadius: 4
            }
        },

        // TODO
        // altitude: {
        //     min: 'auto',
        //     max: 'auto',

        //     height: []
        // },


        // labelLine

        // light
        // postEffect
        // temporalSuperSampling

        itemStyle: {
            color: '#fff',
            borderWidth: 0,
            borderColor: '#333'
        },

        emphasis: {
            itemStyle: {
                // color: '#f94b59'
                color: '#639fc0'
            },
            label: {
                show: true
            }
        }
    }
});

/***/ }),
/* 97 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";

function swap(arr, a, b) {
    var tmp = arr[a];
    arr[a] = arr[b];
    arr[b] = tmp;
}
function partition(arr, pivot, left, right, compare) {
    var storeIndex = left;
    var pivotValue = arr[pivot];

    // put the pivot on the right
    swap(arr, pivot, right);

    // go through the rest
    for(var v = left; v < right; v++) {
        if(compare(arr[v], pivotValue) < 0) {
            swap(arr, v, storeIndex);
            storeIndex++;
        }
    }

    // finally put the pivot in the correct place
    swap(arr, right, storeIndex);

    return storeIndex;
}

function quickSort(array, compare, left, right) {
    if(left < right) {
        var pivot = Math.floor((left + right) / 2);
        var newPivot = partition(array, pivot, left, right, compare);
        quickSort(array, compare, left, newPivot - 1);
        quickSort(array, compare, newPivot + 1, right);
    }
}


// TODO Test.
function ProgressiveQuickSort() {

    // this._pivotList = new LinkedList();
    this._parts = [];
}

ProgressiveQuickSort.prototype.step = function (arr, compare, frame) {

    var len = arr.length;
    if (frame === 0) {
        this._parts = [];
        this._sorted = false;

        // Pick a start pivot;
        var pivot = Math.floor(len / 2);
        this._parts.push({
            pivot: pivot,
            left: 0,
            right: len - 1
        });

        this._currentSortPartIdx = 0;
    }

    if (this._sorted) {
        return;
    }

    var parts = this._parts;
    if (parts.length === 0) {
        this._sorted = true;
        // Already finished.
        return true;
    }
    else if (parts.length < 512) {
        // Sort large parts in about 10 frames.
        for (var i = 0; i < parts.length; i++) {
            // Partition and Modify the pivot index.
            parts[i].pivot = partition(
                arr, parts[i].pivot, parts[i].left, parts[i].right, compare
            );
        }

        var subdividedParts = [];
        for (var i = 0; i < parts.length; i++) {
            // Subdivide left
            var left = parts[i].left;
            var right = parts[i].pivot - 1;
            if (right > left) {
                subdividedParts.push({
                    pivot: Math.floor((right + left) / 2),
                    left: left, right: right
                });
            }
            // Subdivide right
            var left = parts[i].pivot + 1;
            var right = parts[i].right;
            if (right > left) {
                subdividedParts.push({
                    pivot: Math.floor((right + left) / 2),
                    left: left, right: right
                });
            }
        }
        parts = this._parts = subdividedParts;
    }
    else {
        // console.time('sort');
        // Finally quick sort each parts in 10 frames.
        for (var i = 0; i < Math.floor(parts.length / 10); i++) {
            // Sort near parts first.
            var idx = parts.length - 1 - this._currentSortPartIdx;
            quickSort(arr, compare, parts[idx].left, parts[idx].right);
            this._currentSortPartIdx++;

            // Finish sort
            if (this._currentSortPartIdx === parts.length) {
                this._sorted = true;
                return true;
            }
        }
        // console.timeEnd('sort');

    }

    return false;
};

ProgressiveQuickSort.sort = quickSort;

/* harmony default export */ __webpack_exports__["a"] = (ProgressiveQuickSort);

/***/ }),
/* 98 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__geo3D_Geo3D__ = __webpack_require__(99);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout__ = __webpack_require__(47);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_retrieve__ = __webpack_require__(2);






function resizeGeo3D(geo3DModel, api) {
    // Use left/top/width/height
    var boxLayoutOption = geo3DModel.getBoxLayoutParams();

    var viewport = __WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout___default.a.getLayoutRect(boxLayoutOption, {
        width: api.getWidth(),
        height: api.getHeight()
    });

    // Flip Y
    viewport.y = api.getHeight() - viewport.y - viewport.height;

    this.viewGL.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, api.getDevicePixelRatio());

    var geoRect = this.getGeoBoundingRect();
    var aspect = geoRect.width / geoRect.height * (geo3DModel.get('aspectScale') || 0.75);

    var width = geo3DModel.get('boxWidth');
    var depth = geo3DModel.get('boxDepth');
    var height = geo3DModel.get('boxHeight');
    if (height == null) {
        height = 5;
    }
    if (isNaN(width) && isNaN(depth)) {
        // Default to have 100 width
        width = 100;
    }
    if (isNaN(depth)) {
        depth = width / aspect;
    }
    else if (isNaN(width)) {
        width = depth / aspect;
    }

    this.setSize(width, height, depth);

    this.regionHeight = geo3DModel.get('regionHeight');

    if (this.altitudeAxis) {
        this.altitudeAxis.setExtent(0, Math.max(height - this.regionHeight, 0));
    }
}

function updateGeo3D(ecModel, api) {

    var altitudeDataExtent = [Infinity, -Infinity];

    ecModel.eachSeries(function (seriesModel) {
        if (seriesModel.coordinateSystem !== this) {
            return;
        }
        if (seriesModel.type === 'series.map3D') {
            return;
        }
        // Get altitude data extent.
        var data = seriesModel.getData();
        var altDims = seriesModel.coordDimToDataDim('alt');
        var altDim = altDims && altDims[0];
        if (altDim) {
            // TODO altitiude is in coords of lines.
            var dataExtent = data.getDataExtent(altDim, true);
            altitudeDataExtent[0] = Math.min(
                altitudeDataExtent[0], dataExtent[0]
            );
            altitudeDataExtent[1] = Math.max(
                altitudeDataExtent[1], dataExtent[1]
            );
        }
    }, this);
    // Create altitude axis
    if (altitudeDataExtent && isFinite(altitudeDataExtent[1] - altitudeDataExtent[0])) {
        var scale = __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.helper.createScale(
            altitudeDataExtent, {
                type: 'value',
                // PENDING
                min: 'dataMin',
                max: 'dataMax'
            }
        );
        this.altitudeAxis = new __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.Axis('altitude', scale);
        // Resize again
        this.resize(this.model, api);
    }
}


if (true) {
    var mapNotExistsError = function (name) {
        console.error('Map ' + name + ' not exists. You can download map file on http://echarts.baidu.com/download-map.html');
    };
}


var idStart = 0;

var geo3DCreator = {

    dimensions: __WEBPACK_IMPORTED_MODULE_0__geo3D_Geo3D__["a" /* default */].prototype.dimensions,

    create: function (ecModel, api) {

        var geo3DList = [];

        if (!__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.getMap) {
            throw new Error('geo3D component depends on geo component');
        }

        function createGeo3D(componentModel, idx) {

            var geo3D = geo3DCreator.createGeo3D(componentModel);

            // FIXME
            componentModel.__viewGL = componentModel.__viewGL || new __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__["a" /* default */]();

            geo3D.viewGL = componentModel.__viewGL;

            componentModel.coordinateSystem = geo3D;
            geo3D.model = componentModel;

            geo3DList.push(geo3D);

            // Inject resize
            geo3D.resize = resizeGeo3D;
            geo3D.resize(componentModel, api);

            geo3D.update = updateGeo3D;
        }

        ecModel.eachComponent('geo3D', function (geo3DModel, idx) {
            createGeo3D(geo3DModel, idx);
        });

        ecModel.eachSeriesByType('map3D', function (map3DModel, idx) {
            var coordSys = map3DModel.get('coordinateSystem');
            if (coordSys == null) {
                coordSys = 'geo3D';
            }
            if (coordSys === 'geo3D') {
                createGeo3D(map3DModel, idx);
            }
        });

        ecModel.eachSeries(function (seriesModel) {
            if (seriesModel.get('coordinateSystem') === 'geo3D') {
                if (seriesModel.type === 'series.map3D') {
                    return;
                }
                var geo3DModel = seriesModel.getReferringComponents('geo3D')[0];
                if (!geo3DModel) {
                    geo3DModel = ecModel.getComponent('geo3D');
                }

                if (!geo3DModel) {
                    throw new Error('geo "' + __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(
                        seriesModel.get('geo3DIndex'),
                        seriesModel.get('geo3DId'),
                        0
                    ) + '" not found');
                }

                seriesModel.coordinateSystem = geo3DModel.coordinateSystem;
            }
        });

        return geo3DList;
    },

    createGeo3D: function (componentModel) {

        var mapData = componentModel.get('map');
        var name;
        if (typeof mapData === 'string') {
            name = mapData;
            mapData = __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.getMap(mapData);
        }
        else {
            if (mapData && mapData.features) {
                mapData = {
                    geoJson: mapData
                };
            }
        }
        if (true) {
            if (!mapData) {
                mapNotExistsError(mapData);
            }
            if (!mapData.geoJson.features) {
                throw new Error('Invalid GeoJSON for map3D');
            }
        }
        if (name == null) {
            name = 'GEO_ANONYMOUS_' + idStart++;
        }

        return new __WEBPACK_IMPORTED_MODULE_0__geo3D_Geo3D__["a" /* default */](
            name + idStart++, name,
            mapData && mapData.geoJson, mapData && mapData.specialAreas,
            componentModel.get('nameMap')
        );
    }
};

__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.registerCoordinateSystem('geo3D', geo3DCreator);

/* harmony default export */ __webpack_exports__["a"] = (geo3DCreator);

/***/ }),
/* 99 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_coord_geo_fix_textCoord__ = __webpack_require__(205);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_coord_geo_fix_textCoord___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_coord_geo_fix_textCoord__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_coord_geo_fix_geoCoord__ = __webpack_require__(206);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_coord_geo_fix_geoCoord___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_coord_geo_fix_geoCoord__);


var vec3 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__["a" /* default */].vec3;
var mat4 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__["a" /* default */].mat4;



// Geo fix functions
var geoFixFuncs = [__WEBPACK_IMPORTED_MODULE_2_echarts_lib_coord_geo_fix_textCoord___default.a, __WEBPACK_IMPORTED_MODULE_3_echarts_lib_coord_geo_fix_geoCoord___default.a];

function Geo3D(name, map, geoJson, specialAreas, nameMap) {

    this.name = name;

    this.map = map;

    this.regionHeight = 0;

    this.regions = [];

    this._nameCoordMap = {};

    this.loadGeoJson(geoJson, specialAreas, nameMap);

    this.transform = mat4.identity(new Float64Array(16));

    this.invTransform = mat4.identity(new Float64Array(16));

    // Which dimension to extrude. Y or Z
    this.extrudeY = true;

    this.altitudeAxis;
}

Geo3D.prototype = {

    constructor: Geo3D,

    type: 'geo3D',

    dimensions: ['lng', 'lat', 'alt'],

    containPoint: function () {},

    loadGeoJson: function (geoJson, specialAreas, nameMap) {
        var parseGeoJSON = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.parseGeoJSON || __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.parseGeoJson;
        try {
            this.regions = geoJson ? parseGeoJSON(geoJson) : [];
        }
        catch (e) {
            throw 'Invalid geoJson format\n' + e;
        }
        specialAreas = specialAreas || {};
        nameMap = nameMap || {};
        var regions = this.regions;
        var regionsMap = {};
        for (var i = 0; i < regions.length; i++) {
            var regionName = regions[i].name;
            // Try use the alias in nameMap
            regionName = nameMap[regionName] || regionName;
            regions[i].name = regionName;

            regionsMap[regionName] = regions[i];
            // Add geoJson
            this.addGeoCoord(regionName, regions[i].center);

            // Some area like Alaska in USA map needs to be tansformed
            // to look better
            var specialArea = specialAreas[regionName];
            if (specialArea) {
                regions[i].transformTo(
                    specialArea.left, specialArea.top, specialArea.width, specialArea.height
                );
            }
        }

        this._regionsMap = regionsMap;

        this._geoRect = null;

        geoFixFuncs.forEach(function (fixFunc) {
            fixFunc(this);
        }, this);
    },

    getGeoBoundingRect: function () {
        if (this._geoRect) {
            return this._geoRect;
        }
        var rect;

        var regions = this.regions;
        for (var i = 0; i < regions.length; i++) {
            var regionRect = regions[i].getBoundingRect();
            rect = rect || regionRect.clone();
            rect.union(regionRect);
        }
        // FIXME Always return new ?
        return (this._geoRect = rect || new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.BoundingRect(0, 0, 0, 0));
    },

    /**
     * Add geoCoord for indexing by name
     * @param {string} name
     * @param {Array.<number>} geoCoord
     */
    addGeoCoord: function (name, geoCoord) {
        this._nameCoordMap[name] = geoCoord;
    },

    /**
     * @param {string} name
     * @return {module:echarts/coord/geo/Region}
     */
    getRegion: function (name) {
        return this._regionsMap[name];
    },

    getRegionByCoord: function (coord) {
        var regions = this.regions;
        for (var i = 0; i < regions.length; i++) {
            if (regions[i].contain(coord)) {
                return regions[i];
            }
        }
    },

    setSize: function (width, height, depth) {
        this.size = [width, height, depth];

        var rect = this.getGeoBoundingRect();

        var scaleX = width / rect.width;
        var scaleZ = -depth / rect.height;
        var translateX = -width / 2 - rect.x * scaleX;
        var translateZ = depth / 2 - rect.y * scaleZ;

        var position = this.extrudeY ? [translateX, 0, translateZ] : [translateX, translateZ, 0];
        var scale = this.extrudeY ? [scaleX, 1, scaleZ] : [scaleX, scaleZ, 1];

        var m = this.transform;
        mat4.identity(m);
        mat4.translate(m, m, position);
        mat4.scale(m, m, scale);

        mat4.invert(this.invTransform, m);
    },

    dataToPoint: function (data, out) {
        out = out || [];

        var extrudeCoordIndex = this.extrudeY ? 1 : 2;
        var sideCoordIndex = this.extrudeY ? 2 : 1;

        var altitudeVal = data[2];
        // PENDING.
        if (isNaN(altitudeVal)) {
            altitudeVal = 0;
        }
        // lng
        out[0] = data[0];
        // lat
        out[sideCoordIndex] = data[1];

        if (this.altitudeAxis) {
            out[extrudeCoordIndex] = this.altitudeAxis.dataToCoord(altitudeVal);
        }
        else {
            out[extrudeCoordIndex] = 0;
        }
        // PENDING different region height.
        out[extrudeCoordIndex] += this.regionHeight;

        vec3.transformMat4(out, out, this.transform);

        return out;
    },

    pointToData: function (point, out) {
        // TODO
    }
};

/* harmony default export */ __webpack_exports__["a"] = (Geo3D);

/***/ }),
/* 100 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_dep_glmatrix__ = __webpack_require__(6);

var mat4 = __WEBPACK_IMPORTED_MODULE_0_claygl_src_dep_glmatrix__["a" /* default */].mat4;

var TILE_SIZE = 512;
var FOV = 0.6435011087932844;
var PI = Math.PI;

var WORLD_SCALE = 1 / 10;

function MapServiceCoordSys3D() {
    /**
     * Width of mapbox viewport
     */
    this.width = 0;
    /**
     * Height of mapbox viewport
     */
    this.height = 0;

    this.altitudeScale = 1;

    // TODO Change boxHeight won't have animation.
    this.boxHeight = 'auto';

    // Set by mapbox creator
    this.altitudeExtent;

    this.bearing = 0;
    this.pitch = 0;
    this.center = [0, 0];

    this._origin;

    this.zoom = 0;
    this._initialZoom;

    // Some parameters for different map services.
    this.maxPitch = 60;
    this.zoomOffset = 0;
}

MapServiceCoordSys3D.prototype = {

    constructor: MapServiceCoordSys3D,

    dimensions: ['lng', 'lat', 'alt'],

    containPoint: function () {},

    setCameraOption: function (option) {
        this.bearing = option.bearing;
        this.pitch = option.pitch;

        this.center = option.center;
        this.zoom = option.zoom;

        if (!this._origin) {
            this._origin = this.projectOnTileWithScale(this.center, TILE_SIZE);
        }
        if (this._initialZoom == null) {
            this._initialZoom = this.zoom;
        }

        this.updateTransform();
    },

    // https://github.com/mapbox/mapbox-gl-js/blob/master/src/geo/transform.js#L479
    updateTransform: function () {
        if (!this.height) { return; }

        var cameraToCenterDistance = 0.5 / Math.tan(FOV / 2) * this.height * WORLD_SCALE;
        // Convert to radian.
        var pitch = Math.max(Math.min(this.pitch, this.maxPitch), 0) / 180 * Math.PI;

        // Find the distance from the center point [width/2, height/2] to the
        // center top point [width/2, 0] in Z units, using the law of sines.
        // 1 Z unit is equivalent to 1 horizontal px at the center of the map
        // (the distance between[width/2, height/2] and [width/2 + 1, height/2])
        var halfFov = FOV / 2;
        var groundAngle = Math.PI / 2 + pitch;
        var topHalfSurfaceDistance = Math.sin(halfFov) * cameraToCenterDistance / Math.sin(Math.PI - groundAngle - halfFov);

        // Calculate z distance of the farthest fragment that should be rendered.
        var furthestDistance = Math.cos(Math.PI / 2 - pitch) * topHalfSurfaceDistance + cameraToCenterDistance;
        // Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance`
        var farZ = furthestDistance * 1.1;
        // Forced to be 1000
        if (this.pitch > 50) {
            farZ = 1000;
        }

        // matrix for conversion from location to GL coordinates (-1 .. 1)
        var m = [];
        mat4.perspective(m, FOV, this.width / this.height, 1, farZ);
        this.viewGL.camera.projectionMatrix.setArray(m);
        this.viewGL.camera.decomposeProjectionMatrix();

        var m = mat4.identity([]);
        var pt = this.dataToPoint(this.center);
        // Inverse
        mat4.scale(m, m, [1, -1, 1]);
        // Translate to altitude
        mat4.translate(m, m, [0, 0, -cameraToCenterDistance]);
        mat4.rotateX(m, m, pitch);
        mat4.rotateZ(m, m, -this.bearing / 180 * Math.PI);
        // Translate to center.
        mat4.translate(m, m, [-pt[0] * this.getScale() * WORLD_SCALE, -pt[1] * this.getScale() * WORLD_SCALE, 0]);

        this.viewGL.camera.viewMatrix.array = m;
        var invertM = [];
        mat4.invert(invertM, m);
        this.viewGL.camera.worldTransform.array = invertM;
        this.viewGL.camera.decomposeWorldTransform();

        // scale vertically to meters per pixel (inverse of ground resolution):
        // worldSize / (circumferenceOfEarth * cos(lat * π / 180))
        var worldSize = TILE_SIZE * this.getScale();
        var verticalScale;

        if (this.altitudeExtent && !isNaN(this.boxHeight)) {
            var range = this.altitudeExtent[1] - this.altitudeExtent[0];
            verticalScale = this.boxHeight / range * this.getScale() / Math.pow(2, this._initialZoom - this.zoomOffset);
        }
        else {
            verticalScale = worldSize / (2 * Math.PI * 6378000 * Math.abs(Math.cos(this.center[1] * (Math.PI / 180))))
                * this.altitudeScale * WORLD_SCALE;
        }
        // Include scale to avoid relayout when zooming
        // FIXME Camera scale may have problem in shadow
        this.viewGL.rootNode.scale.set(
            this.getScale() * WORLD_SCALE, this.getScale() * WORLD_SCALE, verticalScale
        );
    },

    getScale: function () {
        return Math.pow(2, this.zoom - this.zoomOffset);
    },

    projectOnTile: function (data, out) {
        return this.projectOnTileWithScale(data, this.getScale() * TILE_SIZE, out);
    },

    projectOnTileWithScale: function (data, scale, out) {
        var lng = data[0];
        var lat = data[1];
        var lambda2 = lng * PI / 180;
        var phi2 = lat * PI / 180;
        var x = scale * (lambda2 + PI) / (2 * PI);
        var y = scale * (PI - Math.log(Math.tan(PI / 4 + phi2 * 0.5))) / (2 * PI);
        out = out || [];
        out[0] = x;
        out[1] = y;
        return out;
    },

    unprojectFromTile: function (point, out) {
        return this.unprojectOnTileWithScale(point, this.getScale() * TILE_SIZE, out);
    },

    unprojectOnTileWithScale: function (point, scale, out) {
        var x = point[0];
        var y = point[1];
        var lambda2 = (x / scale) * (2 * PI) - PI;
        var phi2 = 2 * (Math.atan(Math.exp(PI - (y / scale) * (2 * PI))) - PI / 4);
        out = out || [];
        out[0] = lambda2 * 180 / PI;
        out[1] = phi2 * 180 / PI;
        return out;
    },

    dataToPoint: function (data, out) {
        out = this.projectOnTileWithScale(data, TILE_SIZE, out);
        // Add a origin to avoid precision issue in WebGL.
        out[0] -= this._origin[0];
        out[1] -= this._origin[1];
        // PENDING
        out[2] = !isNaN(data[2]) ? data[2] : 0;
        if (!isNaN(data[2])) {
            out[2] = data[2];
            if (this.altitudeExtent) {
                out[2] -= this.altitudeExtent[0];
            }
        }
        return out;
    }
};

/* harmony default export */ __webpack_exports__["a"] = (MapServiceCoordSys3D);

/***/ }),
/* 101 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_ViewGL__ = __webpack_require__(22);




/* harmony default export */ __webpack_exports__["a"] = (function (serviceComponentType, ServiceCtor, afterCreate) {

    function resizeMapService3D(mapService3DModel, api) {
        var width = api.getWidth();
        var height = api.getHeight();
        var dpr = api.getDevicePixelRatio();
        this.viewGL.setViewport(0, 0, width, height, dpr);

        this.width = width;
        this.height = height;

        this.altitudeScale = mapService3DModel.get('altitudeScale');

        this.boxHeight = mapService3DModel.get('boxHeight');
        // this.updateTransform();
    }


    function updateService3D(ecModel, api) {

        if (this.model.get('boxHeight') === 'auto') {
            return;
        }

        var altitudeDataExtent = [Infinity, -Infinity]

        ecModel.eachSeries(function (seriesModel) {
            if (seriesModel.coordinateSystem !== this) {
                return;
            }

            // Get altitude data extent.
            var data = seriesModel.getData();
            var altDim = seriesModel.coordDimToDataDim('alt')[0];
            if (altDim) {
                // TODO altitiude is in coords of lines.
                var dataExtent = data.getDataExtent(altDim, true);
                altitudeDataExtent[0] = Math.min(
                    altitudeDataExtent[0], dataExtent[0]
                );
                altitudeDataExtent[1] = Math.max(
                    altitudeDataExtent[1], dataExtent[1]
                );
            }
        }, this);
        if (altitudeDataExtent && isFinite(altitudeDataExtent[1] - altitudeDataExtent[0])) {
            this.altitudeExtent = altitudeDataExtent;
        }
    }

    return {


        dimensions: ServiceCtor.prototype.dimensions,

        create: function (ecModel, api) {
            var mapService3DList = [];

            ecModel.eachComponent(serviceComponentType, function (mapService3DModel) {
                var viewGL = mapService3DModel.__viewGL;
                if (!viewGL) {
                    viewGL = mapService3DModel.__viewGL = new __WEBPACK_IMPORTED_MODULE_2__core_ViewGL__["a" /* default */]();
                    viewGL.setRootNode(new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node());
                }

                var mapService3DCoordSys = new ServiceCtor();
                mapService3DCoordSys.viewGL = mapService3DModel.__viewGL;
                // Inject resize
                mapService3DCoordSys.resize = resizeMapService3D;
                mapService3DCoordSys.resize(mapService3DModel, api);

                mapService3DList.push(mapService3DCoordSys);

                mapService3DModel.coordinateSystem = mapService3DCoordSys;
                mapService3DCoordSys.model = mapService3DModel;

                mapService3DCoordSys.update = updateService3D;
            });

            ecModel.eachSeries(function (seriesModel) {
                if (seriesModel.get('coordinateSystem') === serviceComponentType) {
                    var mapService3DModel = seriesModel.getReferringComponents(serviceComponentType)[0];
                    if (!mapService3DModel) {
                        mapService3DModel = ecModel.getComponent(serviceComponentType);
                    }

                    if (!mapService3DModel) {
                        throw new Error(serviceComponentType + ' "' + __WEBPACK_IMPORTED_MODULE_0__util_retrieve__["a" /* default */].firstNotNull(
                            seriesModel.get(serviceComponentType + 'Index'),
                            seriesModel.get(serviceComponentType + 'Id'),
                            0
                        ) + '" not found');
                    }

                    seriesModel.coordinateSystem = mapService3DModel.coordinateSystem;
                }
            });

            afterCreate && afterCreate(mapService3DList, ecModel, api);

            return mapService3DList;
        }
    };
});


/***/ }),
/* 102 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("\n@export ecgl.displayShadow.vertex\n\n@import ecgl.common.transformUniforms\n\n@import ecgl.common.uv.header\n\n@import ecgl.common.attributes\n\nvarying vec3 v_WorldPosition;\n\nvarying vec3 v_Normal;\n\nvoid main()\n{\n @import ecgl.common.uv.main\n v_Normal = normalize((worldInverseTranspose * vec4(normal, 0.0)).xyz);\n\n v_WorldPosition = (world * vec4(position, 1.0)).xyz;\n gl_Position = worldViewProjection * vec4(position, 1.0);\n}\n\n@end\n\n\n@export ecgl.displayShadow.fragment\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform float roughness: 0.2;\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n\n@import ecgl.common.ssaoMap.header\n\n@import clay.plugin.compute_shadow_map\n\nvoid main()\n{\n float shadow = 1.0;\n\n @import ecgl.common.ssaoMap.main\n\n#if defined(DIRECTIONAL_LIGHT_COUNT) && defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n for (int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++) {\n shadow = min(shadow, shadowContribsDir[i] * 0.5 + 0.5);\n }\n#endif\n\n shadow *= 0.5 + ao * 0.5;\n shadow = clamp(shadow, 0.0, 1.0);\n\n gl_FragColor = vec4(vec3(0.0), 1.0 - shadow);\n}\n\n@end");


/***/ }),
/* 103 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_zrender_lib_core_matrix__ = __webpack_require__(84);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_zrender_lib_core_matrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_zrender_lib_core_matrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_vector__ = __webpack_require__(83);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_vector___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_vector__);




function GLViewHelper(viewGL) {
    this.viewGL = viewGL;
}

GLViewHelper.prototype.reset = function (seriesModel, api) {
    this._updateCamera(api.getWidth(), api.getHeight(), api.getDevicePixelRatio());
    this._viewTransform = __WEBPACK_IMPORTED_MODULE_0_zrender_lib_core_matrix___default.a.create();
    this.updateTransform(seriesModel, api);
};

GLViewHelper.prototype.updateTransform = function (seriesModel, api) {
    var coordinateSystem = seriesModel.coordinateSystem;

    if (coordinateSystem.getRoamTransform) {

        __WEBPACK_IMPORTED_MODULE_0_zrender_lib_core_matrix___default.a.invert(this._viewTransform, coordinateSystem.getRoamTransform());

        this._setCameraTransform(this._viewTransform);

        api.getZr().refresh();
    }
};

// Reimplement the dataToPoint of coordinate system.
// Remove the effect of pan/zoom transform
GLViewHelper.prototype.dataToPoint = function (coordSys, data, pt) {
    pt = coordSys.dataToPoint(data, null, pt);
    var viewTransform = this._viewTransform;
    if (viewTransform) {
        __WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_vector___default.a.applyTransform(pt, pt, viewTransform);
    }
};

/**
 * Remove transform info in point.
 */
GLViewHelper.prototype.removeTransformInPoint = function (pt) {
    if (this._viewTransform) {
        __WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_vector___default.a.applyTransform(pt, pt, this._viewTransform);
    }
    return pt;
};

/**
 * Return number
 */
GLViewHelper.prototype.getZoom = function () {
    if (this._viewTransform) {
        var m = this._viewTransform;
        return 1 / Math.max(
            Math.sqrt(m[0] * m[0] + m[1] * m[1]),
            Math.sqrt(m[2] * m[2] + m[3] * m[3])
        );
    }
    return 1;
};

GLViewHelper.prototype._setCameraTransform = function (m) {
    var camera = this.viewGL.camera;
    camera.position.set(m[4], m[5], 0);
    camera.scale.set(
        Math.sqrt(m[0] * m[0] + m[1] * m[1]),
        Math.sqrt(m[2] * m[2] + m[3] * m[3]),
        1
    );
};

GLViewHelper.prototype._updateCamera = function (width, height, dpr) {
    // TODO, left, top, right, bottom
    this.viewGL.setViewport(0, 0, width, height, dpr);
    var camera = this.viewGL.camera;
    camera.left = camera.top = 0;
    camera.bottom = height;
    camera.right = width;
    camera.near = 0;
    camera.far = 100;
};

/* harmony default export */ __webpack_exports__["a"] = (GLViewHelper);

/***/ }),
/* 104 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(global) {/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// (1) The code `if (__DEV__) ...` can be removed by build tool.
// (2) If intend to use `__DEV__`, this module should be imported. Use a global
// variable `__DEV__` may cause that miss the declaration (see #6535), or the
// declaration is behind of the using position (for example in `Model.extent`,
// And tools like rollup can not analysis the dependency if not import).
var dev; // In browser

if (typeof window !== 'undefined') {
  dev = window.__DEV__;
} // In node
else if (typeof global !== 'undefined') {
    dev = global.__DEV__;
  }

if (typeof dev === 'undefined') {
  dev = true;
}

var __DEV__ = dev;
exports.__DEV__ = __DEV__;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(68)))

/***/ }),
/* 105 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__ = __webpack_require__(38);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__ = __webpack_require__(6);
/**
 * Lines geometry
 * Use screen space projected lines lineWidth > MAX_LINE_WIDTH
 * https://mattdesl.svbtle.com/drawing-lines-is-hard
 * @module echarts-gl/util/geometry/LinesGeometry
 * @author Yi Shen(http://github.com/pissang)
 */





var vec2 = __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__["a" /* default */].vec2;

// var CURVE_RECURSION_LIMIT = 8;
// var CURVE_COLLINEAR_EPSILON = 40;

var sampleLinePoints = [[0, 0], [1, 1]];
/**
 * @constructor
 * @alias module:echarts-gl/util/geometry/LinesGeometry
 * @extends clay.Geometry
 */

var LinesGeometry = __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].extend(function () {
    return {

        segmentScale: 4,

        dynamic: true,
        /**
         * Need to use mesh to expand lines if lineWidth > MAX_LINE_WIDTH
         */
        useNativeLine: true,

        attributes: {
            position: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('position', 'float', 2, 'POSITION'),
            normal: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('normal', 'float', 2),
            offset: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('offset', 'float', 1),
            color: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('color', 'float', 4, 'COLOR')
        }
    };
},
/** @lends module: echarts-gl/util/geometry/LinesGeometry.prototype */
{

    /**
     * Reset offset
     */
    resetOffset: function () {
        this._vertexOffset = 0;
        this._faceOffset = 0;

        this._itemVertexOffsets = [];
    },

    /**
     * @param {number} nVertex
     */
    setVertexCount: function (nVertex) {
        var attributes = this.attributes;
        if (this.vertexCount !== nVertex) {
            attributes.position.init(nVertex);
            attributes.color.init(nVertex);

            if (!this.useNativeLine) {
                attributes.offset.init(nVertex);
                attributes.normal.init(nVertex);
            }

            if (nVertex > 0xffff) {
                if (this.indices instanceof Uint16Array) {
                    this.indices = new Uint32Array(this.indices);
                }
            }
            else {
                if (this.indices instanceof Uint32Array) {
                    this.indices = new Uint16Array(this.indices);
                }
            }
        }
    },

    /**
     * @param {number} nTriangle
     */
    setTriangleCount: function (nTriangle) {
        if (this.triangleCount !== nTriangle) {
            if (nTriangle === 0) {
                this.indices = null;
            }
            else {
                this.indices = this.vertexCount > 0xffff ? new Uint32Array(nTriangle * 3) : new Uint16Array(nTriangle * 3);
            }
        }
    },

    _getCubicCurveApproxStep: function (p0, p1, p2, p3) {
        var len = vec2.dist(p0, p1) + vec2.dist(p2, p1) + vec2.dist(p3, p2);
        var step = 1 / (len + 1) * this.segmentScale;
        return step;
    },

    /**
     * Get vertex count of cubic curve
     * @param {Array.<number>} p0
     * @param {Array.<number>} p1
     * @param {Array.<number>} p2
     * @param {Array.<number>} p3
     * @return number
     */
    getCubicCurveVertexCount: function (p0, p1, p2, p3) {
        var step = this._getCubicCurveApproxStep(p0, p1, p2, p3);
        var segCount = Math.ceil(1 / step);
        if (!this.useNativeLine) {
            return segCount * 2 + 2;
        }
        else {
            return segCount * 2;
        }
    },

    /**
     * Get face count of cubic curve
     * @param {Array.<number>} p0
     * @param {Array.<number>} p1
     * @param {Array.<number>} p2
     * @param {Array.<number>} p3
     * @return number
     */
    getCubicCurveTriangleCount: function (p0, p1, p2, p3) {
        var step = this._getCubicCurveApproxStep(p0, p1, p2, p3);
        var segCount = Math.ceil(1 / step);
        if (!this.useNativeLine) {
            return segCount * 2;
        }
        else {
            return 0;
        }
    },

    /**
     * Get vertex count of line
     * @return {number}
     */
    getLineVertexCount: function () {
        return this.getPolylineVertexCount(sampleLinePoints);
    },

    /**
     * Get face count of line
     * @return {number}
     */
    getLineTriangleCount: function () {
        return this.getPolylineTriangleCount(sampleLinePoints);
    },

    /**
     * Get how many vertices will polyline take.
     * @type {number|Array} points Can be a 1d/2d list of points, or a number of points amount.
     * @return {number}
     */
    getPolylineVertexCount: function (points) {
        var pointsLen;
        if (typeof points === 'number') {
            pointsLen = points;
        }
        else {
            var is2DArray = typeof points[0] !== 'number';
            pointsLen = is2DArray ? points.length : (points.length / 2);
        }
        return !this.useNativeLine ? ((pointsLen - 1) * 2 + 2) : (pointsLen - 1) * 2;
    },

    /**
     * Get how many triangles will polyline take.
     * @type {number|Array} points Can be a 1d/2d list of points, or a number of points amount.
     * @return {number}
     */
    getPolylineTriangleCount: function (points) {
        var pointsLen;
        if (typeof points === 'number') {
            pointsLen = points;
        }
        else {
            var is2DArray = typeof points[0] !== 'number';
            pointsLen = is2DArray ? points.length : (points.length / 2);
        }
        return !this.useNativeLine ? (pointsLen - 1) * 2 : 0;
    },

    /**
     * Add a cubic curve
     * @param {Array.<number>} p0
     * @param {Array.<number>} p1
     * @param {Array.<number>} p2
     * @param {Array.<number>} p3
     * @param {Array.<number>} color
     * @param {number} [lineWidth=1]
     */
    addCubicCurve: function (p0, p1, p2, p3, color, lineWidth) {
        if (lineWidth == null) {
            lineWidth = 1;
        }
        // incremental interpolation
        // http://antigrain.com/research/bezier_interpolation/index.html#PAGE_BEZIER_INTERPOLATION
        var x0 = p0[0], y0 = p0[1];
        var x1 = p1[0], y1 = p1[1];
        var x2 = p2[0], y2 = p2[1];
        var x3 = p3[0], y3 = p3[1];

        var step = this._getCubicCurveApproxStep(p0, p1, p2, p3);

        var step2 = step * step;
        var step3 = step2 * step;

        var pre1 = 3.0 * step;
        var pre2 = 3.0 * step2;
        var pre4 = 6.0 * step2;
        var pre5 = 6.0 * step3;

        var tmp1x = x0 - x1 * 2.0 + x2;
        var tmp1y = y0 - y1 * 2.0 + y2;

        var tmp2x = (x1 - x2) * 3.0 - x0 + x3;
        var tmp2y = (y1 - y2) * 3.0 - y0 + y3;

        var fx = x0;
        var fy = y0;

        var dfx = (x1 - x0) * pre1 + tmp1x * pre2 + tmp2x * step3;
        var dfy = (y1 - y0) * pre1 + tmp1y * pre2 + tmp2y * step3;

        var ddfx = tmp1x * pre4 + tmp2x * pre5;
        var ddfy = tmp1y * pre4 + tmp2y * pre5;

        var dddfx = tmp2x * pre5;
        var dddfy = tmp2y * pre5;

        var t = 0;

        var k = 0;
        var segCount = Math.ceil(1 / step);

        var points = new Float32Array((segCount + 1) * 3);
        var points = [];
        var offset = 0;
        for (var k = 0; k < segCount + 1; k++) {
            points[offset++] = fx;
            points[offset++] = fy;

            fx += dfx; fy += dfy;
            dfx += ddfx; dfy += ddfy;
            ddfx += dddfx; ddfy += dddfy;
            t += step;

            if (t > 1) {
                fx = dfx > 0 ? Math.min(fx, x3) : Math.max(fx, x3);
                fy = dfy > 0 ? Math.min(fy, y3) : Math.max(fy, y3);
            }
        }

        this.addPolyline(points, color, lineWidth);
    },

    /**
     * Add a straight line
     * @param {Array.<number>} p0
     * @param {Array.<number>} p1
     * @param {Array.<number>} color
     * @param {number} [lineWidth=1]
     */
    addLine: function (p0, p1, color, lineWidth) {
        this.addPolyline([p0, p1], color, lineWidth);
    },

    /**
     * Add a straight line
     * @param {Array.<Array> | Array.<number>} points
     * @param {Array.<number> | Array.<Array>} color
     * @param {number} [lineWidth=1]
     * @param {number} [arrayOffset=0]
     * @param {number} [pointsCount] Default to be amount of points in the first argument
     */
    addPolyline: (function () {
        var dirA = vec2.create();
        var dirB = vec2.create();
        var normal = vec2.create();
        var tangent = vec2.create();
        var point = [], nextPoint = [], prevPoint = [];
        return function (points, color, lineWidth, arrayOffset, pointsCount) {
            if (!points.length) {
                return;
            }
            var is2DArray = typeof points[0] !== 'number';
            if (pointsCount == null) {
                pointsCount = is2DArray ? points.length : points.length / 2;
            }
            if (pointsCount < 2) {
                return;
            }
            if (arrayOffset == null) {
                arrayOffset = 0;
            }
            if (lineWidth == null) {
                lineWidth = 1;
            }

            this._itemVertexOffsets.push(this._vertexOffset);

            var notSharingColor = is2DArray
                ? typeof color[0] !== 'number'
                : color.length / 4 === pointsCount;

            var positionAttr = this.attributes.position;
            var colorAttr = this.attributes.color;
            var offsetAttr = this.attributes.offset;
            var normalAttr = this.attributes.normal;
            var indices = this.indices;

            var vertexOffset = this._vertexOffset;
            var pointColor;
            for (var k = 0; k < pointsCount; k++) {
                if (is2DArray) {
                    point = points[k + arrayOffset];
                    if (notSharingColor) {
                        pointColor = color[k + arrayOffset];
                    }
                    else {
                        pointColor = color;
                    }
                }
                else {
                    var k2 = k * 2 + arrayOffset;
                    point = point || [];
                    point[0] = points[k2];
                    point[1] = points[k2 + 1];

                    if (notSharingColor) {
                        var k4 = k * 4 + arrayOffset;
                        pointColor = pointColor || [];
                        pointColor[0] = color[k4];
                        pointColor[1] = color[k4 + 1];
                        pointColor[2] = color[k4 + 2];
                        pointColor[3] = color[k4 + 3];
                    }
                    else {
                        pointColor = color;
                    }
                }
                if (!this.useNativeLine) {
                    var offset;
                    if (k < pointsCount - 1) {
                        if (is2DArray) {
                            vec2.copy(nextPoint, points[k + 1]);
                        }
                        else {
                            var k2 = (k + 1) * 2 + arrayOffset;
                            nextPoint = nextPoint || [];
                            nextPoint[0] = points[k2];
                            nextPoint[1] = points[k2 + 1];
                        }
                        // TODO In case dir is (0, 0)
                        // TODO miterLimit
                        if (k > 0) {
                            vec2.sub(dirA, point, prevPoint);
                            vec2.sub(dirB, nextPoint, point);
                            vec2.normalize(dirA, dirA);
                            vec2.normalize(dirB, dirB);
                            vec2.add(tangent, dirA, dirB);
                            vec2.normalize(tangent, tangent);
                            var miter = lineWidth / 2 * Math.min(1 / vec2.dot(dirA, tangent), 2);
                            normal[0] = -tangent[1];
                            normal[1] = tangent[0];

                            offset = miter;
                        }
                        else {
                            vec2.sub(dirA, nextPoint, point);
                            vec2.normalize(dirA, dirA);

                            normal[0] = -dirA[1];
                            normal[1] = dirA[0];

                            offset = lineWidth / 2;
                        }

                    }
                    else {
                        vec2.sub(dirA, point, prevPoint);
                        vec2.normalize(dirA, dirA);

                        normal[0] = -dirA[1];
                        normal[1] = dirA[0];

                        offset = lineWidth / 2;
                    }
                    normalAttr.set(vertexOffset, normal);
                    normalAttr.set(vertexOffset + 1, normal);
                    offsetAttr.set(vertexOffset, offset);
                    offsetAttr.set(vertexOffset + 1, -offset);

                    vec2.copy(prevPoint, point);

                    positionAttr.set(vertexOffset, point);
                    positionAttr.set(vertexOffset + 1, point);

                    colorAttr.set(vertexOffset, pointColor);
                    colorAttr.set(vertexOffset + 1, pointColor);

                    vertexOffset += 2;
                }
                else {
                    if (k > 1) {
                        positionAttr.copy(vertexOffset, vertexOffset - 1);
                        colorAttr.copy(vertexOffset, vertexOffset - 1);
                        vertexOffset++;
                    }
                }

                if (!this.useNativeLine) {
                    if (k > 0) {
                        var idx3 = this._faceOffset * 3;
                        var indices = this.indices;
                        // 0-----2
                        // 1-----3
                        // 0->1->2, 1->3->2
                        indices[idx3] = vertexOffset - 4;
                        indices[idx3 + 1] = vertexOffset - 3;
                        indices[idx3 + 2] = vertexOffset - 2;

                        indices[idx3 + 3] = vertexOffset - 3;
                        indices[idx3 + 4] = vertexOffset - 1;
                        indices[idx3 + 5] = vertexOffset - 2;

                        this._faceOffset += 2;
                    }
                }
                else {
                    colorAttr.set(vertexOffset, pointColor);
                    positionAttr.set(vertexOffset, point);
                    vertexOffset++;
                }
            }

            this._vertexOffset = vertexOffset;
        };
    })(),

    /**
     * Set color of single line.
     */
    setItemColor: function (idx, color) {
        var startOffset = this._itemVertexOffsets[idx];
        var endOffset = idx < this._itemVertexOffsets.length - 1 ? this._itemVertexOffsets[idx + 1] : this._vertexOffset;

        for (var i = startOffset; i < endOffset; i++) {
            this.attributes.color.set(i, color);
        }
        this.dirty('color');
    }
});

__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.util.defaults(LinesGeometry.prototype, __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__["a" /* default */]);

/* harmony default export */ __webpack_exports__["a"] = (LinesGeometry);

/***/ }),
/* 106 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__src_echarts_gl__ = __webpack_require__(107);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__src_component_grid3D__ = __webpack_require__(154);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__src_component_geo3D__ = __webpack_require__(201);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__src_component_globe__ = __webpack_require__(207);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__src_component_mapbox3D__ = __webpack_require__(213);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__src_component_maptalks3D__ = __webpack_require__(219);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__src_chart_bar3D__ = __webpack_require__(225);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__src_chart_line3D__ = __webpack_require__(232);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__src_chart_scatter3D__ = __webpack_require__(236);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__src_chart_lines3D__ = __webpack_require__(243);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__src_chart_polygons3D__ = __webpack_require__(249);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__src_chart_surface__ = __webpack_require__(252);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__src_chart_map3D__ = __webpack_require__(256);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__src_chart_scatterGL__ = __webpack_require__(259);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__src_chart_graphGL__ = __webpack_require__(262);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__src_chart_flowGL__ = __webpack_require__(275);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__src_chart_linesGL__ = __webpack_require__(281);





















/***/ }),
/* 107 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_version__ = __webpack_require__(108);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_LayerGL__ = __webpack_require__(109);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__preprocessor_backwardCompat__ = __webpack_require__(153);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_graphicGL__ = __webpack_require__(1);
/**
 * echarts-gl
 * Extension pack of ECharts providing 3d plots and globe visualization
 *
 * Copyright (c) 2014, echarts-gl
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @module echarts-gl
 * @author Yi Shen(http://github.com/pissang)
 */

// PENDING Use a single canvas as layer or use image element?
var echartsGl = {
    version: '1.1.1',
    dependencies: {
        echarts: '4.1.0',
        claygl: '1.2.1'
    }
};






// Version checking
var deps = echartsGl.dependencies;
function versionTooOldMsg(name) {
    throw new Error(
        name + ' version is too old, needs ' + deps[name] + ' or higher'
    );
}
function checkVersion(version, name) {
    if ((version.replace('.', '') - 0) < (deps[name].replace('.', '') - 0)) {
        versionTooOldMsg(name);
    }
    console.log('Loaded ' + name + ', version ' + version);
}
checkVersion(__WEBPACK_IMPORTED_MODULE_1_claygl_src_version__["a" /* default */], 'claygl');
checkVersion(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.version, 'echarts');

function EChartsGL (zr) {
    this._layers = {};

    this._zr = zr;
}

EChartsGL.prototype.update = function (ecModel, api) {
    var self = this;
    var zr = api.getZr();

    if (!zr.getWidth() || !zr.getHeight()) {
        console.warn('Dom has no width or height');
        return;
    }

    function getLayerGL(model) {
        var zlevel;
        // Host on coordinate system.
        if (model.coordinateSystem && model.coordinateSystem.model) {
            zlevel = model.get('zlevel');
        }
        else {
            zlevel = model.get('zlevel');
        }

        var layers = self._layers;
        var layerGL = layers[zlevel];
        if (!layerGL) {
            layerGL = layers[zlevel] = new __WEBPACK_IMPORTED_MODULE_2__core_LayerGL__["a" /* default */]('gl-' + zlevel, zr);

            if (zr.painter.isSingleCanvas()) {
                layerGL.virtual = true;
                // If container is canvas, use image to represent LayerGL
                // FIXME Performance
                var img = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.Image({
                    z: 1e4,
                    style: {
                        image: layerGL.renderer.canvas
                    },
                    silent: true
                });
                layerGL.__hostImage = img;

                zr.add(img);
            }

            zr.painter.insertLayer(zlevel, layerGL);
        }
        if (layerGL.__hostImage) {
            layerGL.__hostImage.setStyle({
                width: layerGL.renderer.getWidth(),
                height: layerGL.renderer.getHeight()
            });
        }

        return layerGL;
    }

    function setSilent(groupGL, silent) {
        if (groupGL) {
            groupGL.traverse(function (mesh) {
                if (mesh.isRenderable && mesh.isRenderable()) {
                    mesh.ignorePicking = mesh.$ignorePicking != null
                        ? mesh.$ignorePicking : silent;
                }
            });
        }
    }

    for (var zlevel in this._layers) {
        this._layers[zlevel].removeViewsAll();
    }

    ecModel.eachComponent(function (componentType, componentModel) {
        if (componentType !== 'series') {
            var view = api.getViewOfComponentModel(componentModel);
            var coordSys = componentModel.coordinateSystem;
            // View with __ecgl__ flag is a echarts-gl component.
            if (view.__ecgl__) {
                var viewGL;
                if (coordSys) {
                    if (!coordSys.viewGL) {
                        console.error('Can\'t find viewGL in coordinateSystem of component ' + componentModel.id);
                        return;
                    }
                    viewGL = coordSys.viewGL;
                }
                else {
                    if (!componentModel.viewGL) {
                        console.error('Can\'t find viewGL of component ' + componentModel.id);
                        return;
                    }
                    viewGL = coordSys.viewGL;
                }

                var viewGL = coordSys.viewGL;
                var layerGL = getLayerGL(componentModel);

                layerGL.addView(viewGL);

                view.afterRender && view.afterRender(
                    componentModel, ecModel, api, layerGL
                );

                setSilent(view.groupGL, componentModel.get('silent'));
            }
        }
    });

    ecModel.eachSeries(function (seriesModel) {
        var chartView = api.getViewOfSeriesModel(seriesModel);
        var coordSys = seriesModel.coordinateSystem;
        if (chartView.__ecgl__) {
            if ((coordSys && !coordSys.viewGL) && !chartView.viewGL) {
                console.error('Can\'t find viewGL of series ' + chartView.id);
                return;
            }
            var viewGL = (coordSys && coordSys.viewGL) || chartView.viewGL;
            // TODO Check zlevel not same with component of coordinate system ?
            var layerGL = getLayerGL(seriesModel);
            layerGL.addView(viewGL);

            chartView.afterRender && chartView.afterRender(
                seriesModel, ecModel, api, layerGL
            );

            setSilent(chartView.groupGL, seriesModel.get('silent'));
        }
    });
};

// Hack original getRenderedCanvas. Will removed after new echarts released
// TODO
var oldInit = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.init;
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.init = function () {
    var chart = oldInit.apply(this, arguments);
    chart.getZr().painter.getRenderedCanvas = function (opts) {
        opts = opts || {};
        if (this._singleCanvas) {
            return this._layers[0].dom;
        }

        var canvas = document.createElement('canvas');
        var dpr = opts.pixelRatio || this.dpr;
        canvas.width = this.getWidth() * dpr;
        canvas.height = this.getHeight() * dpr;
        var ctx = canvas.getContext('2d');
        ctx.dpr = dpr;

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        if (opts.backgroundColor) {
            ctx.fillStyle = opts.backgroundColor;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
        }

        var displayList = this.storage.getDisplayList(true);

        var scope = {};
        var zlevel;

        var self = this;
        function findAndDrawOtherLayer(smaller, larger) {
            var zlevelList = self._zlevelList;
            if (smaller == null) {
                smaller = -Infinity;
            }
            var intermediateLayer;
            for (var i = 0; i < zlevelList.length; i++) {
                var z = zlevelList[i];
                var layer = self._layers[z];
                if (!layer.__builtin__ && z > smaller && z < larger) {
                    intermediateLayer = layer;
                    break;
                }
            }
            if (intermediateLayer && intermediateLayer.renderToCanvas) {
                ctx.save();
                intermediateLayer.renderToCanvas(ctx);
                ctx.restore();
            }
        }
        var layer = {
            ctx: ctx
        };
        for (var i = 0; i < displayList.length; i++) {
            var el = displayList[i];

            if (el.zlevel !== zlevel) {
                findAndDrawOtherLayer(zlevel, el.zlevel);
                zlevel = el.zlevel;
            }
            this._doPaintEl(el, layer, true, scope);
        }

        findAndDrawOtherLayer(zlevel, Infinity);

        return canvas;
    };
    return chart;
};


__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerPostUpdate(function (ecModel, api) {
    var zr = api.getZr();

    var egl = zr.__egl = zr.__egl || new EChartsGL(zr);

    egl.update(ecModel, api);
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerPreprocessor(__WEBPACK_IMPORTED_MODULE_3__preprocessor_backwardCompat__["a" /* default */]);

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphicGL = __WEBPACK_IMPORTED_MODULE_4__util_graphicGL__["a" /* default */];

/* unused harmony default export */ var _unused_webpack_default_export = (EChartsGL);

/***/ }),
/* 108 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/**
 * @name clay.version
 */
/* harmony default export */ __webpack_exports__["a"] = ('1.2.1');


/***/ }),
/* 109 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Renderer__ = __webpack_require__(52);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_picking_RayPicking__ = __webpack_require__(117);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_core_mixin_notifier__ = __webpack_require__(53);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_zrender_lib_animation_requestAnimationFrame__ = __webpack_require__(80);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_zrender_lib_animation_requestAnimationFrame___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_zrender_lib_animation_requestAnimationFrame__);
/**
 * Provide WebGL layer to zrender. Which is rendered on top of clay.
 *
 *
 * Relationship between zrender, LayerGL(renderer) and ViewGL(Scene, Camera, Viewport)
 *           zrender
 *           /     \
 *      LayerGL   LayerGL
 *    (renderer) (renderer)
 *      /     \
 *  ViewGL   ViewGL
 *
 * @module echarts-gl/core/LayerGL
 * @author Yi Shen(http://github.com/pissang)
 */







// PENDING, clay. notifier is same with zrender Eventful



/**
 * @constructor
 * @alias module:echarts-gl/core/LayerGL
 * @param {string} id Layer ID
 * @param {module:zrender/ZRender} zr
 */
var LayerGL = function (id, zr) {

    /**
     * Layer ID
     * @type {string}
     */
    this.id = id;

    /**
     * @type {module:zrender/ZRender}
     */
    this.zr = zr;

    /**
     * @type {clay.Renderer}
     */
    try {
        this.renderer = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Renderer__["a" /* default */]({
            clearBit: 0,
            devicePixelRatio: zr.painter.dpr,
            preserveDrawingBuffer: true,
            // PENDING
            premultipliedAlpha: true
        });
        this.renderer.resize(zr.painter.getWidth(), zr.painter.getHeight());
    }
    catch (e) {
        this.renderer = null;
        this.dom = document.createElement('div');
        this.dom.style.cssText = 'position:absolute; left: 0; top: 0; right: 0; bottom: 0;';
        this.dom.className = 'ecgl-nowebgl';
        this.dom.innerHTML = 'Sorry, your browser does not support WebGL';

        console.error(e);
        return;
    }

    this.onglobalout = this.onglobalout.bind(this);
    zr.on('globalout', this.onglobalout);

    /**
     * Canvas dom for webgl rendering
     * @type {HTMLCanvasElement}
     */
    this.dom = this.renderer.canvas;
    var style = this.dom.style;
    style.position = 'absolute';
    style.left = '0';
    style.top = '0';

    /**
     * @type {Array.<clay.Scene>}
     */
    this.views = [];

    this._picking = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_picking_RayPicking__["a" /* default */]({
        renderer: this.renderer
    });

    this._viewsToDispose = [];

    /**
     * Current accumulating id.
     */
    this._accumulatingId = 0;

    this._zrEventProxy = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.Rect({
        shape: {x: -1, y: -1, width: 2, height: 2},
        // FIXME Better solution.
        __isGLToZRProxy: true
    });

    this._backgroundColor = null;
};

/**
 * @param {module:echarts-gl/core/ViewGL} view
 */
LayerGL.prototype.addView = function (view) {
    if (view.layer === this) {
        return;
    }
    // If needs to dispose in this layer. unmark it.
    var idx = this._viewsToDispose.indexOf(view);
    if (idx >= 0) {
        this._viewsToDispose.splice(idx, 1);
    }

    this.views.push(view);

    view.layer = this;

    var zr = this.zr;
    view.scene.traverse(function (node) {
        node.__zr = zr;
        if (node.addAnimatorsToZr) {
            node.addAnimatorsToZr(zr);
        }
    });
};

function removeFromZr(node) {
    var zr = node.__zr;
    node.__zr = null;
    if (zr && node.removeAnimatorsFromZr) {
        node.removeAnimatorsFromZr(zr);
    }
}
/**
 * @param {module:echarts-gl/core/ViewGL} view
 */
LayerGL.prototype.removeView = function (view) {
    if (view.layer !== this) {
        return;
    }

    var idx = this.views.indexOf(view);
    if (idx >= 0) {
        this.views.splice(idx, 1);
        view.scene.traverse(removeFromZr, this);
        view.layer = null;

        // Mark to dispose in this layer.
        this._viewsToDispose.push(view);
    }
};

/**
 * Remove all views
 */
LayerGL.prototype.removeViewsAll = function () {
    this.views.forEach(function (view) {
        view.scene.traverse(removeFromZr, this);
        view.layer = null;

        // Mark to dispose in this layer.
        this._viewsToDispose.push(view);
    }, this);

    this.views.length = 0;

};

/**
 * Resize the canvas and viewport, will be invoked by zrender
 * @param  {number} width
 * @param  {number} height
 */
LayerGL.prototype.resize = function (width, height) {
    var renderer = this.renderer;
    renderer.resize(width, height);
};

/**
 * Clear color and depth
 * @return {[type]} [description]
 */
LayerGL.prototype.clear = function () {
    var gl = this.renderer.gl;
    var clearColor = this._backgroundColor || [0, 0, 0, 0];
    gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
    gl.depthMask(true);
    gl.colorMask(true, true, true, true);
    gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);
};

/**
 * Clear depth
 */
LayerGL.prototype.clearDepth = function () {
    var gl = this.renderer.gl;
    gl.clear(gl.DEPTH_BUFFER_BIT);
};

/**
 * Clear color
 */
LayerGL.prototype.clearColor = function () {
    var gl = this.renderer.gl;
    gl.clearColor(0, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);
};

/**
 * Mark layer to refresh next tick
 */
LayerGL.prototype.needsRefresh = function () {
    this.zr.refresh();
};

/**
 * Refresh the layer, will be invoked by zrender
 */
LayerGL.prototype.refresh = function (bgColor) {

    this._backgroundColor = bgColor ? __WEBPACK_IMPORTED_MODULE_4__util_graphicGL__["a" /* default */].parseColor(bgColor) : [0, 0, 0, 0];
    this.renderer.clearColor = this._backgroundColor;

    for (var i = 0; i < this.views.length; i++) {
        this.views[i].prepareRender(this.renderer);
    }

    this._doRender(false);

    // Auto dispose unused resources on GPU, like program(shader), texture, geometry(buffers)
    this._trackAndClean();

    // Dispose trashed views
    for (var i = 0; i < this._viewsToDispose.length; i++) {
        this._viewsToDispose[i].dispose(this.renderer);
    }
    this._viewsToDispose.length = 0;

    this._startAccumulating();
};


LayerGL.prototype.renderToCanvas = function (ctx) {
    // PENDING will block the page
    this._startAccumulating(true);
    ctx.drawImage(this.dom, 0, 0, ctx.canvas.width, ctx.canvas.height);
};

LayerGL.prototype._doRender = function (accumulating) {
    this.clear();
    this.renderer.saveViewport();
    for (var i = 0; i < this.views.length; i++) {
        this.views[i].render(this.renderer, accumulating);
    }
    this.renderer.restoreViewport();
};

/**
 * Stop accumulating
 */
LayerGL.prototype._stopAccumulating = function () {
    this._accumulatingId = 0;
    clearTimeout(this._accumulatingTimeout);
};

var accumulatingId = 1;
/**
 * Start accumulating all the views.
 * Accumulating is for antialising and have more sampling in SSAO
 * @private
 */
LayerGL.prototype._startAccumulating = function (immediate) {
    var self = this;
    this._stopAccumulating();

    var needsAccumulate = false;
    for (var i = 0; i < this.views.length; i++) {
        needsAccumulate = this.views[i].needsAccumulate() || needsAccumulate;
    }
    if (!needsAccumulate) {
        return;
    }

    function accumulate(id) {
        if (!self._accumulatingId || id !== self._accumulatingId) {
            return;
        }

        var isFinished = true;
        for (var i = 0; i < self.views.length; i++) {
            isFinished = self.views[i].isAccumulateFinished() && needsAccumulate;
        }

        if (!isFinished) {
            self._doRender(true);

            if (immediate) {
                accumulate(id);
            }
            else {
                __WEBPACK_IMPORTED_MODULE_6_zrender_lib_animation_requestAnimationFrame___default()(function () {
                    accumulate(id);
                });
            }
        }
    }

    this._accumulatingId = accumulatingId++;

    if (immediate) {
        accumulate(self._accumulatingId);
    }
    else {
        this._accumulatingTimeout = setTimeout(function () {
            accumulate(self._accumulatingId);
        }, 50);
    }
};

LayerGL.prototype._trackAndClean = function () {
    var textureList = [];
    var geometriesList = [];

    // Mark all resources unused;
    if (this._textureList) {
        markUnused(this._textureList);
        markUnused(this._geometriesList);
    }

    for (var i = 0; i < this.views.length; i++) {
        collectResources(this.views[i].scene, textureList, geometriesList);
    }

    // Dispose those unsed resources.
    if (this._textureList) {
        checkAndDispose(this.renderer, this._textureList);
        checkAndDispose(this.renderer, this._geometriesList);
    }

    this._textureList = textureList;
    this._geometriesList = geometriesList;
};

function markUnused(resourceList) {
    for (var i = 0; i < resourceList.length; i++) {
        resourceList[i].__used__ = 0;
    }
}
function checkAndDispose(renderer, resourceList) {
    for (var i = 0; i < resourceList.length; i++) {
        if (!resourceList[i].__used__) {
            resourceList[i].dispose(renderer);
        }
    }
}
function updateUsed(resource, list) {
    resource.__used__ = resource.__used__ || 0;
    resource.__used__++;
    if (resource.__used__ === 1) {
        // Don't push to the list twice.
        list.push(resource);
    }
}
function collectResources(scene, textureResourceList, geometryResourceList) {
    var prevMaterial;
    var prevGeometry;
    scene.traverse(function (renderable) {
        if (renderable.isRenderable()) {
            var geometry = renderable.geometry;
            var material = renderable.material;

            // TODO optimize!!
            if (material !== prevMaterial) {
                var textureUniforms = material.getTextureUniforms();
                for (var u = 0; u < textureUniforms.length; u++) {
                    var uniformName = textureUniforms[u];
                    var val = material.uniforms[uniformName].value;
                    if (!val) {
                        continue;
                    }
                    if (val instanceof __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */]) {
                        updateUsed(val, textureResourceList);
                    }
                    else if (val instanceof Array) {
                        for (var k = 0; k < val.length; k++) {
                            if (val[k] instanceof __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */]) {
                                updateUsed(val[k], textureResourceList);
                            }
                        }
                    }
                }
            }
            if (geometry !== prevGeometry) {
                updateUsed(geometry, geometryResourceList);
            }

            prevMaterial = material;
            prevGeometry = geometry;
        }
    });

    for (var k = 0; k < scene.lights.length; k++) {
        // Track AmbientCubemap
        if (scene.lights[k].cubemap) {
            updateUsed(scene.lights[k].cubemap, textureResourceList);
        }
    }
}
/**
 * Dispose the layer
 */
LayerGL.prototype.dispose = function () {
    this._stopAccumulating();
    this.renderer.disposeScene(this.scene);

    this.zr.off('globalout', this.onglobalout);
};

// Event handlers
LayerGL.prototype.onmousedown = function (e) {
    if (e.target && e.target.__isGLToZRProxy) {
        return;
    }

    e = e.event;
    var obj = this.pickObject(e.offsetX, e.offsetY);
    if (obj) {
        this._dispatchEvent('mousedown', e, obj);
        this._dispatchDataEvent('mousedown', e, obj);
    }

    this._downX = e.offsetX;
    this._downY = e.offsetY;
};

LayerGL.prototype.onmousemove = function (e) {
    if (e.target && e.target.__isGLToZRProxy) {
        return;
    }

    e = e.event;
    var obj = this.pickObject(e.offsetX, e.offsetY);

    var target = obj && obj.target;
    var lastHovered = this._hovered;
    this._hovered = obj;

    if (lastHovered && target !== lastHovered.target) {
        lastHovered.relatedTarget = target;
        this._dispatchEvent('mouseout', e, lastHovered);
        // this._dispatchDataEvent('mouseout', e, lastHovered);

        this.zr.setCursorStyle('default');
    }

    this._dispatchEvent('mousemove', e, obj);

    if (obj) {
        this.zr.setCursorStyle('pointer');

        if (!lastHovered || (target !== lastHovered.target)) {
            this._dispatchEvent('mouseover', e, obj);
            // this._dispatchDataEvent('mouseover', e, obj);
        }
    }

    this._dispatchDataEvent('mousemove', e, obj);
};

LayerGL.prototype.onmouseup = function (e) {
    if (e.target && e.target.__isGLToZRProxy) {
        return;
    }

    e = e.event;
    var obj = this.pickObject(e.offsetX, e.offsetY);

    if (obj) {
        this._dispatchEvent('mouseup', e, obj);
        this._dispatchDataEvent('mouseup', e, obj);
    }

    this._upX = e.offsetX;
    this._upY = e.offsetY;
};

LayerGL.prototype.onclick = LayerGL.prototype.dblclick = function (e) {
    if (e.target && e.target.__isGLToZRProxy) {
        return;
    }

    // Ignore click event if mouse moved
    var dx = this._upX - this._downX;
    var dy = this._upY - this._downY;
    if (Math.sqrt(dx * dx + dy * dy) > 20) {
        return;
    }

    e = e.event;
    var obj = this.pickObject(e.offsetX, e.offsetY);

    if (obj) {
        this._dispatchEvent(e.type, e, obj);
        this._dispatchDataEvent(e.type, e, obj);
    }

    // Try set depth of field onclick
    var result = this._clickToSetFocusPoint(e);
    if (result) {
        var success = result.view.setDOFFocusOnPoint(result.distance);
        if (success) {
            this.zr.refresh();
        }
    }
};

LayerGL.prototype._clickToSetFocusPoint = function (e) {
    var renderer = this.renderer;
    var oldViewport = renderer.viewport;
    for (var i = this.views.length - 1; i >= 0; i--) {
        var viewGL = this.views[i];
        if (viewGL.hasDOF() && viewGL.containPoint(e.offsetX, e.offsetY)) {
            this._picking.scene = viewGL.scene;
            this._picking.camera = viewGL.camera;
            // Only used for picking, renderer.setViewport will also invoke gl.viewport.
            // Set directly, PENDING.
            renderer.viewport = viewGL.viewport;
            var result = this._picking.pick(e.offsetX, e.offsetY, true);
            if (result) {
                result.view = viewGL;
                return result;
            }
        }
    }
    renderer.viewport = oldViewport;
};

LayerGL.prototype.onglobalout = function (e) {
    var lastHovered = this._hovered;
    if (lastHovered) {
        this._dispatchEvent('mouseout', e, {
            target: lastHovered.target
        });
    }
};

LayerGL.prototype.pickObject = function (x, y) {

    var output = [];
    var renderer = this.renderer;
    var oldViewport = renderer.viewport;
    for (var i = 0; i < this.views.length; i++) {
        var viewGL = this.views[i];
        if (viewGL.containPoint(x, y)) {
            this._picking.scene = viewGL.scene;
            this._picking.camera = viewGL.camera;
            // Only used for picking, renderer.setViewport will also invoke gl.viewport.
            // Set directly, PENDING.
            renderer.viewport = viewGL.viewport;
            this._picking.pickAll(x, y, output);
        }
    }
    renderer.viewport = oldViewport;
    output.sort(function (a, b) {
        return a.distance - b.distance;
    });
    return output[0];
};

LayerGL.prototype._dispatchEvent = function (eveName, originalEvent, newEvent) {
    if (!newEvent) {
        newEvent = {};
    }
    var current = newEvent.target;

    newEvent.cancelBubble = false;
    newEvent.event = originalEvent;
    newEvent.type = eveName;
    newEvent.offsetX = originalEvent.offsetX;
    newEvent.offsetY = originalEvent.offsetY;

    while (current) {
        current.trigger(eveName, newEvent);
        current = current.getParent();

        if (newEvent.cancelBubble) {
            break;
        }
    }

    this._dispatchToView(eveName, newEvent);
};

LayerGL.prototype._dispatchDataEvent = function (eveName, originalEvent, newEvent) {
    var mesh = newEvent && newEvent.target;

    var dataIndex = mesh && mesh.dataIndex;
    var seriesIndex = mesh && mesh.seriesIndex;
    // Custom event data
    var eventData = mesh && mesh.eventData;
    var elChangedInMouseMove = false;

    var eventProxy = this._zrEventProxy;
    eventProxy.position = [originalEvent.offsetX, originalEvent.offsetY];
    eventProxy.update();

    var targetInfo = {
        target: eventProxy
    };
    if (eveName === 'mousemove') {
        if (dataIndex != null) {
            if (dataIndex !== this._lastDataIndex) {
                if (parseInt(this._lastDataIndex, 10) >= 0) {
                    eventProxy.dataIndex = this._lastDataIndex;
                    eventProxy.seriesIndex = this._lastSeriesIndex;
                    // FIXME May cause double events.
                    this.zr.handler.dispatchToElement(targetInfo, 'mouseout', originalEvent);
                }
                elChangedInMouseMove = true;
            }
        }
        else if (eventData != null) {
            if (eventData !== this._lastEventData) {
                if (this._lastEventData != null) {
                    eventProxy.eventData = this._lastEventData;
                    // FIXME May cause double events.
                    this.zr.handler.dispatchToElement(targetInfo, 'mouseout', originalEvent);
                }
                elChangedInMouseMove = true;
            }
        }
        this._lastEventData = eventData;
        this._lastDataIndex = dataIndex;
        this._lastSeriesIndex = seriesIndex;
    }

    eventProxy.eventData = eventData;
    eventProxy.dataIndex = dataIndex;
    eventProxy.seriesIndex = seriesIndex;

    if (eventData != null || (parseInt(dataIndex, 10) >= 0 && parseInt(seriesIndex, 10) >= 0)) {
        this.zr.handler.dispatchToElement(targetInfo, eveName, originalEvent);

        if (elChangedInMouseMove) {
            this.zr.handler.dispatchToElement(targetInfo, 'mouseover', originalEvent);
        }
    }
};

LayerGL.prototype._dispatchToView = function (eventName, e) {
    for (var i = 0; i < this.views.length; i++) {
        if (this.views[i].containPoint(e.offsetX, e.offsetY)) {
            this.views[i].trigger(eventName, e);
        }
    }
};

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.extend(LayerGL.prototype, __WEBPACK_IMPORTED_MODULE_5_claygl_src_core_mixin_notifier__["a" /* default */]);

/* harmony default export */ __webpack_exports__["a"] = (LayerGL);

/***/ }),
/* 110 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/**
 * Extend a sub class from base class
 * @param {object|Function} makeDefaultOpt default option of this sub class, method of the sub can use this.xxx to access this option
 * @param {Function} [initialize] Initialize after the sub class is instantiated
 * @param {Object} [proto] Prototype methods/properties of the sub class
 * @memberOf clay.core.mixin.extend
 * @return {Function}
 */
function derive(makeDefaultOpt, initialize/*optional*/, proto/*optional*/) {

    if (typeof initialize == 'object') {
        proto = initialize;
        initialize = null;
    }

    var _super = this;

    var propList;
    if (!(makeDefaultOpt instanceof Function)) {
        // Optimize the property iterate if it have been fixed
        propList = [];
        for (var propName in makeDefaultOpt) {
            if (makeDefaultOpt.hasOwnProperty(propName)) {
                propList.push(propName);
            }
        }
    }

    var sub = function(options) {

        // call super constructor
        _super.apply(this, arguments);

        if (makeDefaultOpt instanceof Function) {
            // Invoke makeDefaultOpt each time if it is a function, So we can make sure each
            // property in the object will not be shared by mutiple instances
            extend(this, makeDefaultOpt.call(this, options));
        }
        else {
            extendWithPropList(this, makeDefaultOpt, propList);
        }

        if (this.constructor === sub) {
            // Initialize function will be called in the order of inherit
            var initializers = sub.__initializers__;
            for (var i = 0; i < initializers.length; i++) {
                initializers[i].apply(this, arguments);
            }
        }
    };
    // save super constructor
    sub.__super__ = _super;
    // Initialize function will be called after all the super constructor is called
    if (!_super.__initializers__) {
        sub.__initializers__ = [];
    } else {
        sub.__initializers__ = _super.__initializers__.slice();
    }
    if (initialize) {
        sub.__initializers__.push(initialize);
    }

    var Ctor = function() {};
    Ctor.prototype = _super.prototype;
    sub.prototype = new Ctor();
    sub.prototype.constructor = sub;
    extend(sub.prototype, proto);

    // extend the derive method as a static method;
    sub.extend = _super.extend;

    // DEPCRATED
    sub.derive = _super.extend;

    return sub;
}

function extend(target, source) {
    if (!source) {
        return;
    }
    for (var name in source) {
        if (source.hasOwnProperty(name)) {
            target[name] = source[name];
        }
    }
}

function extendWithPropList(target, source, propList) {
    for (var i = 0; i < propList.length; i++) {
        var propName = propList[i];
        target[propName] = source[propName];
    }
}

/**
 * @alias clay.core.mixin.extend
 * @mixin
 */
/* harmony default export */ __webpack_exports__["a"] = ({

    extend: derive,

    // DEPCRATED
    derive: derive
});


/***/ }),
/* 111 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
var EXTENSION_LIST = [
    'OES_texture_float',
    'OES_texture_half_float',
    'OES_texture_float_linear',
    'OES_texture_half_float_linear',
    'OES_standard_derivatives',
    'OES_vertex_array_object',
    'OES_element_index_uint',
    'WEBGL_compressed_texture_s3tc',
    'WEBGL_depth_texture',
    'EXT_texture_filter_anisotropic',
    'EXT_shader_texture_lod',
    'WEBGL_draw_buffers',
    'EXT_frag_depth',
    'EXT_sRGB'
];

var PARAMETER_NAMES = [
    'MAX_TEXTURE_SIZE',
    'MAX_CUBE_MAP_TEXTURE_SIZE'
];

function GLInfo(_gl) {
    var extensions = {};
    var parameters = {};

    // Get webgl extension
    for (var i = 0; i < EXTENSION_LIST.length; i++) {
        var extName = EXTENSION_LIST[i];
        createExtension(extName);
    }
    // Get parameters
    for (var i = 0; i < PARAMETER_NAMES.length; i++) {
        var name = PARAMETER_NAMES[i];
        parameters[name] = _gl.getParameter(_gl[name]);
    }

    this.getExtension = function (name) {
        if (!(name in extensions)) {
            createExtension(name);
        }
        return extensions[name];
    };

    this.getParameter = function (name) {
        return parameters[name];
    };

    this.getMaxJointNumber = function () {
        return 15;
    };

    function createExtension(name) {
        var ext = _gl.getExtension(name);
        if (!ext) {
            ext = _gl.getExtension('MOZ_' + name);
        }
        if (!ext) {
            ext = _gl.getExtension('WEBKIT_' + name);
        }
        extensions[name] = ext;
    }
}

/* harmony default export */ __webpack_exports__["a"] = (GLInfo);


/***/ }),
/* 112 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
function get(options) {

    var xhr = new XMLHttpRequest();

    xhr.open('get', options.url);
    // With response type set browser can get and put binary data
    // https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Sending_and_Receiving_Binary_Data
    // Default is text, and it can be set
    // arraybuffer, blob, document, json, text
    xhr.responseType = options.responseType || 'text';

    if (options.onprogress) {
        //https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest
        xhr.onprogress = function(e) {
            if (e.lengthComputable) {
                var percent = e.loaded / e.total;
                options.onprogress(percent, e.loaded, e.total);
            }
            else {
                options.onprogress(null);
            }
        };
    }
    xhr.onload = function(e) {
        if (xhr.status >= 400) {
            options.onerror && options.onerror();
        }
        else {
            options.onload && options.onload(xhr.response);
        }
    };
    if (options.onerror) {
        xhr.onerror = options.onerror;
    }
    xhr.send(null);
}

/* harmony default export */ __webpack_exports__["a"] = ({
    get: get
});


/***/ }),
/* 113 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_LRU__ = __webpack_require__(69);
/**
 * @namespace clay.core.color
 */


var colorUtil = {};

var kCSSColorTable = {
    'transparent': [0,0,0,0], 'aliceblue': [240,248,255,1],
    'antiquewhite': [250,235,215,1], 'aqua': [0,255,255,1],
    'aquamarine': [127,255,212,1], 'azure': [240,255,255,1],
    'beige': [245,245,220,1], 'bisque': [255,228,196,1],
    'black': [0,0,0,1], 'blanchedalmond': [255,235,205,1],
    'blue': [0,0,255,1], 'blueviolet': [138,43,226,1],
    'brown': [165,42,42,1], 'burlywood': [222,184,135,1],
    'cadetblue': [95,158,160,1], 'chartreuse': [127,255,0,1],
    'chocolate': [210,105,30,1], 'coral': [255,127,80,1],
    'cornflowerblue': [100,149,237,1], 'cornsilk': [255,248,220,1],
    'crimson': [220,20,60,1], 'cyan': [0,255,255,1],
    'darkblue': [0,0,139,1], 'darkcyan': [0,139,139,1],
    'darkgoldenrod': [184,134,11,1], 'darkgray': [169,169,169,1],
    'darkgreen': [0,100,0,1], 'darkgrey': [169,169,169,1],
    'darkkhaki': [189,183,107,1], 'darkmagenta': [139,0,139,1],
    'darkolivegreen': [85,107,47,1], 'darkorange': [255,140,0,1],
    'darkorchid': [153,50,204,1], 'darkred': [139,0,0,1],
    'darksalmon': [233,150,122,1], 'darkseagreen': [143,188,143,1],
    'darkslateblue': [72,61,139,1], 'darkslategray': [47,79,79,1],
    'darkslategrey': [47,79,79,1], 'darkturquoise': [0,206,209,1],
    'darkviolet': [148,0,211,1], 'deeppink': [255,20,147,1],
    'deepskyblue': [0,191,255,1], 'dimgray': [105,105,105,1],
    'dimgrey': [105,105,105,1], 'dodgerblue': [30,144,255,1],
    'firebrick': [178,34,34,1], 'floralwhite': [255,250,240,1],
    'forestgreen': [34,139,34,1], 'fuchsia': [255,0,255,1],
    'gainsboro': [220,220,220,1], 'ghostwhite': [248,248,255,1],
    'gold': [255,215,0,1], 'goldenrod': [218,165,32,1],
    'gray': [128,128,128,1], 'green': [0,128,0,1],
    'greenyellow': [173,255,47,1], 'grey': [128,128,128,1],
    'honeydew': [240,255,240,1], 'hotpink': [255,105,180,1],
    'indianred': [205,92,92,1], 'indigo': [75,0,130,1],
    'ivory': [255,255,240,1], 'khaki': [240,230,140,1],
    'lavender': [230,230,250,1], 'lavenderblush': [255,240,245,1],
    'lawngreen': [124,252,0,1], 'lemonchiffon': [255,250,205,1],
    'lightblue': [173,216,230,1], 'lightcoral': [240,128,128,1],
    'lightcyan': [224,255,255,1], 'lightgoldenrodyellow': [250,250,210,1],
    'lightgray': [211,211,211,1], 'lightgreen': [144,238,144,1],
    'lightgrey': [211,211,211,1], 'lightpink': [255,182,193,1],
    'lightsalmon': [255,160,122,1], 'lightseagreen': [32,178,170,1],
    'lightskyblue': [135,206,250,1], 'lightslategray': [119,136,153,1],
    'lightslategrey': [119,136,153,1], 'lightsteelblue': [176,196,222,1],
    'lightyellow': [255,255,224,1], 'lime': [0,255,0,1],
    'limegreen': [50,205,50,1], 'linen': [250,240,230,1],
    'magenta': [255,0,255,1], 'maroon': [128,0,0,1],
    'mediumaquamarine': [102,205,170,1], 'mediumblue': [0,0,205,1],
    'mediumorchid': [186,85,211,1], 'mediumpurple': [147,112,219,1],
    'mediumseagreen': [60,179,113,1], 'mediumslateblue': [123,104,238,1],
    'mediumspringgreen': [0,250,154,1], 'mediumturquoise': [72,209,204,1],
    'mediumvioletred': [199,21,133,1], 'midnightblue': [25,25,112,1],
    'mintcream': [245,255,250,1], 'mistyrose': [255,228,225,1],
    'moccasin': [255,228,181,1], 'navajowhite': [255,222,173,1],
    'navy': [0,0,128,1], 'oldlace': [253,245,230,1],
    'olive': [128,128,0,1], 'olivedrab': [107,142,35,1],
    'orange': [255,165,0,1], 'orangered': [255,69,0,1],
    'orchid': [218,112,214,1], 'palegoldenrod': [238,232,170,1],
    'palegreen': [152,251,152,1], 'paleturquoise': [175,238,238,1],
    'palevioletred': [219,112,147,1], 'papayawhip': [255,239,213,1],
    'peachpuff': [255,218,185,1], 'peru': [205,133,63,1],
    'pink': [255,192,203,1], 'plum': [221,160,221,1],
    'powderblue': [176,224,230,1], 'purple': [128,0,128,1],
    'red': [255,0,0,1], 'rosybrown': [188,143,143,1],
    'royalblue': [65,105,225,1], 'saddlebrown': [139,69,19,1],
    'salmon': [250,128,114,1], 'sandybrown': [244,164,96,1],
    'seagreen': [46,139,87,1], 'seashell': [255,245,238,1],
    'sienna': [160,82,45,1], 'silver': [192,192,192,1],
    'skyblue': [135,206,235,1], 'slateblue': [106,90,205,1],
    'slategray': [112,128,144,1], 'slategrey': [112,128,144,1],
    'snow': [255,250,250,1], 'springgreen': [0,255,127,1],
    'steelblue': [70,130,180,1], 'tan': [210,180,140,1],
    'teal': [0,128,128,1], 'thistle': [216,191,216,1],
    'tomato': [255,99,71,1], 'turquoise': [64,224,208,1],
    'violet': [238,130,238,1], 'wheat': [245,222,179,1],
    'white': [255,255,255,1], 'whitesmoke': [245,245,245,1],
    'yellow': [255,255,0,1], 'yellowgreen': [154,205,50,1]
};

function clampCssByte(i) {  // Clamp to integer 0 .. 255.
    i = Math.round(i);  // Seems to be what Chrome does (vs truncation).
    return i < 0 ? 0 : i > 255 ? 255 : i;
}

function clampCssAngle(i) {  // Clamp to integer 0 .. 360.
    i = Math.round(i);  // Seems to be what Chrome does (vs truncation).
    return i < 0 ? 0 : i > 360 ? 360 : i;
}

function clampCssFloat(f) {  // Clamp to float 0.0 .. 1.0.
    return f < 0 ? 0 : f > 1 ? 1 : f;
}

function parseCssInt(str) {  // int or percentage.
    if (str.length && str.charAt(str.length - 1) === '%') {
        return clampCssByte(parseFloat(str) / 100 * 255);
    }
    return clampCssByte(parseInt(str, 10));
}

function parseCssFloat(str) {  // float or percentage.
    if (str.length && str.charAt(str.length - 1) === '%') {
        return clampCssFloat(parseFloat(str) / 100);
    }
    return clampCssFloat(parseFloat(str));
}

function cssHueToRgb(m1, m2, h) {
    if (h < 0) {
        h += 1;
    }
    else if (h > 1) {
        h -= 1;
    }

    if (h * 6 < 1) {
        return m1 + (m2 - m1) * h * 6;
    }
    if (h * 2 < 1) {
        return m2;
    }
    if (h * 3 < 2) {
        return m1 + (m2 - m1) * (2/3 - h) * 6;
    }
    return m1;
}

function lerpNumber(a, b, p) {
    return a + (b - a) * p;
}

function setRgba(out, r, g, b, a) {
    out[0] = r; out[1] = g; out[2] = b; out[3] = a;
    return out;
}
function copyRgba(out, a) {
    out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3];
    return out;
}

var colorCache = new __WEBPACK_IMPORTED_MODULE_0__core_LRU__["a" /* default */](20);
var lastRemovedArr = null;

function putToCache(colorStr, rgbaArr) {
    // Reuse removed array
    if (lastRemovedArr) {
        copyRgba(lastRemovedArr, rgbaArr);
    }
    lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || (rgbaArr.slice()));
}

/**
 * @name clay.core.color.parse
 * @param {string} colorStr
 * @param {Array.<number>} out
 * @return {Array.<number>}
 */
colorUtil.parse = function (colorStr, rgbaArr) {
    if (!colorStr) {
        return;
    }
    rgbaArr = rgbaArr || [];

    var cached = colorCache.get(colorStr);
    if (cached) {
        return copyRgba(rgbaArr, cached);
    }

    // colorStr may be not string
    colorStr = colorStr + '';
    // Remove all whitespace, not compliant, but should just be more accepting.
    var str = colorStr.replace(/ /g, '').toLowerCase();

    // Color keywords (and transparent) lookup.
    if (str in kCSSColorTable) {
        copyRgba(rgbaArr, kCSSColorTable[str]);
        putToCache(colorStr, rgbaArr);
        return rgbaArr;
    }

    // #abc and #abc123 syntax.
    if (str.charAt(0) === '#') {
        if (str.length === 4) {
            var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.
            if (!(iv >= 0 && iv <= 0xfff)) {
                setRgba(rgbaArr, 0, 0, 0, 1);
                return;  // Covers NaN.
            }
            setRgba(rgbaArr,
                ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),
                (iv & 0xf0) | ((iv & 0xf0) >> 4),
                (iv & 0xf) | ((iv & 0xf) << 4),
                1
            );
            putToCache(colorStr, rgbaArr);
            return rgbaArr;
        }
        else if (str.length === 7) {
            var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.
            if (!(iv >= 0 && iv <= 0xffffff)) {
                setRgba(rgbaArr, 0, 0, 0, 1);
                return;  // Covers NaN.
            }
            setRgba(rgbaArr,
                (iv & 0xff0000) >> 16,
                (iv & 0xff00) >> 8,
                iv & 0xff,
                1
            );
            putToCache(colorStr, rgbaArr);
            return rgbaArr;
        }

        return;
    }
    var op = str.indexOf('('), ep = str.indexOf(')');
    if (op !== -1 && ep + 1 === str.length) {
        var fname = str.substr(0, op);
        var params = str.substr(op + 1, ep - (op + 1)).split(',');
        var alpha = 1;  // To allow case fallthrough.
        switch (fname) {
            case 'rgba':
                if (params.length !== 4) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                alpha = parseCssFloat(params.pop()); // jshint ignore:line
            // Fall through.
            case 'rgb':
                if (params.length !== 3) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                setRgba(rgbaArr,
                    parseCssInt(params[0]),
                    parseCssInt(params[1]),
                    parseCssInt(params[2]),
                    alpha
                );
                putToCache(colorStr, rgbaArr);
                return rgbaArr;
            case 'hsla':
                if (params.length !== 4) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                params[3] = parseCssFloat(params[3]);
                hsla2rgba(params, rgbaArr);
                putToCache(colorStr, rgbaArr);
                return rgbaArr;
            case 'hsl':
                if (params.length !== 3) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                hsla2rgba(params, rgbaArr);
                putToCache(colorStr, rgbaArr);
                return rgbaArr;
            default:
                return;
        }
    }

    setRgba(rgbaArr, 0, 0, 0, 1);
    return;
};

colorUtil.parseToFloat = function (colorStr, rgbaArr) {
    rgbaArr = colorUtil.parse(colorStr, rgbaArr);
    if (!rgbaArr) {
        return;
    }
    rgbaArr[0] /= 255;
    rgbaArr[1] /= 255;
    rgbaArr[2] /= 255;
    return rgbaArr;
}

/**
 * @name clay.core.color.hsla2rgba
 * @param {Array.<number>} hsla
 * @param {Array.<number>} rgba
 * @return {Array.<number>} rgba
 */
function hsla2rgba(hsla, rgba) {
    var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360;  // 0 .. 1
    // NOTE(deanm): According to the CSS spec s/l should only be
    // percentages, but we don't bother and let float or percentage.
    var s = parseCssFloat(hsla[1]);
    var l = parseCssFloat(hsla[2]);
    var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
    var m1 = l * 2 - m2;

    rgba = rgba || [];
    setRgba(rgba,
        clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255),
        clampCssByte(cssHueToRgb(m1, m2, h) * 255),
        clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255),
        1
    );

    if (hsla.length === 4) {
        rgba[3] = hsla[3];
    }

    return rgba;
}

/**
 * @name clay.core.color.rgba2hsla
 * @param {Array.<number>} rgba
 * @return {Array.<number>} hsla
 */
function rgba2hsla(rgba) {
    if (!rgba) {
        return;
    }

    // RGB from 0 to 255
    var R = rgba[0] / 255;
    var G = rgba[1] / 255;
    var B = rgba[2] / 255;

    var vMin = Math.min(R, G, B); // Min. value of RGB
    var vMax = Math.max(R, G, B); // Max. value of RGB
    var delta = vMax - vMin; // Delta RGB value

    var L = (vMax + vMin) / 2;
    var H;
    var S;
    // HSL results from 0 to 1
    if (delta === 0) {
        H = 0;
        S = 0;
    }
    else {
        if (L < 0.5) {
            S = delta / (vMax + vMin);
        }
        else {
            S = delta / (2 - vMax - vMin);
        }

        var deltaR = (((vMax - R) / 6) + (delta / 2)) / delta;
        var deltaG = (((vMax - G) / 6) + (delta / 2)) / delta;
        var deltaB = (((vMax - B) / 6) + (delta / 2)) / delta;

        if (R === vMax) {
            H = deltaB - deltaG;
        }
        else if (G === vMax) {
            H = (1 / 3) + deltaR - deltaB;
        }
        else if (B === vMax) {
            H = (2 / 3) + deltaG - deltaR;
        }

        if (H < 0) {
            H += 1;
        }

        if (H > 1) {
            H -= 1;
        }
    }

    var hsla = [H * 360, S, L];

    if (rgba[3] != null) {
        hsla.push(rgba[3]);
    }

    return hsla;
}

/**
 * @name clay.core.color.lift
 * @param {string} color
 * @param {number} level
 * @return {string}
 */
colorUtil.lift = function (color, level) {
    var colorArr = colorUtil.parse(color);
    if (colorArr) {
        for (var i = 0; i < 3; i++) {
            if (level < 0) {
                colorArr[i] = colorArr[i] * (1 - level) | 0;
            }
            else {
                colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0;
            }
        }
        return colorUtil.stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
    }
}

/**
 * @name clay.core.color.toHex
 * @param {string} color
 * @return {string}
 */
colorUtil.toHex = function (color) {
    var colorArr = colorUtil.parse(color);
    if (colorArr) {
        return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + (+colorArr[2])).toString(16).slice(1);
    }
};

/**
 * Map value to color. Faster than lerp methods because color is represented by rgba array.
 * @name clay.core.color
 * @param {number} normalizedValue A float between 0 and 1.
 * @param {Array.<Array.<number>>} colors List of rgba color array
 * @param {Array.<number>} [out] Mapped gba color array
 * @return {Array.<number>} will be null/undefined if input illegal.
 */
colorUtil.fastLerp = function (normalizedValue, colors, out) {
    if (!(colors && colors.length)
        || !(normalizedValue >= 0 && normalizedValue <= 1)
    ) {
        return;
    }

    out = out || [];

    var value = normalizedValue * (colors.length - 1);
    var leftIndex = Math.floor(value);
    var rightIndex = Math.ceil(value);
    var leftColor = colors[leftIndex];
    var rightColor = colors[rightIndex];
    var dv = value - leftIndex;
    out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv));
    out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv));
    out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv));
    out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv));

    return out;
}

colorUtil.fastMapToColor = colorUtil.fastLerp;

/**
 * @param {number} normalizedValue A float between 0 and 1.
 * @param {Array.<string>} colors Color list.
 * @param {boolean=} fullOutput Default false.
 * @return {(string|Object)} Result color. If fullOutput,
 *                           return {color: ..., leftIndex: ..., rightIndex: ..., value: ...},
 */
colorUtil.lerp = function (normalizedValue, colors, fullOutput) {
    if (!(colors && colors.length)
        || !(normalizedValue >= 0 && normalizedValue <= 1)
    ) {
        return;
    }

    var value = normalizedValue * (colors.length - 1);
    var leftIndex = Math.floor(value);
    var rightIndex = Math.ceil(value);
    var leftColor = colorUtil.parse(colors[leftIndex]);
    var rightColor = colorUtil.parse(colors[rightIndex]);
    var dv = value - leftIndex;

    var color = colorUtil.stringify(
        [
            clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)),
            clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)),
            clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)),
            clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv))
        ],
        'rgba'
    );

    return fullOutput
        ? {
            color: color,
            leftIndex: leftIndex,
            rightIndex: rightIndex,
            value: value
        }
        : color;
}

/**
 * @deprecated
 */
colorUtil.mapToColor = colorUtil.lerp;

/**
 * @name clay.core.color
 * @param {string} color
 * @param {number=} h 0 ~ 360, ignore when null.
 * @param {number=} s 0 ~ 1, ignore when null.
 * @param {number=} l 0 ~ 1, ignore when null.
 * @return {string} Color string in rgba format.
 */
colorUtil.modifyHSL = function (color, h, s, l) {
    color = colorUtil.parse(color);

    if (color) {
        color = rgba2hsla(color);
        h != null && (color[0] = clampCssAngle(h));
        s != null && (color[1] = parseCssFloat(s));
        l != null && (color[2] = parseCssFloat(l));

        return colorUtil.stringify(hsla2rgba(color), 'rgba');
    }
}

/**
 * @param {string} color
 * @param {number=} alpha 0 ~ 1
 * @return {string} Color string in rgba format.
 */
colorUtil.modifyAlpha = function (color, alpha) {
    color = colorUtil.parse(color);

    if (color && alpha != null) {
        color[3] = clampCssFloat(alpha);
        return colorUtil.stringify(color, 'rgba');
    }
}

/**
 * @param {Array.<number>} arrColor like [12,33,44,0.4]
 * @param {string} type 'rgba', 'hsva', ...
 * @return {string} Result color. (If input illegal, return undefined).
 */
colorUtil.stringify = function (arrColor, type) {
    if (!arrColor || !arrColor.length) {
        return;
    }
    var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
    if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
        colorStr += ',' + arrColor[3];
    }
    return type + '(' + colorStr + ')';
};



/* harmony default export */ __webpack_exports__["a"] = (colorUtil);

/***/ }),
/* 114 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/**
 * Simple double linked list. Compared with array, it has O(1) remove operation.
 * @constructor
 * @alias clay.core.LinkedList
 */
var LinkedList = function () {

    /**
     * @type {clay.core.LinkedList.Entry}
     */
    this.head = null;

    /**
     * @type {clay.core.LinkedList.Entry}
     */
    this.tail = null;

    this._length = 0;
};

/**
 * Insert a new value at the tail
 * @param  {} val
 * @return {clay.core.LinkedList.Entry}
 */
LinkedList.prototype.insert = function (val) {
    var entry = new LinkedList.Entry(val);
    this.insertEntry(entry);
    return entry;
};

/**
 * Insert a new value at idx
 * @param {number} idx
 * @param  {} val
 * @return {clay.core.LinkedList.Entry}
 */
LinkedList.prototype.insertAt = function (idx, val) {
    if (idx < 0) {
        return;
    }
    var next = this.head;
    var cursor = 0;
    while (next && cursor != idx) {
        next = next.next;
        cursor++;
    }
    if (next) {
        var entry = new LinkedList.Entry(val);
        var prev = next.prev;
        if (!prev) { //next is head
            this.head = entry;
        }
        else {
            prev.next = entry;
            entry.prev = prev;
        }
        entry.next = next;
        next.prev = entry;
    }
    else {
        this.insert(val);
    }
};

LinkedList.prototype.insertBeforeEntry = function (val, next) {
    var entry = new LinkedList.Entry(val);
    var prev = next.prev;
    if (!prev) { //next is head
        this.head = entry;
    }
    else {
        prev.next = entry;
        entry.prev = prev;
    }
    entry.next = next;
    next.prev = entry;

    this._length++;
};

/**
 * Insert an entry at the tail
 * @param  {clay.core.LinkedList.Entry} entry
 */
LinkedList.prototype.insertEntry = function (entry) {
    if (!this.head) {
        this.head = this.tail = entry;
    }
    else {
        this.tail.next = entry;
        entry.prev = this.tail;
        this.tail = entry;
    }
    this._length++;
};

/**
 * Remove entry.
 * @param  {clay.core.LinkedList.Entry} entry
 */
LinkedList.prototype.remove = function (entry) {
    var prev = entry.prev;
    var next = entry.next;
    if (prev) {
        prev.next = next;
    }
    else {
        // Is head
        this.head = next;
    }
    if (next) {
        next.prev = prev;
    }
    else {
        // Is tail
        this.tail = prev;
    }
    entry.next = entry.prev = null;
    this._length--;
};

/**
 * Remove entry at index.
 * @param  {number} idx
 * @return {}
 */
LinkedList.prototype.removeAt = function (idx) {
    if (idx < 0) {
        return;
    }
    var curr = this.head;
    var cursor = 0;
    while (curr && cursor != idx) {
        curr = curr.next;
        cursor++;
    }
    if (curr) {
        this.remove(curr);
        return curr.value;
    }
};
/**
 * Get head value
 * @return {}
 */
LinkedList.prototype.getHead = function () {
    if (this.head) {
        return this.head.value;
    }
};
/**
 * Get tail value
 * @return {}
 */
LinkedList.prototype.getTail = function () {
    if (this.tail) {
        return this.tail.value;
    }
};
/**
 * Get value at idx
 * @param {number} idx
 * @return {}
 */
LinkedList.prototype.getAt = function (idx) {
    if (idx < 0) {
        return;
    }
    var curr = this.head;
    var cursor = 0;
    while (curr && cursor != idx) {
        curr = curr.next;
        cursor++;
    }
    return curr.value;
};

/**
 * @param  {} value
 * @return {number}
 */
LinkedList.prototype.indexOf = function (value) {
    var curr = this.head;
    var cursor = 0;
    while (curr) {
        if (curr.value === value) {
            return cursor;
        }
        curr = curr.next;
        cursor++;
    }
};

/**
 * @return {number}
 */
LinkedList.prototype.length = function () {
    return this._length;
};

/**
 * If list is empty
 */
LinkedList.prototype.isEmpty = function () {
    return this._length === 0;
};

/**
 * @param  {Function} cb
 * @param  {} context
 */
LinkedList.prototype.forEach = function (cb, context) {
    var curr = this.head;
    var idx = 0;
    var haveContext = typeof(context) != 'undefined';
    while (curr) {
        if (haveContext) {
            cb.call(context, curr.value, idx);
        }
        else {
            cb(curr.value, idx);
        }
        curr = curr.next;
        idx++;
    }
};

/**
 * Clear the list
 */
LinkedList.prototype.clear = function () {
    this.tail = this.head = null;
    this._length = 0;
};

/**
 * @constructor
 * @param {} val
 */
LinkedList.Entry = function (val) {
    /**
     * @type {}
     */
    this.value = val;

    /**
     * @type {clay.core.LinkedList.Entry}
     */
    this.next = null;

    /**
     * @type {clay.core.LinkedList.Entry}
     */
    this.prev = null;
};

/* harmony default export */ __webpack_exports__["a"] = (LinkedList);


/***/ }),
/* 115 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__GLProgram__ = __webpack_require__(116);


var loopRegex = /for\s*?\(int\s*?_idx_\s*\=\s*([\w-]+)\;\s*_idx_\s*<\s*([\w-]+);\s*_idx_\s*\+\+\s*\)\s*\{\{([\s\S]+?)(?=\}\})\}\}/g;

function unrollLoop(shaderStr, defines, lightsNumbers) {
    // Loop unroll from three.js, https://github.com/mrdoob/three.js/blob/master/src/renderers/webgl/WebGLProgram.js#L175
    // In some case like shadowMap in loop use 'i' to index value much slower.

    // Loop use _idx_ and increased with _idx_++ will be unrolled
    // Use {{ }} to match the pair so the if statement will not be affected
    // Write like following
    // for (int _idx_ = 0; _idx_ < 4; _idx_++) {{
    //     vec3 color = texture2D(textures[_idx_], uv).rgb;
    // }}
    function replace(match, start, end, snippet) {
        var unroll = '';
        // Try to treat as define
        if (isNaN(start)) {
            if (start in defines) {
                start = defines[start];
            }
            else {
                start = lightNumberDefines[start];
            }
        }
        if (isNaN(end)) {
            if (end in defines) {
                end = defines[end];
            }
            else {
                end = lightNumberDefines[end];
            }
        }
        // TODO Error checking

        for (var idx = parseInt(start); idx < parseInt(end); idx++) {
            // PENDING Add scope?
            unroll += '{'
                + snippet
                    .replace(/float\s*\(\s*_idx_\s*\)/g, idx.toFixed(1))
                    .replace(/_idx_/g, idx)
            + '}';
        }

        return unroll;
    }

    var lightNumberDefines = {};
    for (var lightType in lightsNumbers) {
        lightNumberDefines[lightType + '_COUNT'] = lightsNumbers[lightType];
    }
    return shaderStr.replace(loopRegex, replace);
}

function getDefineCode(defines, lightsNumbers, enabledTextures) {
    var defineStr = [];
    if (lightsNumbers) {
        for (var lightType in lightsNumbers) {
            var count = lightsNumbers[lightType];
            if (count > 0) {
                defineStr.push('#define ' + lightType.toUpperCase() + '_COUNT ' + count);
            }
        }
    }
    if (enabledTextures) {
        for (var i = 0; i < enabledTextures.length; i++) {
            var symbol = enabledTextures[i];
            defineStr.push('#define ' + symbol.toUpperCase() + '_ENABLED');
        }
    }
    // Custom Defines
    for (var symbol in defines) {
        var value = defines[symbol];
        if (value === null) {
            defineStr.push('#define ' + symbol);
        }
        else{
            defineStr.push('#define ' + symbol + ' ' + value.toString());
        }
    }
    return defineStr.join('\n');
}

function getExtensionCode(exts) {
    // Extension declaration must before all non-preprocessor codes
    // TODO vertex ? extension enum ?
    var extensionStr = [];
    for (var i = 0; i < exts.length; i++) {
        extensionStr.push('#extension GL_' + exts[i] + ' : enable');
    }
    return extensionStr.join('\n');
}

function getPrecisionCode(precision) {
    return ['precision', precision, 'float'].join(' ') + ';\n'
        + ['precision', precision, 'int'].join(' ') + ';\n'
        // depth texture may have precision problem on iOS device.
        + ['precision', precision, 'sampler2D'].join(' ') + ';\n';
}

function ProgramManager(renderer) {
    this._renderer = renderer;
    this._cache = {};
}

ProgramManager.prototype.getProgram = function (renderable, material, scene) {
    var cache = this._cache;

    var isSkinnedMesh = renderable.isSkinnedMesh && renderable.isSkinnedMesh();
    var key = 's' + material.shader.shaderID + 'm' + material.getProgramKey();
    if (scene) {
        key += 'se' + scene.getProgramKey(renderable.lightGroup);
    }
    if (isSkinnedMesh) {
        key += ',' + renderable.joints.length;
    }
    var program = cache[key];

    if (program) {
        return program;
    }

    var lightsNumbers = scene ? scene.getLightsNumbers(renderable.lightGroup) : {};
    var renderer = this._renderer;
    var _gl = renderer.gl;
    var enabledTextures = material.getEnabledTextures();
    var skinDefineCode = '';
    if (isSkinnedMesh) {
        var skinDefines = {
            SKINNING: null,
            JOINT_COUNT: renderable.joints.length
        };
        if (renderable.joints.length > renderer.getMaxJointNumber()) {
            skinDefines.USE_SKIN_MATRICES_TEXTURE = null;
        }
        // TODO Add skinning code?
        skinDefineCode = '\n' + getDefineCode(skinDefines) + '\n';
    }
    // TODO Optimize key generation
    // VERTEX
    var vertexDefineStr = skinDefineCode + getDefineCode(material.vertexDefines, lightsNumbers, enabledTextures);
    // FRAGMENT
    var fragmentDefineStr = skinDefineCode + getDefineCode(material.fragmentDefines, lightsNumbers, enabledTextures);

    var vertexCode = vertexDefineStr + '\n' + material.shader.vertex;

    var extensions = [
        'OES_standard_derivatives',
        'EXT_shader_texture_lod'
    ].filter(function (ext) {
        return renderer.getGLExtension(ext) != null;
    });

    if (extensions.indexOf('EXT_shader_texture_lod') >= 0) {
        fragmentDefineStr += '\n#define SUPPORT_TEXTURE_LOD';
    }
    if (extensions.indexOf('OES_standard_derivatives') >= 0) {
        fragmentDefineStr += '\n#define SUPPORT_STANDARD_DERIVATIVES';
    }

    var fragmentCode = getExtensionCode(extensions) + '\n'
        + getPrecisionCode(material.precision) + '\n'
        + fragmentDefineStr + '\n'
        + material.shader.fragment;

    var finalVertexCode = unrollLoop(vertexCode, material.vertexDefines, lightsNumbers);
    var finalFragmentCode = unrollLoop(fragmentCode, material.fragmentDefines, lightsNumbers);

    var program = new __WEBPACK_IMPORTED_MODULE_0__GLProgram__["a" /* default */]();
    program.uniformSemantics = material.shader.uniformSemantics;
    program.attributes = material.shader.attributes;
    var errorMsg = program.buildProgram(_gl, material.shader, finalVertexCode, finalFragmentCode);
    program.__error = errorMsg;

    cache[key] = program;

    return program;
};

/* harmony default export */ __webpack_exports__["a"] = (ProgramManager);

/***/ }),
/* 116 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_vendor__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_Base__ = __webpack_require__(7);



var SHADER_STATE_TO_ENABLE = 1;
var SHADER_STATE_KEEP_ENABLE = 2;
var SHADER_STATE_PENDING = 3;

// Enable attribute operation is global to all programs
// Here saved the list of all enabled attribute index
// http://www.mjbshaw.com/2013/03/webgl-fixing-invalidoperation.html
var enabledAttributeList = {};

// some util functions
function addLineNumbers(string) {
    var chunks = string.split('\n');
    for (var i = 0, il = chunks.length; i < il; i ++) {
        // Chrome reports shader errors on lines
        // starting counting from 1
        chunks[i] = (i + 1) + ': ' + chunks[i];
    }
    return chunks.join('\n');
}

// Return true or error msg if error happened
function checkShaderErrorMsg(_gl, shader, shaderString) {
    if (!_gl.getShaderParameter(shader, _gl.COMPILE_STATUS)) {
        return [_gl.getShaderInfoLog(shader), addLineNumbers(shaderString)].join('\n');
    }
}

var tmpFloat32Array16 = new __WEBPACK_IMPORTED_MODULE_0__core_vendor__["a" /* default */].Float32Array(16);

var GLProgram = __WEBPACK_IMPORTED_MODULE_1__core_Base__["a" /* default */].extend({

    uniformSemantics: {},
    attributes: {}

}, function () {
    this._locations = {};

    this._textureSlot = 0;

    this._program = null;
}, {

    bind: function (renderer) {
        this._textureSlot = 0;
        renderer.gl.useProgram(this._program);
    },

    hasUniform: function (symbol) {
        var location = this._locations[symbol];
        return location !== null && location !== undefined;
    },

    useTextureSlot: function (renderer, texture, slot) {
        if (texture) {
            renderer.gl.activeTexture(renderer.gl.TEXTURE0 + slot);
            // Maybe texture is not loaded yet;
            if (texture.isRenderable()) {
                texture.bind(renderer);
            }
            else {
                // Bind texture to null
                texture.unbind(renderer);
            }
        }
    },

    currentTextureSlot: function () {
        return this._textureSlot;
    },

    resetTextureSlot: function (slot) {
        this._textureSlot = slot || 0;
    },

    takeCurrentTextureSlot: function (renderer, texture) {
        var textureSlot = this._textureSlot;

        this.useTextureSlot(renderer, texture, textureSlot);

        this._textureSlot++;

        return textureSlot;
    },

    setUniform: function (_gl, type, symbol, value) {
        var locationMap = this._locations;
        var location = locationMap[symbol];
        // Uniform is not existed in the shader
        if (location === null || location === undefined) {
            return false;
        }

        switch (type) {
            case 'm4':
                if (!(value instanceof Float32Array)) {
                    // Use Float32Array is much faster than array when uniformMatrix4fv.
                    for (var i = 0; i < value.length; i++) {
                        tmpFloat32Array16[i] = value[i];
                    }
                    value = tmpFloat32Array16;
                }
                _gl.uniformMatrix4fv(location, false, value);
                break;
            case '2i':
                _gl.uniform2i(location, value[0], value[1]);
                break;
            case '2f':
                _gl.uniform2f(location, value[0], value[1]);
                break;
            case '3i':
                _gl.uniform3i(location, value[0], value[1], value[2]);
                break;
            case '3f':
                _gl.uniform3f(location, value[0], value[1], value[2]);
                break;
            case '4i':
                _gl.uniform4i(location, value[0], value[1], value[2], value[3]);
                break;
            case '4f':
                _gl.uniform4f(location, value[0], value[1], value[2], value[3]);
                break;
            case '1i':
                _gl.uniform1i(location, value);
                break;
            case '1f':
                _gl.uniform1f(location, value);
                break;
            case '1fv':
                _gl.uniform1fv(location, value);
                break;
            case '1iv':
                _gl.uniform1iv(location, value);
                break;
            case '2iv':
                _gl.uniform2iv(location, value);
                break;
            case '2fv':
                _gl.uniform2fv(location, value);
                break;
            case '3iv':
                _gl.uniform3iv(location, value);
                break;
            case '3fv':
                _gl.uniform3fv(location, value);
                break;
            case '4iv':
                _gl.uniform4iv(location, value);
                break;
            case '4fv':
                _gl.uniform4fv(location, value);
                break;
            case 'm2':
            case 'm2v':
                _gl.uniformMatrix2fv(location, false, value);
                break;
            case 'm3':
            case 'm3v':
                _gl.uniformMatrix3fv(location, false, value);
                break;
            case 'm4v':
                // Raw value
                if (Array.isArray(value) && Array.isArray(value[0])) {
                    var array = new __WEBPACK_IMPORTED_MODULE_0__core_vendor__["a" /* default */].Float32Array(value.length * 16);
                    var cursor = 0;
                    for (var i = 0; i < value.length; i++) {
                        var item = value[i];
                        for (var j = 0; j < 16; j++) {
                            array[cursor++] = item[j];
                        }
                    }
                    _gl.uniformMatrix4fv(location, false, array);
                }
                else {   // ArrayBufferView
                    _gl.uniformMatrix4fv(location, false, value);
                }
                break;
        }
        return true;
    },

    setUniformOfSemantic: function (_gl, semantic, val) {
        var semanticInfo = this.uniformSemantics[semantic];
        if (semanticInfo) {
            return this.setUniform(_gl, semanticInfo.type, semanticInfo.symbol, val);
        }
        return false;
    },

    // Used for creating VAO
    // Enable the attributes passed in and disable the rest
    // Example Usage:
    // enableAttributes(renderer, ["position", "texcoords"])
    enableAttributes: function (renderer, attribList, vao) {
        var _gl = renderer.gl;
        var program = this._program;

        var locationMap = this._locations;

        var enabledAttributeListInContext;
        if (vao) {
            enabledAttributeListInContext = vao.__enabledAttributeList;
        }
        else {
            enabledAttributeListInContext = enabledAttributeList[renderer.__uid__];
        }
        if (!enabledAttributeListInContext) {
            // In vertex array object context
            // PENDING Each vao object needs to enable attributes again?
            if (vao) {
                enabledAttributeListInContext
                    = vao.__enabledAttributeList
                    = [];
            }
            else {
                enabledAttributeListInContext
                    = enabledAttributeList[renderer.__uid__]
                    = [];
            }
        }
        var locationList = [];
        for (var i = 0; i < attribList.length; i++) {
            var symbol = attribList[i];
            if (!this.attributes[symbol]) {
                locationList[i] = -1;
                continue;
            }
            var location = locationMap[symbol];
            if (location == null) {
                location = _gl.getAttribLocation(program, symbol);
                // Attrib location is a number from 0 to ...
                if (location === -1) {
                    locationList[i] = -1;
                    continue;
                }
                locationMap[symbol] = location;
            }
            locationList[i] = location;

            if (!enabledAttributeListInContext[location]) {
                enabledAttributeListInContext[location] = SHADER_STATE_TO_ENABLE;
            }
            else {
                enabledAttributeListInContext[location] = SHADER_STATE_KEEP_ENABLE;
            }
        }

        for (var i = 0; i < enabledAttributeListInContext.length; i++) {
            switch(enabledAttributeListInContext[i]){
                case SHADER_STATE_TO_ENABLE:
                    _gl.enableVertexAttribArray(i);
                    enabledAttributeListInContext[i] = SHADER_STATE_PENDING;
                    break;
                case SHADER_STATE_KEEP_ENABLE:
                    enabledAttributeListInContext[i] = SHADER_STATE_PENDING;
                    break;
                // Expired
                case SHADER_STATE_PENDING:
                    _gl.disableVertexAttribArray(i);
                    enabledAttributeListInContext[i] = 0;
                    break;
            }
        }

        return locationList;
    },

    buildProgram: function (_gl, shader, vertexShaderCode, fragmentShaderCode) {
        var vertexShader = _gl.createShader(_gl.VERTEX_SHADER);
        var program = _gl.createProgram();

        _gl.shaderSource(vertexShader, vertexShaderCode);
        _gl.compileShader(vertexShader);

        var fragmentShader = _gl.createShader(_gl.FRAGMENT_SHADER);
        _gl.shaderSource(fragmentShader, fragmentShaderCode);
        _gl.compileShader(fragmentShader);

        var msg = checkShaderErrorMsg(_gl, vertexShader, vertexShaderCode);
        if (msg) {
            return msg;
        }
        msg = checkShaderErrorMsg(_gl, fragmentShader, fragmentShaderCode);
        if (msg) {
            return msg;
        }

        _gl.attachShader(program, vertexShader);
        _gl.attachShader(program, fragmentShader);
        // Force the position bind to location 0;
        if (shader.attributeSemantics['POSITION']) {
            _gl.bindAttribLocation(program, 0, shader.attributeSemantics['POSITION'].symbol);
        }
        else {
            // Else choose an attribute and bind to location 0;
            var keys = Object.keys(this.attributes);
            _gl.bindAttribLocation(program, 0, keys[0]);
        }

        _gl.linkProgram(program);

        if (!_gl.getProgramParameter(program, _gl.LINK_STATUS)) {
            return 'Could not link program\n' + _gl.getProgramInfoLog(program);
        }

        // Cache uniform locations
        for (var i = 0; i < shader.uniforms.length; i++) {
            var uniformSymbol = shader.uniforms[i];
            this._locations[uniformSymbol] = _gl.getUniformLocation(program, uniformSymbol);
        }

        _gl.deleteShader(vertexShader);
        _gl.deleteShader(fragmentShader);

        this._program = program;

        // Save code.
        this.vertexCode = vertexShaderCode;
        this.fragmentCode = fragmentShaderCode;
    }
});

/* harmony default export */ __webpack_exports__["a"] = (GLProgram);

/***/ }),
/* 117 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_Ray__ = __webpack_require__(54);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__math_Vector2__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Renderable__ = __webpack_require__(72);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__glmatrix_vec3__ = __webpack_require__(12);









/**
 * @constructor clay.picking.RayPicking
 * @extends clay.core.Base
 */
var RayPicking = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(/** @lends clay.picking.RayPicking# */{
    /**
     * Target scene
     * @type {clay.Scene}
     */
    scene: null,
    /**
     * Target camera
     * @type {clay.Camera}
     */
    camera: null,
    /**
     * Target renderer
     * @type {clay.Renderer}
     */
    renderer: null
}, function () {
    this._ray = new __WEBPACK_IMPORTED_MODULE_1__math_Ray__["a" /* default */]();
    this._ndc = new __WEBPACK_IMPORTED_MODULE_2__math_Vector2__["a" /* default */]();
},
/** @lends clay.picking.RayPicking.prototype */
{

    /**
     * Pick the nearest intersection object in the scene
     * @param  {number} x Mouse position x
     * @param  {number} y Mouse position y
     * @param  {boolean} [forcePickAll=false] ignore ignorePicking
     * @return {clay.picking.RayPicking~Intersection}
     */
    pick: function (x, y, forcePickAll) {
        var out = this.pickAll(x, y, [], forcePickAll);
        return out[0] || null;
    },

    /**
     * Pick all intersection objects, wich will be sorted from near to far
     * @param  {number} x Mouse position x
     * @param  {number} y Mouse position y
     * @param  {Array} [output]
     * @param  {boolean} [forcePickAll=false] ignore ignorePicking
     * @return {Array.<clay.picking.RayPicking~Intersection>}
     */
    pickAll: function (x, y, output, forcePickAll) {
        this.renderer.screenToNDC(x, y, this._ndc);
        this.camera.castRay(this._ndc, this._ray);

        output = output || [];

        this._intersectNode(this.scene, output, forcePickAll || false);

        output.sort(this._intersectionCompareFunc);

        return output;
    },

    _intersectNode: function (node, out, forcePickAll) {
        if ((node instanceof __WEBPACK_IMPORTED_MODULE_5__Renderable__["a" /* default */]) && node.isRenderable()) {
            if ((!node.ignorePicking || forcePickAll)
                && (
                    // Only triangle mesh support ray picking
                    (node.mode === __WEBPACK_IMPORTED_MODULE_6__core_glenum__["a" /* default */].TRIANGLES && node.geometry.isUseIndices())
                    // Or if geometry has it's own pickByRay, pick, implementation
                    || node.geometry.pickByRay
                    || node.geometry.pick
                )
            ) {
                this._intersectRenderable(node, out);
            }
        }
        for (var i = 0; i < node._children.length; i++) {
            this._intersectNode(node._children[i], out, forcePickAll);
        }
    },

    _intersectRenderable: (function () {

        var v1 = new __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */]();
        var v2 = new __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */]();
        var v3 = new __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */]();
        var ray = new __WEBPACK_IMPORTED_MODULE_1__math_Ray__["a" /* default */]();
        var worldInverse = new __WEBPACK_IMPORTED_MODULE_4__math_Matrix4__["a" /* default */]();

        return function (renderable, out) {

            var isSkinnedMesh = renderable.isSkinnedMesh();
            ray.copy(this._ray);
            __WEBPACK_IMPORTED_MODULE_4__math_Matrix4__["a" /* default */].invert(worldInverse, renderable.worldTransform);

            // Skinned mesh will ignore the world transform.
            if (!isSkinnedMesh) {
                ray.applyTransform(worldInverse);
            }

            var geometry = renderable.geometry;

            var bbox = isSkinnedMesh ? renderable.skeleton.boundingBox : geometry.boundingBox;

            if (bbox && !ray.intersectBoundingBox(bbox)) {
                return;
            }
            // Use user defined picking algorithm
            if (geometry.pick) {
                geometry.pick(
                    this._ndc.x, this._ndc.y,
                    this.renderer,
                    this.camera,
                    renderable, out
                );
                return;
            }
            // Use user defined ray picking algorithm
            else if (geometry.pickByRay) {
                geometry.pickByRay(ray, renderable, out);
                return;
            }

            var cullBack = (renderable.cullFace === __WEBPACK_IMPORTED_MODULE_6__core_glenum__["a" /* default */].BACK && renderable.frontFace === __WEBPACK_IMPORTED_MODULE_6__core_glenum__["a" /* default */].CCW)
                        || (renderable.cullFace === __WEBPACK_IMPORTED_MODULE_6__core_glenum__["a" /* default */].FRONT && renderable.frontFace === __WEBPACK_IMPORTED_MODULE_6__core_glenum__["a" /* default */].CW);

            var point;
            var indices = geometry.indices;
            var positionAttr = geometry.attributes.position;
            var weightAttr = geometry.attributes.weight;
            var jointAttr = geometry.attributes.joint;
            var skinMatricesArray;
            var skinMatrices = [];
            // Check if valid.
            if (!positionAttr || !positionAttr.value || !indices) {
                return;
            }
            if (isSkinnedMesh) {
                skinMatricesArray = renderable.skeleton.getSubSkinMatrices(renderable.__uid__, renderable.joints);
                for (var i = 0; i < renderable.joints.length; i++) {
                    skinMatrices[i] = skinMatrices[i] || [];
                    for (var k = 0; k < 16; k++) {
                        skinMatrices[i][k] = skinMatricesArray[i * 16 + k];
                    }
                }
                var pos = [];
                var weight = [];
                var joint = [];
                var skinnedPos = [];
                var tmp = [];
                var skinnedPositionAttr = geometry.attributes.skinnedPosition;
                if (!skinnedPositionAttr || !skinnedPositionAttr.value) {
                    geometry.createAttribute('skinnedPosition', 'f', 3);
                    skinnedPositionAttr = geometry.attributes.skinnedPosition;
                    skinnedPositionAttr.init(geometry.vertexCount);
                }
                for (var i = 0; i < geometry.vertexCount; i++) {
                    positionAttr.get(i, pos);
                    weightAttr.get(i, weight);
                    jointAttr.get(i, joint);
                    weight[3] = 1 - weight[0] - weight[1] - weight[2];
                    __WEBPACK_IMPORTED_MODULE_7__glmatrix_vec3__["a" /* default */].set(skinnedPos, 0, 0, 0);
                    for (var k = 0; k < 4; k++) {
                        if (joint[k] >= 0 && weight[k] > 1e-4) {
                            __WEBPACK_IMPORTED_MODULE_7__glmatrix_vec3__["a" /* default */].transformMat4(tmp, pos, skinMatrices[joint[k]]);
                            __WEBPACK_IMPORTED_MODULE_7__glmatrix_vec3__["a" /* default */].scaleAndAdd(skinnedPos, skinnedPos, tmp, weight[k]);
                        }
                    }
                    skinnedPositionAttr.set(i, skinnedPos);
                }
            }

            for (var i = 0; i < indices.length; i += 3) {
                var i1 = indices[i];
                var i2 = indices[i + 1];
                var i3 = indices[i + 2];
                var finalPosAttr = isSkinnedMesh
                    ? geometry.attributes.skinnedPosition
                    : positionAttr;
                finalPosAttr.get(i1, v1.array);
                finalPosAttr.get(i2, v2.array);
                finalPosAttr.get(i3, v3.array);

                if (cullBack) {
                    point = ray.intersectTriangle(v1, v2, v3, renderable.culling);
                }
                else {
                    point = ray.intersectTriangle(v1, v3, v2, renderable.culling);
                }
                if (point) {
                    var pointW = new __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */]();
                    if (!isSkinnedMesh) {
                        __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].transformMat4(pointW, point, renderable.worldTransform);
                    }
                    else {
                        // TODO point maybe not right.
                        __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].copy(pointW, point);
                    }
                    out.push(new RayPicking.Intersection(
                        point, pointW, renderable, [i1, i2, i3], i / 3,
                        __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].dist(pointW, this._ray.origin)
                    ));
                }
            }
        };
    })(),

    _intersectionCompareFunc: function (a, b) {
        return a.distance - b.distance;
    }
});

/**
 * @constructor clay.picking.RayPicking~Intersection
 * @param {clay.Vector3} point
 * @param {clay.Vector3} pointWorld
 * @param {clay.Node} target
 * @param {Array.<number>} triangle
 * @param {number} triangleIndex
 * @param {number} distance
 */
RayPicking.Intersection = function (point, pointWorld, target, triangle, triangleIndex, distance) {
    /**
     * Intersection point in local transform coordinates
     * @type {clay.Vector3}
     */
    this.point = point;
    /**
     * Intersection point in world transform coordinates
     * @type {clay.Vector3}
     */
    this.pointWorld = pointWorld;
    /**
     * Intersection scene node
     * @type {clay.Node}
     */
    this.target = target;
    /**
     * Intersection triangle, which is an array of vertex index
     * @type {Array.<number>}
     */
    this.triangle = triangle;
    /**
     * Index of intersection triangle.
     */
    this.triangleIndex = triangleIndex;
    /**
     * Distance from intersection point to ray origin
     * @type {number}
     */
    this.distance = distance;
};

/* harmony default export */ __webpack_exports__["a"] = (RayPicking);


/***/ }),
/* 118 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_Cache__ = __webpack_require__(57);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_vendor__ = __webpack_require__(14);





function getArrayCtorByType (type) {
    return ({
        'byte': __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Int8Array,
        'ubyte': __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Uint8Array,
        'short': __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Int16Array,
        'ushort': __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Uint16Array
    })[type] || __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Float32Array;
}

function makeAttrKey(attrName) {
    return 'attr_' + attrName;
}
/**
 * GeometryBase attribute
 * @alias clay.GeometryBase.Attribute
 * @constructor
 */
function Attribute(name, type, size, semantic) {
    /**
     * Attribute name
     * @type {string}
     */
    this.name = name;
    /**
     * Attribute type
     * Possible values:
     *  + `'byte'`
     *  + `'ubyte'`
     *  + `'short'`
     *  + `'ushort'`
     *  + `'float'` Most commonly used.
     * @type {string}
     */
    this.type = type;
    /**
     * Size of attribute component. 1 - 4.
     * @type {number}
     */
    this.size = size;
    /**
     * Semantic of this attribute.
     * Possible values:
     *  + `'POSITION'`
     *  + `'NORMAL'`
     *  + `'BINORMAL'`
     *  + `'TANGENT'`
     *  + `'TEXCOORD'`
     *  + `'TEXCOORD_0'`
     *  + `'TEXCOORD_1'`
     *  + `'COLOR'`
     *  + `'JOINT'`
     *  + `'WEIGHT'`
     *
     * In shader, attribute with same semantic will be automatically mapped. For example:
     * ```glsl
     * attribute vec3 pos: POSITION
     * ```
     * will use the attribute value with semantic POSITION in geometry, no matter what name it used.
     * @type {string}
     */
    this.semantic = semantic || '';

    /**
     * Value of the attribute.
     * @type {TypedArray}
     */
    this.value = null;

    // Init getter setter
    switch (size) {
        case 1:
            this.get = function (idx) {
                return this.value[idx];
            };
            this.set = function (idx, value) {
                this.value[idx] = value;
            };
            // Copy from source to target
            this.copy = function (target, source) {
                this.value[target] = this.value[target];
            };
            break;
        case 2:
            this.get = function (idx, out) {
                var arr = this.value;
                out[0] = arr[idx * 2];
                out[1] = arr[idx * 2 + 1];
                return out;
            };
            this.set = function (idx, val) {
                var arr = this.value;
                arr[idx * 2] = val[0];
                arr[idx * 2 + 1] = val[1];
            };
            this.copy = function (target, source) {
                var arr = this.value;
                source *= 2;
                target *= 2;
                arr[target] = arr[source];
                arr[target + 1] = arr[source + 1];
            };
            break;
        case 3:
            this.get = function (idx, out) {
                var idx3 = idx * 3;
                var arr = this.value;
                out[0] = arr[idx3];
                out[1] = arr[idx3 + 1];
                out[2] = arr[idx3 + 2];
                return out;
            };
            this.set = function (idx, val) {
                var idx3 = idx * 3;
                var arr = this.value;
                arr[idx3] = val[0];
                arr[idx3 + 1] = val[1];
                arr[idx3 + 2] = val[2];
            };
            this.copy = function (target, source) {
                var arr = this.value;
                source *= 3;
                target *= 3;
                arr[target] = arr[source];
                arr[target + 1] = arr[source + 1];
                arr[target + 2] = arr[source + 2];
            };
            break;
        case 4:
            this.get = function (idx, out) {
                var arr = this.value;
                var idx4 = idx * 4;
                out[0] = arr[idx4];
                out[1] = arr[idx4 + 1];
                out[2] = arr[idx4 + 2];
                out[3] = arr[idx4 + 3];
                return out;
            };
            this.set = function (idx, val) {
                var arr = this.value;
                var idx4 = idx * 4;
                arr[idx4] = val[0];
                arr[idx4 + 1] = val[1];
                arr[idx4 + 2] = val[2];
                arr[idx4 + 3] = val[3];
            };
            this.copy = function (target, source) {
                var arr = this.value;
                source *= 4;
                target *= 4;
                // copyWithin is extremely slow
                arr[target] = arr[source];
                arr[target + 1] = arr[source + 1];
                arr[target + 2] = arr[source + 2];
                arr[target + 3] = arr[source + 3];
            };
    }
}

/**
 * Set item value at give index. Second parameter val is number if size is 1
 * @function
 * @name clay.GeometryBase.Attribute#set
 * @param {number} idx
 * @param {number[]|number} val
 * @example
 * geometry.getAttribute('position').set(0, [1, 1, 1]);
 */

/**
 * Get item value at give index. Second parameter out is no need if size is 1
 * @function
 * @name clay.GeometryBase.Attribute#set
 * @param {number} idx
 * @param {number[]} [out]
 * @example
 * geometry.getAttribute('position').get(0, out);
 */

/**
 * Initialize attribute with given vertex count
 * @param {number} nVertex
 */
Attribute.prototype.init = function (nVertex) {
    if (!this.value || this.value.length != nVertex * this.size) {
        var ArrayConstructor = getArrayCtorByType(this.type);
        this.value = new ArrayConstructor(nVertex * this.size);
    }
};

/**
 * Initialize attribute with given array. Which can be 1 dimensional or 2 dimensional
 * @param {Array} array
 * @example
 *  geometry.getAttribute('position').fromArray(
 *      [-1, 0, 0, 1, 0, 0, 0, 1, 0]
 *  );
 *  geometry.getAttribute('position').fromArray(
 *      [ [-1, 0, 0], [1, 0, 0], [0, 1, 0] ]
 *  );
 */
Attribute.prototype.fromArray = function (array) {
    var ArrayConstructor = getArrayCtorByType(this.type);
    var value;
    // Convert 2d array to flat
    if (array[0] && (array[0].length)) {
        var n = 0;
        var size = this.size;
        value = new ArrayConstructor(array.length * size);
        for (var i = 0; i < array.length; i++) {
            for (var j = 0; j < size; j++) {
                value[n++] = array[i][j];
            }
        }
    }
    else {
        value = new ArrayConstructor(array);
    }
    this.value = value;
};

Attribute.prototype.clone = function(copyValue) {
    var ret = new Attribute(this.name, this.type, this.size, this.semantic);
    // FIXME
    if (copyValue) {
        console.warn('todo');
    }
    return ret;
};

function AttributeBuffer(name, type, buffer, size, semantic) {
    this.name = name;
    this.type = type;
    this.buffer = buffer;
    this.size = size;
    this.semantic = semantic;

    // To be set in mesh
    // symbol in the shader
    this.symbol = '';

    // Needs remove flag
    this.needsRemove = false;
}

function IndicesBuffer(buffer) {
    this.buffer = buffer;
    this.count = 0;
}

/**
 * Base of all geometry. Use {@link clay.Geometry} for common 3D usage.
 * @constructor clay.GeometryBase
 * @extends clay.core.Base
 */
var GeometryBase = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
    return /** @lends clay.GeometryBase# */ {
        /**
         * Attributes of geometry.
         * @type {Object.<string, clay.GeometryBase.Attribute>}
         */
        attributes: {},

        /**
         * Indices of geometry.
         * @type {Uint16Array|Uint32Array}
         */
        indices: null,

        /**
         * Is vertices data dynamically updated.
         * Attributes value can't be changed after first render if dyanmic is false.
         * @type {boolean}
         */
        dynamic: true,

        _enabledAttributes: null,

        // PENDING
        // Init it here to avoid deoptimization when it's assigned in application dynamically
        __used: 0
    };
}, function() {
    // Use cache
    this._cache = new __WEBPACK_IMPORTED_MODULE_2__core_Cache__["a" /* default */]();

    this._attributeList = Object.keys(this.attributes);

    this.__vaoCache = {};
},
/** @lends clay.GeometryBase.prototype */
{
    /**
     * Main attribute will be used to count vertex number
     * @type {string}
     */
    mainAttribute: '',
    /**
     * User defined picking algorithm instead of default
     * triangle ray intersection
     * x, y are NDC.
     * ```typescript
     * (x, y, renderer, camera, renderable, out) => boolean
     * ```
     * @type {?Function}
     */
    pick: null,

    /**
     * User defined ray picking algorithm instead of default
     * triangle ray intersection
     * ```typescript
     * (ray: clay.Ray, renderable: clay.Renderable, out: Array) => boolean
     * ```
     * @type {?Function}
     */
    pickByRay: null,

    /**
     * Mark attributes and indices in geometry needs to update.
     * Usually called after you change the data in attributes.
     */
    dirty: function () {
        var enabledAttributes = this.getEnabledAttributes();
        for (var i = 0; i < enabledAttributes.length; i++) {
            this.dirtyAttribute(enabledAttributes[i]);
        }
        this.dirtyIndices();
        this._enabledAttributes = null;

        this._cache.dirty('any');
    },
    /**
     * Mark the indices needs to update.
     */
    dirtyIndices: function () {
        this._cache.dirtyAll('indices');
    },
    /**
     * Mark the attributes needs to update.
     * @param {string} [attrName]
     */
    dirtyAttribute: function (attrName) {
        this._cache.dirtyAll(makeAttrKey(attrName));
        this._cache.dirtyAll('attributes');
    },
    /**
     * Get indices of triangle at given index.
     * @param {number} idx
     * @param {Array.<number>} out
     * @return {Array.<number>}
     */
    getTriangleIndices: function (idx, out) {
        if (idx < this.triangleCount && idx >= 0) {
            if (!out) {
                out = [];
            }
            var indices = this.indices;
            out[0] = indices[idx * 3];
            out[1] = indices[idx * 3 + 1];
            out[2] = indices[idx * 3 + 2];
            return out;
        }
    },

    /**
     * Set indices of triangle at given index.
     * @param {number} idx
     * @param {Array.<number>} arr
     */
    setTriangleIndices: function (idx, arr) {
        var indices = this.indices;
        indices[idx * 3] = arr[0];
        indices[idx * 3 + 1] = arr[1];
        indices[idx * 3 + 2] = arr[2];
    },

    isUseIndices: function () {
        return !!this.indices;
    },

    /**
     * Initialize indices from an array.
     * @param {Array} array
     */
    initIndicesFromArray: function (array) {
        var value;
        var ArrayConstructor = this.vertexCount > 0xffff
            ? __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Uint32Array : __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Uint16Array;
        // Convert 2d array to flat
        if (array[0] && (array[0].length)) {
            var n = 0;
            var size = 3;

            value = new ArrayConstructor(array.length * size);
            for (var i = 0; i < array.length; i++) {
                for (var j = 0; j < size; j++) {
                    value[n++] = array[i][j];
                }
            }
        }
        else {
            value = new ArrayConstructor(array);
        }

        this.indices = value;
    },
    /**
     * Create a new attribute
     * @param {string} name
     * @param {string} type
     * @param {number} size
     * @param {string} [semantic]
     */
    createAttribute: function (name, type, size, semantic) {
        var attrib = new Attribute(name, type, size, semantic);
        if (this.attributes[name]) {
            this.removeAttribute(name);
        }
        this.attributes[name] = attrib;
        this._attributeList.push(name);
        return attrib;
    },
    /**
     * Remove attribute
     * @param {string} name
     */
    removeAttribute: function (name) {
        var attributeList = this._attributeList;
        var idx = attributeList.indexOf(name);
        if (idx >= 0) {
            attributeList.splice(idx, 1);
            delete this.attributes[name];
            return true;
        }
        return false;
    },

    /**
     * Get attribute
     * @param {string} name
     * @return {clay.GeometryBase.Attribute}
     */
    getAttribute: function (name) {
        return this.attributes[name];
    },

    /**
     * Get enabled attributes name list
     * Attribute which has the same vertex number with position is treated as a enabled attribute
     * @return {string[]}
     */
    getEnabledAttributes: function () {
        var enabledAttributes = this._enabledAttributes;
        var attributeList = this._attributeList;
        // Cache
        if (enabledAttributes) {
            return enabledAttributes;
        }

        var result = [];
        var nVertex = this.vertexCount;

        for (var i = 0; i < attributeList.length; i++) {
            var name = attributeList[i];
            var attrib = this.attributes[name];
            if (attrib.value) {
                if (attrib.value.length === nVertex * attrib.size) {
                    result.push(name);
                }
            }
        }

        this._enabledAttributes = result;

        return result;
    },

    getBufferChunks: function (renderer) {
        var cache = this._cache;
        cache.use(renderer.__uid__);
        var isAttributesDirty = cache.isDirty('attributes');
        var isIndicesDirty = cache.isDirty('indices');
        if (isAttributesDirty || isIndicesDirty) {
            this._updateBuffer(renderer.gl, isAttributesDirty, isIndicesDirty);
            var enabledAttributes = this.getEnabledAttributes();
            for (var i = 0; i < enabledAttributes.length; i++) {
                cache.fresh(makeAttrKey(enabledAttributes[i]));
            }
            cache.fresh('attributes');
            cache.fresh('indices');
        }
        cache.fresh('any');
        return cache.get('chunks');
    },

    _updateBuffer: function (_gl, isAttributesDirty, isIndicesDirty) {
        var cache = this._cache;
        var chunks = cache.get('chunks');
        var firstUpdate = false;
        if (!chunks) {
            chunks = [];
            // Intialize
            chunks[0] = {
                attributeBuffers: [],
                indicesBuffer: null
            };
            cache.put('chunks', chunks);
            firstUpdate = true;
        }

        var chunk = chunks[0];
        var attributeBuffers = chunk.attributeBuffers;
        var indicesBuffer = chunk.indicesBuffer;

        if (isAttributesDirty || firstUpdate) {
            var attributeList = this.getEnabledAttributes();

            var attributeBufferMap = {};
            if (!firstUpdate) {
                for (var i = 0; i < attributeBuffers.length; i++) {
                    attributeBufferMap[attributeBuffers[i].name] = attributeBuffers[i];
                }
            }
            // FIXME If some attributes removed
            for (var k = 0; k < attributeList.length; k++) {
                var name = attributeList[k];
                var attribute = this.attributes[name];

                var bufferInfo;

                if (!firstUpdate) {
                    bufferInfo = attributeBufferMap[name];
                }
                var buffer;
                if (bufferInfo) {
                    buffer = bufferInfo.buffer;
                }
                else {
                    buffer = _gl.createBuffer();
                }
                if (cache.isDirty(makeAttrKey(name))) {
                    // Only update when they are dirty.
                    // TODO: Use BufferSubData?
                    _gl.bindBuffer(_gl.ARRAY_BUFFER, buffer);
                    _gl.bufferData(_gl.ARRAY_BUFFER, attribute.value, this.dynamic ? __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DYNAMIC_DRAW : __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].STATIC_DRAW);
                }

                attributeBuffers[k] = new AttributeBuffer(name, attribute.type, buffer, attribute.size, attribute.semantic);
            }
            // Remove unused attributes buffers.
            // PENDING
            for (var i = k; i < attributeBuffers.length; i++) {
                _gl.deleteBuffer(attributeBuffers[i].buffer);
            }
            attributeBuffers.length = k;

        }

        if (this.isUseIndices() && (isIndicesDirty || firstUpdate)) {
            if (!indicesBuffer) {
                indicesBuffer = new IndicesBuffer(_gl.createBuffer());
                chunk.indicesBuffer = indicesBuffer;
            }
            indicesBuffer.count = this.indices.length;
            _gl.bindBuffer(_gl.ELEMENT_ARRAY_BUFFER, indicesBuffer.buffer);
            _gl.bufferData(_gl.ELEMENT_ARRAY_BUFFER, this.indices, this.dynamic ? __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DYNAMIC_DRAW : __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].STATIC_DRAW);
        }
    },

    /**
     * Dispose geometry data in GL context.
     * @param {clay.Renderer} renderer
     */
    dispose: function (renderer) {

        var cache = this._cache;

        cache.use(renderer.__uid__);
        var chunks = cache.get('chunks');
        if (chunks) {
            for (var c = 0; c < chunks.length; c++) {
                var chunk = chunks[c];

                for (var k = 0; k < chunk.attributeBuffers.length; k++) {
                    var attribs = chunk.attributeBuffers[k];
                    renderer.gl.deleteBuffer(attribs.buffer);
                }

                if (chunk.indicesBuffer) {
                    renderer.gl.deleteBuffer(chunk.indicesBuffer.buffer);
                }
            }
        }
        if (this.__vaoCache) {
            var vaoExt = renderer.getGLExtension('OES_vertex_array_object');
            for (var id in this.__vaoCache) {
                var vao = this.__vaoCache[id].vao;
                if (vao) {
                    vaoExt.deleteVertexArrayOES(vao);
                }
            }
        }
        this.__vaoCache = {};
        cache.deleteContext(renderer.__uid__);
    }

});

if (Object.defineProperty) {
    /**
     * @name clay.GeometryBase#vertexCount
     * @type {number}
     * @readOnly
     */
    Object.defineProperty(GeometryBase.prototype, 'vertexCount', {

        enumerable: false,

        get: function () {

            var mainAttribute = this.attributes[this.mainAttribute];

            if (!mainAttribute) {
                mainAttribute = this.attributes[this._attributeList[0]];
            }

            if (!mainAttribute || !mainAttribute.value) {
                return 0;
            }
            return mainAttribute.value.length / mainAttribute.size;
        }
    });
    /**
     * @name clay.GeometryBase#triangleCount
     * @type {number}
     * @readOnly
     */
    Object.defineProperty(GeometryBase.prototype, 'triangleCount', {

        enumerable: false,

        get: function () {
            var indices = this.indices;
            if (!indices) {
                return 0;
            }
            else {
                return indices.length / 3;
            }
        }
    });
}

GeometryBase.STATIC_DRAW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].STATIC_DRAW;
GeometryBase.DYNAMIC_DRAW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DYNAMIC_DRAW;
GeometryBase.STREAM_DRAW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].STREAM_DRAW;

GeometryBase.AttributeBuffer = AttributeBuffer;
GeometryBase.IndicesBuffer = IndicesBuffer;

GeometryBase.Attribute = Attribute;

/* harmony default export */ __webpack_exports__["a"] = (GeometryBase);


/***/ }),
/* 119 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__calcAmbientSHLight_glsl_js__ = __webpack_require__(120);


var uniformVec3Prefix = 'uniform vec3 ';
var uniformFloatPrefix = 'uniform float ';
var exportHeaderPrefix = '@export clay.header.';
var exportEnd = '@end';
var unconfigurable = ':unconfigurable;';
/* harmony default export */ __webpack_exports__["a"] = ([
    exportHeaderPrefix + 'directional_light',
    uniformVec3Prefix + 'directionalLightDirection[DIRECTIONAL_LIGHT_COUNT]' + unconfigurable,
    uniformVec3Prefix + 'directionalLightColor[DIRECTIONAL_LIGHT_COUNT]' + unconfigurable,
    exportEnd,

    exportHeaderPrefix + 'ambient_light',
    uniformVec3Prefix + 'ambientLightColor[AMBIENT_LIGHT_COUNT]' + unconfigurable,
    exportEnd,

    exportHeaderPrefix + 'ambient_sh_light',
    uniformVec3Prefix + 'ambientSHLightColor[AMBIENT_SH_LIGHT_COUNT]' + unconfigurable,
    uniformVec3Prefix + 'ambientSHLightCoefficients[AMBIENT_SH_LIGHT_COUNT * 9]' + unconfigurable,
    __WEBPACK_IMPORTED_MODULE_0__calcAmbientSHLight_glsl_js__["a" /* default */],
    exportEnd,

    exportHeaderPrefix + 'ambient_cubemap_light',
    uniformVec3Prefix + 'ambientCubemapLightColor[AMBIENT_CUBEMAP_LIGHT_COUNT]' + unconfigurable,
    'uniform samplerCube ambientCubemapLightCubemap[AMBIENT_CUBEMAP_LIGHT_COUNT]' + unconfigurable,
    'uniform sampler2D ambientCubemapLightBRDFLookup[AMBIENT_CUBEMAP_LIGHT_COUNT]' + unconfigurable,
    exportEnd,

    exportHeaderPrefix + 'point_light',
    uniformVec3Prefix + 'pointLightPosition[POINT_LIGHT_COUNT]' + unconfigurable,
    uniformFloatPrefix + 'pointLightRange[POINT_LIGHT_COUNT]' + unconfigurable,
    uniformVec3Prefix + 'pointLightColor[POINT_LIGHT_COUNT]' + unconfigurable,
    exportEnd,

    exportHeaderPrefix + 'spot_light',
    uniformVec3Prefix + 'spotLightPosition[SPOT_LIGHT_COUNT]' + unconfigurable,
    uniformVec3Prefix + 'spotLightDirection[SPOT_LIGHT_COUNT]' + unconfigurable,
    uniformFloatPrefix + 'spotLightRange[SPOT_LIGHT_COUNT]' + unconfigurable,
    uniformFloatPrefix + 'spotLightUmbraAngleCosine[SPOT_LIGHT_COUNT]' + unconfigurable,
    uniformFloatPrefix + 'spotLightPenumbraAngleCosine[SPOT_LIGHT_COUNT]' + unconfigurable,
    uniformFloatPrefix + 'spotLightFalloffFactor[SPOT_LIGHT_COUNT]' + unconfigurable,
    uniformVec3Prefix + 'spotLightColor[SPOT_LIGHT_COUNT]' + unconfigurable,
    exportEnd
].join('\n'));


/***/ }),
/* 120 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("vec3 calcAmbientSHLight(int idx, vec3 N) {\n int offset = 9 * idx;\n return ambientSHLightCoefficients[0]\n + ambientSHLightCoefficients[1] * N.x\n + ambientSHLightCoefficients[2] * N.y\n + ambientSHLightCoefficients[3] * N.z\n + ambientSHLightCoefficients[4] * N.x * N.z\n + ambientSHLightCoefficients[5] * N.z * N.y\n + ambientSHLightCoefficients[6] * N.y * N.x\n + ambientSHLightCoefficients[7] * (3.0 * N.z * N.z - 1.0)\n + ambientSHLightCoefficients[8] * (N.x * N.x - N.y * N.y);\n}");


/***/ }),
/* 121 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.skybox.vertex\n#define SHADER_NAME skybox\nuniform mat4 world : WORLD;\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\nvarying vec3 v_WorldPosition;\nvoid main()\n{\n v_WorldPosition = (world * vec4(position, 1.0)).xyz;\n gl_Position = worldViewProjection * vec4(position, 1.0);\n}\n@end\n@export clay.skybox.fragment\n#define PI 3.1415926\nuniform mat4 viewInverse : VIEWINVERSE;\n#ifdef EQUIRECTANGULAR\nuniform sampler2D environmentMap;\n#else\nuniform samplerCube environmentMap;\n#endif\nuniform float lod: 0.0;\nvarying vec3 v_WorldPosition;\n@import clay.util.rgbm\n@import clay.util.srgb\n@import clay.util.ACES\nvoid main()\n{\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(v_WorldPosition - eyePos);\n#ifdef EQUIRECTANGULAR\n float phi = acos(V.y);\n float theta = atan(-V.x, V.z) + PI * 0.5;\n vec2 uv = vec2(theta / 2.0 / PI, phi / PI);\n vec4 texel = decodeHDR(texture2D(environmentMap, fract(uv)));\n#else\n #if defined(LOD) || defined(SUPPORT_TEXTURE_LOD)\n vec4 texel = decodeHDR(textureCubeLodEXT(environmentMap, V, lod));\n #else\n vec4 texel = decodeHDR(textureCube(environmentMap, V));\n #endif\n#endif\n#ifdef SRGB_DECODE\n texel = sRGBToLinear(texel);\n#endif\n#ifdef TONEMAPPING\n texel.rgb = ACESToneMapping(texel.rgb);\n#endif\n#ifdef SRGB_ENCODE\n texel = linearTosRGB(texel);\n#endif\n gl_FragColor = encodeHDR(vec4(texel.rgb, 1.0));\n}\n@end");


/***/ }),
/* 122 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__TextureCube__ = __webpack_require__(27);




// http://msdn.microsoft.com/en-us/library/windows/desktop/bb943991(v=vs.85).aspx
// https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
var DDS_MAGIC = 0x20534444;

var DDSD_CAPS = 0x1;
var DDSD_HEIGHT = 0x2;
var DDSD_WIDTH = 0x4;
var DDSD_PITCH = 0x8;
var DDSD_PIXELFORMAT = 0x1000;
var DDSD_MIPMAPCOUNT = 0x20000;
var DDSD_LINEARSIZE = 0x80000;
var DDSD_DEPTH = 0x800000;

var DDSCAPS_COMPLEX = 0x8;
var DDSCAPS_MIPMAP = 0x400000;
var DDSCAPS_TEXTURE = 0x1000;

var DDSCAPS2_CUBEMAP = 0x200;
var DDSCAPS2_CUBEMAP_POSITIVEX = 0x400;
var DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800;
var DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000;
var DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000;
var DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000;
var DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000;
var DDSCAPS2_VOLUME = 0x200000;

var DDPF_ALPHAPIXELS = 0x1;
var DDPF_ALPHA = 0x2;
var DDPF_FOURCC = 0x4;
var DDPF_RGB = 0x40;
var DDPF_YUV = 0x200;
var DDPF_LUMINANCE = 0x20000;

function fourCCToInt32(value) {
    return value.charCodeAt(0) +
        (value.charCodeAt(1) << 8) +
        (value.charCodeAt(2) << 16) +
        (value.charCodeAt(3) << 24);
}

function int32ToFourCC(value) {
    return String.fromCharCode(
        value & 0xff,
        (value >> 8) & 0xff,
        (value >> 16) & 0xff,
        (value >> 24) & 0xff
    );
}

var headerLengthInt = 31; // The header length in 32 bit ints

var FOURCC_DXT1 = fourCCToInt32('DXT1');
var FOURCC_DXT3 = fourCCToInt32('DXT3');
var FOURCC_DXT5 = fourCCToInt32('DXT5');
// Offsets into the header array
var off_magic = 0;

var off_size = 1;
var off_flags = 2;
var off_height = 3;
var off_width = 4;

var off_mipmapCount = 7;

var off_pfFlags = 20;
var off_pfFourCC = 21;

var off_caps = 27;
var off_caps2 = 28;
var off_caps3 = 29;
var off_caps4 = 30;

var ret = {
    parse: function(arrayBuffer, out) {
        var header = new Int32Array(arrayBuffer, 0, headerLengthInt);
        if (header[off_magic] !== DDS_MAGIC) {
            return null;
        }
        if (!header(off_pfFlags) & DDPF_FOURCC) {
            return null;
        }

        var fourCC = header(off_pfFourCC);
        var width = header[off_width];
        var height = header[off_height];
        var isCubeMap = header[off_caps2] & DDSCAPS2_CUBEMAP;
        var hasMipmap = header[off_flags] & DDSD_MIPMAPCOUNT;
        var blockBytes, internalFormat;
        switch(fourCC) {
            case FOURCC_DXT1:
                blockBytes = 8;
                internalFormat = __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].COMPRESSED_RGB_S3TC_DXT1_EXT;
                break;
            case FOURCC_DXT3:
                blockBytes = 16;
                internalFormat = __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].COMPRESSED_RGBA_S3TC_DXT3_EXT;
                break;
            case FOURCC_DXT5:
                blockBytes = 16;
                internalFormat = __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].COMPRESSED_RGBA_S3TC_DXT5_EXT;
                break;
            default:
                return null;
        }
        var dataOffset = header[off_size] + 4;
        // TODO: Suppose all face are existed
        var faceNumber = isCubeMap ? 6 : 1;
        var mipmapCount = 1;
        if (hasMipmap) {
            mipmapCount = Math.max(1, header[off_mipmapCount]);
        }

        var textures = [];
        for (var f = 0; f < faceNumber; f++) {
            var _width = width;
            var _height = height;
            textures[f] = new __WEBPACK_IMPORTED_MODULE_1__Texture2D__["a" /* default */]({
                width: _width,
                height: _height,
                format: internalFormat
            });
            var mipmaps = [];
            for (var i = 0; i < mipmapCount; i++) {
                var dataLength = Math.max(4, _width) / 4 * Math.max(4, _height) / 4 * blockBytes;
                var byteArray = new Uint8Array(arrayBuffer, dataOffset, dataLength);

                dataOffset += dataLength;
                _width *= 0.5;
                _height *= 0.5;
                mipmaps[i] = byteArray;
            }
            textures[f].pixels = mipmaps[0];
            if (hasMipmap) {
                textures[f].mipmaps = mipmaps;
            }
        }
        // TODO
        // return isCubeMap ? textures : textures[0];
        if (out) {
            out.width = textures[0].width;
            out.height = textures[0].height;
            out.format = textures[0].format;
            out.pixels = textures[0].pixels;
            out.mipmaps = textures[0].mipmaps;
        }
        else {
            return textures[0];
        }
    }
};

/* harmony default export */ __webpack_exports__["a"] = (ret);


/***/ }),
/* 123 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Texture2D__ = __webpack_require__(5);


var toChar = String.fromCharCode;

var MINELEN = 8;
var MAXELEN = 0x7fff;
function rgbe2float(rgbe, buffer, offset, exposure) {
    if (rgbe[3] > 0) {
        var f = Math.pow(2.0, rgbe[3] - 128 - 8 + exposure);
        buffer[offset + 0] = rgbe[0] * f;
        buffer[offset + 1] = rgbe[1] * f;
        buffer[offset + 2] = rgbe[2] * f;
    }
    else {
        buffer[offset + 0] = 0;
        buffer[offset + 1] = 0;
        buffer[offset + 2] = 0;
    }
    buffer[offset + 3] = 1.0;
    return buffer;
}

function uint82string(array, offset, size) {
    var str = '';
    for (var i = offset; i < size; i++) {
        str += toChar(array[i]);
    }
    return str;
}

function copyrgbe(s, t) {
    t[0] = s[0];
    t[1] = s[1];
    t[2] = s[2];
    t[3] = s[3];
}

// TODO : check
function oldReadColors(scan, buffer, offset, xmax) {
    var rshift = 0, x = 0, len = xmax;
    while (len > 0) {
        scan[x][0] = buffer[offset++];
        scan[x][1] = buffer[offset++];
        scan[x][2] = buffer[offset++];
        scan[x][3] = buffer[offset++];
        if (scan[x][0] === 1 && scan[x][1] === 1 && scan[x][2] === 1) {
            // exp is count of repeated pixels
            for (var i = (scan[x][3] << rshift) >>> 0; i > 0; i--) {
                copyrgbe(scan[x-1], scan[x]);
                x++;
                len--;
            }
            rshift += 8;
        } else {
            x++;
            len--;
            rshift = 0;
        }
    }
    return offset;
}

function readColors(scan, buffer, offset, xmax) {
    if ((xmax < MINELEN) | (xmax > MAXELEN)) {
        return oldReadColors(scan, buffer, offset, xmax);
    }
    var i = buffer[offset++];
    if (i != 2) {
        return oldReadColors(scan, buffer, offset - 1, xmax);
    }
    scan[0][1] = buffer[offset++];
    scan[0][2] = buffer[offset++];

    i = buffer[offset++];
    if ((((scan[0][2] << 8) >>> 0) | i) >>> 0 !== xmax) {
        return null;
    }
    for (var i = 0; i < 4; i++) {
        for (var x = 0; x < xmax;) {
            var code = buffer[offset++];
            if (code > 128) {
                code = (code & 127) >>> 0;
                var val = buffer[offset++];
                while (code--) {
                    scan[x++][i] = val;
                }
            } else {
                while (code--) {
                    scan[x++][i] = buffer[offset++];
                }
            }
        }
    }
    return offset;
}


var ret = {
    // http://www.graphics.cornell.edu/~bjw/rgbe.html
    // Blender source
    // http://radsite.lbl.gov/radiance/refer/Notes/picture_format.html
    parseRGBE: function(arrayBuffer, texture, exposure) {
        if (exposure == null) {
            exposure = 0;
        }
        var data = new Uint8Array(arrayBuffer);
        var size = data.length;
        if (uint82string(data, 0, 2) !== '#?') {
            return;
        }
        // find empty line, next line is resolution info
        for (var i = 2; i < size; i++) {
            if (toChar(data[i]) === '\n' && toChar(data[i+1]) === '\n') {
                break;
            }
        }
        if (i >= size) { // not found
            return;
        }
        // find resolution info line
        i += 2;
        var str = '';
        for (; i < size; i++) {
            var _char = toChar(data[i]);
            if (_char === '\n') {
                break;
            }
            str += _char;
        }
        // -Y M +X N
        var tmp = str.split(' ');
        var height = parseInt(tmp[1]);
        var width = parseInt(tmp[3]);
        if (!width || !height) {
            return;
        }

        // read and decode actual data
        var offset = i+1;
        var scanline = [];
        // memzero
        for (var x = 0; x < width; x++) {
            scanline[x] = [];
            for (var j = 0; j < 4; j++) {
                scanline[x][j] = 0;
            }
        }
        var pixels = new Float32Array(width * height * 4);
        var offset2 = 0;
        for (var y = 0; y < height; y++) {
            var offset = readColors(scanline, data, offset, width);
            if (!offset) {
                return null;
            }
            for (var x = 0; x < width; x++) {
                rgbe2float(scanline[x], pixels, offset2, exposure);
                offset2 += 4;
            }
        }

        if (!texture) {
            texture = new __WEBPACK_IMPORTED_MODULE_1__Texture2D__["a" /* default */]();
        }
        texture.width = width;
        texture.height = height;
        texture.pixels = pixels;
        // HALF_FLOAT can't use Float32Array
        texture.type = __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].FLOAT;
        return texture;
    },

    parseRGBEFromPNG: function(png) {

    }
};

/* harmony default export */ __webpack_exports__["a"] = (ret);


/***/ }),
/* 124 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__ = __webpack_require__(26);
/**
 * Surface texture in the 3D scene.
 * Provide management and rendering of zrender shapes and groups
 *
 * @module echarts-gl/util/EChartsSurface
 * @author Yi Shen(http://github.com/pissang)
 */





var events = ['mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu'];

function makeHandlerName(eventName) {
    return '_on' + eventName;
}
/**
 * @constructor
 * @alias echarts-gl/util/EChartsSurface
 * @param {module:echarts~ECharts} chart
 */
var EChartsSurface = function (chart) {
    var self = this;
    this._texture = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__["a" /* default */]({
        anisotropic: 32,
        flipY: false,

        surface: this,

        dispose: function (renderer) {
            self.dispose();
            __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__["a" /* default */].prototype.dispose.call(this, renderer);
        }
    });

    events.forEach(function (eventName) {
        this[makeHandlerName(eventName)] = function (eveObj) {
            if (!eveObj.triangle) {
                return;
            }
            this._meshes.forEach(function (mesh) {
                this.dispatchEvent(eventName, mesh, eveObj.triangle, eveObj.point);
            }, this);
        };
    }, this);

    this._meshes = [];

    if (chart) {
        this.setECharts(chart);
    }

    // Texture updated callback;
    this.onupdate = null;
};

EChartsSurface.prototype = {

    constructor: EChartsSurface,

    getTexture: function () {
        return this._texture;
    },

    setECharts: function (chart) {
        this._chart = chart;

        var canvas = chart.getDom();
        if (!(canvas instanceof HTMLCanvasElement)) {
            console.error('ECharts must init on canvas if it is used as texture.');
            // Use an empty canvas
            canvas = document.createElement('canvas');
        }
        else {
            var self = this;
            // Wrap refreshImmediately
            var zr = chart.getZr();
            var oldRefreshImmediately = zr.__oldRefreshImmediately || zr.refreshImmediately;
            zr.refreshImmediately = function () {
                oldRefreshImmediately.call(this);
                self._texture.dirty();

                self.onupdate && self.onupdate();
            };
            zr.__oldRefreshImmediately = oldRefreshImmediately;
        }

        this._texture.image = canvas;
        this._texture.dirty();
        this.onupdate && this.onupdate();
    },

    /**
     * @method
     * @param {clay.Mesh} attachedMesh
     * @param {Array.<number>} triangle Triangle indices
     * @param {clay.math.Vector3} point
     */
    dispatchEvent: (function () {

        var p0 = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */]();
        var p1 = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */]();
        var p2 = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */]();
        var uv0 = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */]();
        var uv1 = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */]();
        var uv2 = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */]();
        var uv = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */]();

        var vCross = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */]();

        return function (eventName, attachedMesh, triangle, point) {
            var geo = attachedMesh.geometry;
            var position = geo.attributes.position;
            var texcoord = geo.attributes.texcoord0;
            var dot = __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */].dot;
            var cross = __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */].cross;

            position.get(triangle[0], p0.array);
            position.get(triangle[1], p1.array);
            position.get(triangle[2], p2.array);
            texcoord.get(triangle[0], uv0.array);
            texcoord.get(triangle[1], uv1.array);
            texcoord.get(triangle[2], uv2.array);

            cross(vCross, p1, p2);
            var det = dot(p0, vCross);
            var t = dot(point, vCross) / det;
            cross(vCross, p2, p0);
            var u = dot(point, vCross) / det;
            cross(vCross, p0, p1);
            var v = dot(point, vCross) / det;

            __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */].scale(uv, uv0, t);
            __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */].scaleAndAdd(uv, uv, uv1, u);
            __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */].scaleAndAdd(uv, uv, uv2, v);

            var x = uv.x * this._chart.getWidth();
            var y = uv.y * this._chart.getHeight();
            this._chart.getZr().handler.dispatch(eventName, {
                zrX: x,
                zrY: y
            });
        };
    })(),

    attachToMesh: function (mesh) {
        if (this._meshes.indexOf(mesh) >= 0) {
            return;
        }

        events.forEach(function (eventName) {
            mesh.on(eventName, this[makeHandlerName(eventName)], this);
        }, this);

        this._meshes.push(mesh);
    },

    detachFromMesh: function (mesh) {
        var idx = this._meshes.indexOf(mesh);
        if (idx >= 0) {
            this._meshes.splice(idx, 1);
        }

        events.forEach(function (eventName) {
            mesh.off(eventName, this[makeHandlerName(eventName)]);
        }, this);
    },

    dispose: function () {
        this._meshes.forEach(function (mesh) {
            this.detachFromMesh(mesh);
        }, this);
    }
};

/* harmony default export */ __webpack_exports__["a"] = (EChartsSurface);

/***/ }),
/* 125 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Light__ = __webpack_require__(24);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_cubemap__ = __webpack_require__(77);
// https://docs.unrealengine.com/latest/INT/Engine/Rendering/LightingAndShadows/AmbientCubemap/



/**
 * Ambient cubemap light provides specular parts of Image Based Lighting.
 * Which is a basic requirement for Physically Based Rendering
 * @constructor clay.light.AmbientCubemap
 * @extends clay.Light
 */
var AmbientCubemapLight = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].extend({

    /**
     * @type {clay.TextureCube}
     * @memberOf clay.light.AmbientCubemap#
     */
    cubemap: null,

    // TODO
    // range: 100,

    castShadow: false,

    _normalDistribution: null,
    _brdfLookup: null

}, /** @lends clay.light.AmbientCubemap# */ {

    type: 'AMBIENT_CUBEMAP_LIGHT',

    /**
     * Do prefitering the cubemap
     * @param {clay.Renderer} renderer
     * @param {number} [size=32]
     */
    prefilter: function (renderer, size) {
        if (!renderer.getGLExtension('EXT_shader_texture_lod')) {
            console.warn('Device not support textureCubeLodEXT');
            return;
        }
        if (!this._brdfLookup) {
            this._normalDistribution = __WEBPACK_IMPORTED_MODULE_1__util_cubemap__["a" /* default */].generateNormalDistribution();
            this._brdfLookup = __WEBPACK_IMPORTED_MODULE_1__util_cubemap__["a" /* default */].integrateBRDF(renderer, this._normalDistribution);
        }
        var cubemap = this.cubemap;
        if (cubemap.__prefiltered) {
            return;
        }

        var result = __WEBPACK_IMPORTED_MODULE_1__util_cubemap__["a" /* default */].prefilterEnvironmentMap(
            renderer, cubemap, {
                encodeRGBM: true,
                width: size,
                height: size
            }, this._normalDistribution, this._brdfLookup
        );
        this.cubemap = result.environmentMap;
        this.cubemap.__prefiltered = true;

        cubemap.dispose(renderer);
    },

    getBRDFLookup: function () {
        return this._brdfLookup;
    },

    uniformTemplates: {
        ambientCubemapLightColor: {
            type: '3f',
            value: function (instance) {
                var color = instance.color;
                var intensity = instance.intensity;
                return [color[0]*intensity, color[1]*intensity, color[2]*intensity];
            }
        },

        ambientCubemapLightCubemap: {
            type: 't',
            value: function (instance) {
                return instance.cubemap;
            }
        },

        ambientCubemapLightBRDFLookup: {
            type: 't',
            value: function (instance) {
                return instance._brdfLookup;
            }
        }
    }
    /**
     * @function
     * @name clone
     * @return {clay.light.AmbientCubemap}
     * @memberOf clay.light.AmbientCubemap.prototype
     */
});

/* harmony default export */ __webpack_exports__["a"] = (AmbientCubemapLight);


/***/ }),
/* 126 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("\n@export clay.compositor.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n v_Texcoord = texcoord;\n gl_Position = worldViewProjection * vec4(position, 1.0);\n}\n@end");


/***/ }),
/* 127 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("#define SAMPLE_NUMBER 1024\n#define PI 3.14159265358979\nuniform sampler2D normalDistribution;\nuniform vec2 viewportSize : [512, 256];\nconst vec3 N = vec3(0.0, 0.0, 1.0);\nconst float fSampleNumber = float(SAMPLE_NUMBER);\nvec3 importanceSampleNormal(float i, float roughness, vec3 N) {\n vec3 H = texture2D(normalDistribution, vec2(roughness, i)).rgb;\n vec3 upVector = abs(N.y) > 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nfloat G_Smith(float roughness, float NoV, float NoL) {\n float k = roughness * roughness / 2.0;\n float G1V = NoV / (NoV * (1.0 - k) + k);\n float G1L = NoL / (NoL * (1.0 - k) + k);\n return G1L * G1V;\n}\nvoid main() {\n vec2 uv = gl_FragCoord.xy / viewportSize;\n float NoV = uv.x;\n float roughness = uv.y;\n vec3 V;\n V.x = sqrt(1.0 - NoV * NoV);\n V.y = 0.0;\n V.z = NoV;\n float A = 0.0;\n float B = 0.0;\n for (int i = 0; i < SAMPLE_NUMBER; i++) {\n vec3 H = importanceSampleNormal(float(i) / fSampleNumber, roughness, N);\n vec3 L = reflect(-V, H);\n float NoL = clamp(L.z, 0.0, 1.0);\n float NoH = clamp(H.z, 0.0, 1.0);\n float VoH = clamp(dot(V, H), 0.0, 1.0);\n if (NoL > 0.0) {\n float G = G_Smith(roughness, NoV, NoL);\n float G_Vis = G * VoH / (NoH * NoV);\n float Fc = pow(1.0 - VoH, 5.0);\n A += (1.0 - Fc) * G_Vis;\n B += Fc * G_Vis;\n }\n }\n gl_FragColor = vec4(vec2(A, B) / fSampleNumber, 0.0, 1.0);\n}\n");


/***/ }),
/* 128 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("#define SHADER_NAME prefilter\n#define SAMPLE_NUMBER 1024\n#define PI 3.14159265358979\nuniform mat4 viewInverse : VIEWINVERSE;\nuniform samplerCube environmentMap;\nuniform sampler2D normalDistribution;\nuniform float roughness : 0.5;\nvarying vec2 v_Texcoord;\nvarying vec3 v_WorldPosition;\n@import clay.util.rgbm\nvec3 importanceSampleNormal(float i, float roughness, vec3 N) {\n vec3 H = texture2D(normalDistribution, vec2(roughness, i)).rgb;\n vec3 upVector = abs(N.y) > 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nvoid main() {\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(v_WorldPosition - eyePos);\n vec3 N = V;\n vec3 prefilteredColor = vec3(0.0);\n float totalWeight = 0.0;\n float fMaxSampleNumber = float(SAMPLE_NUMBER);\n for (int i = 0; i < SAMPLE_NUMBER; i++) {\n vec3 H = importanceSampleNormal(float(i) / fMaxSampleNumber, roughness, N);\n vec3 L = reflect(-V, H);\n float NoL = clamp(dot(N, L), 0.0, 1.0);\n if (NoL > 0.0) {\n prefilteredColor += decodeHDR(textureCube(environmentMap, L)).rgb * NoL;\n totalWeight += NoL;\n }\n }\n gl_FragColor = encodeHDR(vec4(prefilteredColor / totalWeight, 1.0));\n}\n");


/***/ }),
/* 129 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Light__ = __webpack_require__(24);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_vendor__ = __webpack_require__(14);



/**
 * Spherical Harmonic Ambient Light
 * @constructor clay.light.AmbientSH
 * @extends clay.Light
 */
var AmbientSHLight = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].extend({

    castShadow: false,

    /**
     * Spherical Harmonic Coefficients
     * @type {Array.<number>}
     * @memberOf clay.light.AmbientSH#
     */
    coefficients: [],

}, function () {
    this._coefficientsTmpArr = new __WEBPACK_IMPORTED_MODULE_1__core_vendor__["a" /* default */].Float32Array(9 * 3);
}, {

    type: 'AMBIENT_SH_LIGHT',

    uniformTemplates: {
        ambientSHLightColor: {
            type: '3f',
            value: function (instance) {
                var color = instance.color;
                var intensity = instance.intensity;
                return [color[0] * intensity, color[1] * intensity, color[2] * intensity];
            }
        },

        ambientSHLightCoefficients: {
            type: '3f',
            value: function (instance) {
                var coefficientsTmpArr = instance._coefficientsTmpArr;
                for (var i = 0; i < instance.coefficients.length; i++) {
                    coefficientsTmpArr[i] = instance.coefficients[i];
                }
                return coefficientsTmpArr;
            }
        }
    }
    /**
     * @function
     * @name clone
     * @return {clay.light.Ambient}
     * @memberOf clay.light.Ambient.prototype
     */
});

/* harmony default export */ __webpack_exports__["a"] = (AmbientSHLight);


/***/ }),
/* 130 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__compositor_Pass__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__core_vendor__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__plugin_Skybox__ = __webpack_require__(42);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__plugin_Skydome__ = __webpack_require__(75);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__prePass_EnvironmentMap__ = __webpack_require__(62);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Scene__ = __webpack_require__(36);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__glmatrix_vec3__ = __webpack_require__(12);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__shader_projectEnvMap_glsl_js__ = __webpack_require__(131);
// Spherical Harmonic Helpers










var sh = {};



var targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz'];

// Project on gpu, but needs browser to support readPixels as Float32Array.
function projectEnvironmentMapGPU(renderer, envMap) {
    var shTexture = new __WEBPACK_IMPORTED_MODULE_2__Texture2D__["a" /* default */]({
        width: 9,
        height: 1,
        type: __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].FLOAT
    });
    var pass = new __WEBPACK_IMPORTED_MODULE_3__compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_10__shader_projectEnvMap_glsl_js__["a" /* default */]
    });
    pass.material.define('fragment', 'TEXTURE_SIZE', envMap.width);
    pass.setUniform('environmentMap', envMap);

    var framebuffer = new __WEBPACK_IMPORTED_MODULE_1__FrameBuffer__["a" /* default */]();
    framebuffer.attach(shTexture);
    pass.render(renderer, framebuffer);

    framebuffer.bind(renderer);
    // TODO Only chrome and firefox support Float32Array
    var pixels = new __WEBPACK_IMPORTED_MODULE_4__core_vendor__["a" /* default */].Float32Array(9 * 4);
    renderer.gl.readPixels(0, 0, 9, 1, __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].RGBA, __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].FLOAT, pixels);

    var coeff = new __WEBPACK_IMPORTED_MODULE_4__core_vendor__["a" /* default */].Float32Array(9 * 3);
    for (var i = 0; i < 9; i++) {
        coeff[i * 3] = pixels[i * 4];
        coeff[i * 3 + 1] = pixels[i * 4 + 1];
        coeff[i * 3 + 2] = pixels[i * 4 + 2];
    }
    framebuffer.unbind(renderer);

    framebuffer.dispose(renderer);
    pass.dispose(renderer);
    return coeff;
}

function harmonics(normal, index){
    var x = normal[0];
    var y = normal[1];
    var z = normal[2];

    if (index === 0) {
        return 1.0;
    }
    else if (index === 1) {
        return x;
    }
    else if (index === 2) {
        return y;
    }
    else if (index === 3) {
        return z;
    }
    else if (index === 4) {
        return x * z;
    }
    else if (index === 5) {
        return y * z;
    }
    else if (index === 6) {
        return x * y;
    }
    else if (index === 7) {
        return 3.0 * z * z - 1.0;
    }
    else {
        return x * x - y * y;
    }
}

var normalTransform = {
    px: [2, 1, 0, -1, -1, 1],
    nx: [2, 1, 0, 1, -1, -1],
    py: [0, 2, 1, 1, -1, -1],
    ny: [0, 2, 1, 1, 1, 1],
    pz: [0, 1, 2, -1, -1, -1],
    nz: [0, 1, 2, 1, -1, 1]
};

// Project on cpu.
function projectEnvironmentMapCPU(renderer, cubePixels, width, height) {
    var coeff = new __WEBPACK_IMPORTED_MODULE_4__core_vendor__["a" /* default */].Float32Array(9 * 3);
    var normal = __WEBPACK_IMPORTED_MODULE_9__glmatrix_vec3__["a" /* default */].create();
    var texel = __WEBPACK_IMPORTED_MODULE_9__glmatrix_vec3__["a" /* default */].create();
    var fetchNormal = __WEBPACK_IMPORTED_MODULE_9__glmatrix_vec3__["a" /* default */].create();
    for (var m = 0; m < 9; m++) {
        var result = __WEBPACK_IMPORTED_MODULE_9__glmatrix_vec3__["a" /* default */].create();
        for (var k = 0; k < targets.length; k++) {
            var pixels = cubePixels[targets[k]];

            var sideResult = __WEBPACK_IMPORTED_MODULE_9__glmatrix_vec3__["a" /* default */].create();
            var divider = 0;
            var i = 0;
            var transform = normalTransform[targets[k]];
            for (var y = 0; y < height; y++) {
                for (var x = 0; x < width; x++) {

                    normal[0] = x / (width - 1.0) * 2.0 - 1.0;
                    // TODO Flip y?
                    normal[1] = y / (height - 1.0) * 2.0 - 1.0;
                    normal[2] = -1.0;
                    __WEBPACK_IMPORTED_MODULE_9__glmatrix_vec3__["a" /* default */].normalize(normal, normal);

                    fetchNormal[0] = normal[transform[0]] * transform[3];
                    fetchNormal[1] = normal[transform[1]] * transform[4];
                    fetchNormal[2] = normal[transform[2]] * transform[5];

                    texel[0] = pixels[i++] / 255;
                    texel[1] = pixels[i++] / 255;
                    texel[2] = pixels[i++] / 255;
                    // RGBM Decode
                    var scale = pixels[i++] / 255 * 8.12;
                    texel[0] *= scale;
                    texel[1] *= scale;
                    texel[2] *= scale;

                    __WEBPACK_IMPORTED_MODULE_9__glmatrix_vec3__["a" /* default */].scaleAndAdd(sideResult, sideResult, texel, harmonics(fetchNormal, m) * -normal[2]);
                    // -normal.z equals cos(theta) of Lambertian
                    divider += -normal[2];
                }
            }
            __WEBPACK_IMPORTED_MODULE_9__glmatrix_vec3__["a" /* default */].scaleAndAdd(result, result, sideResult, 1 / divider);
        }

        coeff[m * 3] = result[0] / 6.0;
        coeff[m * 3 + 1] = result[1] / 6.0;
        coeff[m * 3 + 2] = result[2] / 6.0;
    }
    return coeff;
}

/**
 * @param  {clay.Renderer} renderer
 * @param  {clay.Texture} envMap
 * @param  {Object} [textureOpts]
 * @param  {Object} [textureOpts.lod]
 * @param  {boolean} [textureOpts.decodeRGBM]
 */
sh.projectEnvironmentMap = function (renderer, envMap, opts) {

    // TODO sRGB

    opts = opts || {};
    opts.lod = opts.lod || 0;

    var skybox;
    var dummyScene = new __WEBPACK_IMPORTED_MODULE_8__Scene__["a" /* default */]();
    var size = 64;
    if (envMap.textureType === 'texture2D') {
        skybox = new __WEBPACK_IMPORTED_MODULE_6__plugin_Skydome__["a" /* default */]({
            scene: dummyScene,
            environmentMap: envMap
        });
    }
    else {
        size = (envMap.image && envMap.image.px) ? envMap.image.px.width : envMap.width;
        skybox = new __WEBPACK_IMPORTED_MODULE_5__plugin_Skybox__["a" /* default */]({
            scene: dummyScene,
            environmentMap: envMap
        });
    }
    // Convert to rgbm
    var width = Math.ceil(size / Math.pow(2, opts.lod));
    var height = Math.ceil(size / Math.pow(2, opts.lod));
    var rgbmTexture = new __WEBPACK_IMPORTED_MODULE_2__Texture2D__["a" /* default */]({
        width: width,
        height: height
    });
    var framebuffer = new __WEBPACK_IMPORTED_MODULE_1__FrameBuffer__["a" /* default */]();
    skybox.material.define('fragment', 'RGBM_ENCODE');
    if (opts.decodeRGBM) {
        skybox.material.define('fragment', 'RGBM_DECODE');
    }
    skybox.material.set('lod', opts.lod);
    var envMapPass = new __WEBPACK_IMPORTED_MODULE_7__prePass_EnvironmentMap__["a" /* default */]({
        texture: rgbmTexture
    });
    var cubePixels = {};
    for (var i = 0; i < targets.length; i++) {
        cubePixels[targets[i]] = new Uint8Array(width * height * 4);
        var camera = envMapPass.getCamera(targets[i]);
        camera.fov = 90;
        framebuffer.attach(rgbmTexture);
        framebuffer.bind(renderer);
        renderer.render(dummyScene, camera);
        renderer.gl.readPixels(
            0, 0, width, height,
            __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].RGBA, __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].UNSIGNED_BYTE, cubePixels[targets[i]]
        );
        framebuffer.unbind(renderer);
    }

    skybox.dispose(renderer);
    framebuffer.dispose(renderer);
    rgbmTexture.dispose(renderer);

    return projectEnvironmentMapCPU(renderer, cubePixels, width, height);
};

/* harmony default export */ __webpack_exports__["a"] = (sh);


/***/ }),
/* 131 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("uniform samplerCube environmentMap;\nvarying vec2 v_Texcoord;\n#define TEXTURE_SIZE 16\nmat3 front = mat3(\n 1.0, 0.0, 0.0,\n 0.0, 1.0, 0.0,\n 0.0, 0.0, 1.0\n);\nmat3 back = mat3(\n -1.0, 0.0, 0.0,\n 0.0, 1.0, 0.0,\n 0.0, 0.0, -1.0\n);\nmat3 left = mat3(\n 0.0, 0.0, -1.0,\n 0.0, 1.0, 0.0,\n 1.0, 0.0, 0.0\n);\nmat3 right = mat3(\n 0.0, 0.0, 1.0,\n 0.0, 1.0, 0.0,\n -1.0, 0.0, 0.0\n);\nmat3 up = mat3(\n 1.0, 0.0, 0.0,\n 0.0, 0.0, 1.0,\n 0.0, -1.0, 0.0\n);\nmat3 down = mat3(\n 1.0, 0.0, 0.0,\n 0.0, 0.0, -1.0,\n 0.0, 1.0, 0.0\n);\nfloat harmonics(vec3 normal){\n int index = int(gl_FragCoord.x);\n float x = normal.x;\n float y = normal.y;\n float z = normal.z;\n if(index==0){\n return 1.0;\n }\n else if(index==1){\n return x;\n }\n else if(index==2){\n return y;\n }\n else if(index==3){\n return z;\n }\n else if(index==4){\n return x*z;\n }\n else if(index==5){\n return y*z;\n }\n else if(index==6){\n return x*y;\n }\n else if(index==7){\n return 3.0*z*z - 1.0;\n }\n else{\n return x*x - y*y;\n }\n}\nvec3 sampleSide(mat3 rot)\n{\n vec3 result = vec3(0.0);\n float divider = 0.0;\n for (int i = 0; i < TEXTURE_SIZE * TEXTURE_SIZE; i++) {\n float x = mod(float(i), float(TEXTURE_SIZE));\n float y = float(i / TEXTURE_SIZE);\n vec2 sidecoord = ((vec2(x, y) + vec2(0.5, 0.5)) / vec2(TEXTURE_SIZE)) * 2.0 - 1.0;\n vec3 normal = normalize(vec3(sidecoord, -1.0));\n vec3 fetchNormal = rot * normal;\n vec3 texel = textureCube(environmentMap, fetchNormal).rgb;\n result += harmonics(fetchNormal) * texel * -normal.z;\n divider += -normal.z;\n }\n return result / divider;\n}\nvoid main()\n{\n vec3 result = (\n sampleSide(front) +\n sampleSide(back) +\n sampleSide(left) +\n sampleSide(right) +\n sampleSide(up) +\n sampleSide(down)\n ) / 6.0;\n gl_FragColor = vec4(result, 1.0);\n}");


/***/ }),
/* 132 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Geometry__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_BoundingBox__ = __webpack_require__(18);



/**
 * @constructor clay.geometry.Sphere
 * @extends clay.Geometry
 * @param {Object} [opt]
 * @param {number} [widthSegments]
 * @param {number} [heightSegments]
 * @param {number} [phiStart]
 * @param {number} [phiLength]
 * @param {number} [thetaStart]
 * @param {number} [thetaLength]
 * @param {number} [radius]
 */
var Sphere = __WEBPACK_IMPORTED_MODULE_0__Geometry__["a" /* default */].extend(/** @lends clay.geometry.Sphere# */ {
    dynamic: false,
    /**
     * @type {number}
     */
    widthSegments: 40,
    /**
     * @type {number}
     */
    heightSegments: 20,

    /**
     * @type {number}
     */
    phiStart: 0,
    /**
     * @type {number}
     */
    phiLength: Math.PI * 2,

    /**
     * @type {number}
     */
    thetaStart: 0,
    /**
     * @type {number}
     */
    thetaLength: Math.PI,

    /**
     * @type {number}
     */
    radius: 1

}, function() {
    this.build();
},
/** @lends clay.geometry.Sphere.prototype */
{
    /**
     * Build sphere geometry
     */
    build: function() {
        var heightSegments = this.heightSegments;
        var widthSegments = this.widthSegments;

        var positionAttr = this.attributes.position;
        var texcoordAttr = this.attributes.texcoord0;
        var normalAttr = this.attributes.normal;

        var vertexCount = (widthSegments + 1) * (heightSegments + 1);
        positionAttr.init(vertexCount);
        texcoordAttr.init(vertexCount);
        normalAttr.init(vertexCount);

        var IndicesCtor = vertexCount > 0xffff ? Uint32Array : Uint16Array;
        var indices = this.indices = new IndicesCtor(widthSegments * heightSegments * 6);

        var x, y, z,
            u, v,
            i, j;

        var radius = this.radius;
        var phiStart = this.phiStart;
        var phiLength = this.phiLength;
        var thetaStart = this.thetaStart;
        var thetaLength = this.thetaLength;
        var radius = this.radius;

        var pos = [];
        var uv = [];
        var offset = 0;
        var divider = 1 / radius;
        for (j = 0; j <= heightSegments; j ++) {
            for (i = 0; i <= widthSegments; i ++) {
                u = i / widthSegments;
                v = j / heightSegments;

                // X axis is inverted so texture can be mapped from left to right
                x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
                y = radius * Math.cos(thetaStart + v * thetaLength);
                z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);

                pos[0] = x; pos[1] = y; pos[2] = z;
                uv[0] = u; uv[1] = v;
                positionAttr.set(offset, pos);
                texcoordAttr.set(offset, uv);
                pos[0] *= divider;
                pos[1] *= divider;
                pos[2] *= divider;
                normalAttr.set(offset, pos);
                offset++;
            }
        }

        var i1, i2, i3, i4;

        var len = widthSegments + 1;

        var n = 0;
        for (j = 0; j < heightSegments; j ++) {
            for (i = 0; i < widthSegments; i ++) {
                i2 = j * len + i;
                i1 = (j * len + i + 1);
                i4 = (j + 1) * len + i + 1;
                i3 = (j + 1) * len + i;

                indices[n++] = i1;
                indices[n++] = i2;
                indices[n++] = i4;

                indices[n++] = i2;
                indices[n++] = i3;
                indices[n++] = i4;
            }
        }

        this.boundingBox = new __WEBPACK_IMPORTED_MODULE_1__math_BoundingBox__["a" /* default */]();
        this.boundingBox.max.set(radius, radius, radius);
        this.boundingBox.min.set(-radius, -radius, -radius);
    }
});

/* harmony default export */ __webpack_exports__["a"] = (Sphere);


/***/ }),
/* 133 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Light__ = __webpack_require__(24);


/**
 * @constructor clay.light.Ambient
 * @extends clay.Light
 */
var AmbientLight = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].extend({

    castShadow: false

}, {

    type: 'AMBIENT_LIGHT',

    uniformTemplates: {
        ambientLightColor: {
            type: '3f',
            value: function(instance) {
                var color = instance.color;
                var intensity = instance.intensity;
                return [color[0]*intensity, color[1]*intensity, color[2]*intensity];
            }
        }
    }
    /**
     * @function
     * @name clone
     * @return {clay.light.Ambient}
     * @memberOf clay.light.Ambient.prototype
     */
});

/* harmony default export */ __webpack_exports__["a"] = (AmbientLight);


/***/ }),
/* 134 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Light__ = __webpack_require__(24);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_Vector3__ = __webpack_require__(3);



/**
 * @constructor clay.light.Directional
 * @extends clay.Light
 *
 * @example
 *     var light = new clay.light.Directional({
 *         intensity: 0.5,
 *         color: [1.0, 0.0, 0.0]
 *     });
 *     light.position.set(10, 10, 10);
 *     light.lookAt(clay.Vector3.ZERO);
 *     scene.add(light);
 */
var DirectionalLight = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].extend(/** @lends clay.light.Directional# */ {
    /**
     * @type {number}
     */
    shadowBias: 0.001,
    /**
     * @type {number}
     */
    shadowSlopeScale: 2.0,
    /**
     * Shadow cascade.
     * Use PSSM technique when it is larger than 1 and have a unique directional light in scene.
     * @type {number}
     */
    shadowCascade: 1,

    /**
     * Available when shadowCascade is larger than 1 and have a unique directional light in scene.
     * @type {number}
     */
    cascadeSplitLogFactor: 0.2
}, {

    type: 'DIRECTIONAL_LIGHT',

    uniformTemplates: {
        directionalLightDirection: {
            type: '3f',
            value: function (instance) {
                instance.__dir = instance.__dir || new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */]();
                // Direction is target to eye
                return instance.__dir.copy(instance.worldTransform.z).normalize().negate().array;
            }
        },
        directionalLightColor: {
            type: '3f',
            value: function (instance) {
                var color = instance.color;
                var intensity = instance.intensity;
                return [color[0] * intensity, color[1] * intensity, color[2] * intensity];
            }
        }
    },
    /**
     * @return {clay.light.Directional}
     * @memberOf clay.light.Directional.prototype
     */
    clone: function () {
        var light = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].prototype.clone.call(this);
        light.shadowBias = this.shadowBias;
        light.shadowSlopeScale = this.shadowSlopeScale;
        return light;
    }
});

/* harmony default export */ __webpack_exports__["a"] = (DirectionalLight);


/***/ }),
/* 135 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Light__ = __webpack_require__(24);


/**
 * @constructor clay.light.Point
 * @extends clay.Light
 */
var PointLight = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].extend(/** @lends clay.light.Point# */ {
    /**
     * @type {number}
     */
    range: 100,

    /**
     * @type {number}
     */
    castShadow: false
}, {

    type: 'POINT_LIGHT',

    uniformTemplates: {
        pointLightPosition: {
            type: '3f',
            value: function(instance) {
                return instance.getWorldPosition().array;
            }
        },
        pointLightRange: {
            type: '1f',
            value: function(instance) {
                return instance.range;
            }
        },
        pointLightColor: {
            type: '3f',
            value: function(instance) {
                var color = instance.color;
                var intensity = instance.intensity;
                return [color[0] * intensity, color[1] * intensity, color[2] * intensity];
            }
        }
    },
    /**
     * @return {clay.light.Point}
     * @memberOf clay.light.Point.prototype
     */
    clone: function() {
        var light = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].prototype.clone.call(this);
        light.range = this.range;
        return light;
    }
});

/* harmony default export */ __webpack_exports__["a"] = (PointLight);


/***/ }),
/* 136 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Light__ = __webpack_require__(24);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_Vector3__ = __webpack_require__(3);



/**
 * @constructor clay.light.Spot
 * @extends clay.Light
 */
var SpotLight = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].extend(/**@lends clay.light.Spot */ {
    /**
     * @type {number}
     */
    range: 20,
    /**
     * @type {number}
     */
    umbraAngle: 30,
    /**
     * @type {number}
     */
    penumbraAngle: 45,
    /**
     * @type {number}
     */
    falloffFactor: 2.0,
    /**
     * @type {number}
     */
    shadowBias: 0.001,
    /**
     * @type {number}
     */
    shadowSlopeScale: 2.0
}, {

    type: 'SPOT_LIGHT',

    uniformTemplates: {
        spotLightPosition: {
            type: '3f',
            value: function (instance) {
                return instance.getWorldPosition().array;
            }
        },
        spotLightRange: {
            type: '1f',
            value: function (instance) {
                return instance.range;
            }
        },
        spotLightUmbraAngleCosine: {
            type: '1f',
            value: function (instance) {
                return Math.cos(instance.umbraAngle * Math.PI / 180);
            }
        },
        spotLightPenumbraAngleCosine: {
            type: '1f',
            value: function (instance) {
                return Math.cos(instance.penumbraAngle * Math.PI / 180);
            }
        },
        spotLightFalloffFactor: {
            type: '1f',
            value: function (instance) {
                return instance.falloffFactor;
            }
        },
        spotLightDirection: {
            type: '3f',
            value: function (instance) {
                instance.__dir = instance.__dir || new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */]();
                // Direction is target to eye
                return instance.__dir.copy(instance.worldTransform.z).negate().array;
            }
        },
        spotLightColor: {
            type: '3f',
            value: function (instance) {
                var color = instance.color;
                var intensity = instance.intensity;
                return [color[0] * intensity, color[1] * intensity, color[2] * intensity];
            }
        }
    },
    /**
     * @return {clay.light.Spot}
     * @memberOf clay.light.Spot.prototype
     */
    clone: function () {
        var light = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].prototype.clone.call(this);
        light.range = this.range;
        light.umbraAngle = this.umbraAngle;
        light.penumbraAngle = this.penumbraAngle;
        light.falloffFactor = this.falloffFactor;
        light.shadowBias = this.shadowBias;
        light.shadowSlopeScale = this.shadowSlopeScale;
        return light;
    }
});

/* harmony default export */ __webpack_exports__["a"] = (SpotLight);


/***/ }),
/* 137 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__ = __webpack_require__(33);


/**
 * @constructor
 * @alias clay.Vector4
 * @param {number} x
 * @param {number} y
 * @param {number} z
 * @param {number} w
 */
var Vector4 = function(x, y, z, w) {

    x = x || 0;
    y = y || 0;
    z = z || 0;
    w = w || 0;

    /**
     * Storage of Vector4, read and write of x, y, z, w will change the values in array
     * All methods also operate on the array instead of x, y, z, w components
     * @name array
     * @type {Float32Array}
     * @memberOf clay.Vector4#
     */
    this.array = __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].fromValues(x, y, z, w);

    /**
     * Dirty flag is used by the Node to determine
     * if the matrix is updated to latest
     * @name _dirty
     * @type {boolean}
     * @memberOf clay.Vector4#
     */
    this._dirty = true;
};

Vector4.prototype = {

    constructor: Vector4,

    /**
     * Add b to self
     * @param  {clay.Vector4} b
     * @return {clay.Vector4}
     */
    add: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].add(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Set x, y and z components
     * @param  {number}  x
     * @param  {number}  y
     * @param  {number}  z
     * @param  {number}  w
     * @return {clay.Vector4}
     */
    set: function(x, y, z, w) {
        this.array[0] = x;
        this.array[1] = y;
        this.array[2] = z;
        this.array[3] = w;
        this._dirty = true;
        return this;
    },

    /**
     * Set x, y, z and w components from array
     * @param  {Float32Array|number[]} arr
     * @return {clay.Vector4}
     */
    setArray: function(arr) {
        this.array[0] = arr[0];
        this.array[1] = arr[1];
        this.array[2] = arr[2];
        this.array[3] = arr[3];

        this._dirty = true;
        return this;
    },

    /**
     * Clone a new Vector4
     * @return {clay.Vector4}
     */
    clone: function() {
        return new Vector4(this.x, this.y, this.z, this.w);
    },

    /**
     * Copy from b
     * @param  {clay.Vector4} b
     * @return {clay.Vector4}
     */
    copy: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].copy(this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for distance
     * @param  {clay.Vector4} b
     * @return {number}
     */
    dist: function(b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].dist(this.array, b.array);
    },

    /**
     * Distance between self and b
     * @param  {clay.Vector4} b
     * @return {number}
     */
    distance: function(b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].distance(this.array, b.array);
    },

    /**
     * Alias for divide
     * @param  {clay.Vector4} b
     * @return {clay.Vector4}
     */
    div: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].div(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Divide self by b
     * @param  {clay.Vector4} b
     * @return {clay.Vector4}
     */
    divide: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].divide(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Dot product of self and b
     * @param  {clay.Vector4} b
     * @return {number}
     */
    dot: function(b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].dot(this.array, b.array);
    },

    /**
     * Alias of length
     * @return {number}
     */
    len: function() {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].len(this.array);
    },

    /**
     * Calculate the length
     * @return {number}
     */
    length: function() {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].length(this.array);
    },
    /**
     * Linear interpolation between a and b
     * @param  {clay.Vector4} a
     * @param  {clay.Vector4} b
     * @param  {number}  t
     * @return {clay.Vector4}
     */
    lerp: function(a, b, t) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].lerp(this.array, a.array, b.array, t);
        this._dirty = true;
        return this;
    },

    /**
     * Minimum of self and b
     * @param  {clay.Vector4} b
     * @return {clay.Vector4}
     */
    min: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].min(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Maximum of self and b
     * @param  {clay.Vector4} b
     * @return {clay.Vector4}
     */
    max: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].max(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for multiply
     * @param  {clay.Vector4} b
     * @return {clay.Vector4}
     */
    mul: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].mul(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Mutiply self and b
     * @param  {clay.Vector4} b
     * @return {clay.Vector4}
     */
    multiply: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].multiply(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Negate self
     * @return {clay.Vector4}
     */
    negate: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].negate(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Normalize self
     * @return {clay.Vector4}
     */
    normalize: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].normalize(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Generate random x, y, z, w components with a given scale
     * @param  {number} scale
     * @return {clay.Vector4}
     */
    random: function(scale) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].random(this.array, scale);
        this._dirty = true;
        return this;
    },

    /**
     * Scale self
     * @param  {number}  scale
     * @return {clay.Vector4}
     */
    scale: function(s) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].scale(this.array, this.array, s);
        this._dirty = true;
        return this;
    },
    /**
     * Scale b and add to self
     * @param  {clay.Vector4} b
     * @param  {number}  scale
     * @return {clay.Vector4}
     */
    scaleAndAdd: function(b, s) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].scaleAndAdd(this.array, this.array, b.array, s);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for squaredDistance
     * @param  {clay.Vector4} b
     * @return {number}
     */
    sqrDist: function(b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].sqrDist(this.array, b.array);
    },

    /**
     * Squared distance between self and b
     * @param  {clay.Vector4} b
     * @return {number}
     */
    squaredDistance: function(b) {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].squaredDistance(this.array, b.array);
    },

    /**
     * Alias for squaredLength
     * @return {number}
     */
    sqrLen: function() {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].sqrLen(this.array);
    },

    /**
     * Squared length of self
     * @return {number}
     */
    squaredLength: function() {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].squaredLength(this.array);
    },

    /**
     * Alias for subtract
     * @param  {clay.Vector4} b
     * @return {clay.Vector4}
     */
    sub: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].sub(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Subtract b from self
     * @param  {clay.Vector4} b
     * @return {clay.Vector4}
     */
    subtract: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].subtract(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Transform self with a Matrix4 m
     * @param  {clay.Matrix4} m
     * @return {clay.Vector4}
     */
    transformMat4: function(m) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].transformMat4(this.array, this.array, m.array);
        this._dirty = true;
        return this;
    },

    /**
     * Transform self with a Quaternion q
     * @param  {clay.Quaternion} q
     * @return {clay.Vector4}
     */
    transformQuat: function(q) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].transformQuat(this.array, this.array, q.array);
        this._dirty = true;
        return this;
    },

    toString: function() {
        return '[' + Array.prototype.join.call(this.array, ',') + ']';
    },

    toArray: function () {
        return Array.prototype.slice.call(this.array);
    }
};

var defineProperty = Object.defineProperty;
// Getter and Setter
if (defineProperty) {

    var proto = Vector4.prototype;
    /**
     * @name x
     * @type {number}
     * @memberOf clay.Vector4
     * @instance
     */
    defineProperty(proto, 'x', {
        get: function () {
            return this.array[0];
        },
        set: function (value) {
            this.array[0] = value;
            this._dirty = true;
        }
    });

    /**
     * @name y
     * @type {number}
     * @memberOf clay.Vector4
     * @instance
     */
    defineProperty(proto, 'y', {
        get: function () {
            return this.array[1];
        },
        set: function (value) {
            this.array[1] = value;
            this._dirty = true;
        }
    });

    /**
     * @name z
     * @type {number}
     * @memberOf clay.Vector4
     * @instance
     */
    defineProperty(proto, 'z', {
        get: function () {
            return this.array[2];
        },
        set: function (value) {
            this.array[2] = value;
            this._dirty = true;
        }
    });

    /**
     * @name w
     * @type {number}
     * @memberOf clay.Vector4
     * @instance
     */
    defineProperty(proto, 'w', {
        get: function () {
            return this.array[3];
        },
        set: function (value) {
            this.array[3] = value;
            this._dirty = true;
        }
    });
}

// Supply methods that are not in place

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {clay.Vector4}
 */
Vector4.add = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].add(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector4} out
 * @param  {number}  x
 * @param  {number}  y
 * @param  {number}  z
 * @return {clay.Vector4}
 */
Vector4.set = function(out, x, y, z, w) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].set(out.array, x, y, z, w);
    out._dirty = true;
};

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} b
 * @return {clay.Vector4}
 */
Vector4.copy = function(out, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].copy(out.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {number}
 */
Vector4.dist = function(a, b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].distance(a.array, b.array);
};

/**
 * @function
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {number}
 */
Vector4.distance = Vector4.dist;

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {clay.Vector4}
 */
Vector4.div = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].divide(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @function
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {clay.Vector4}
 */
Vector4.divide = Vector4.div;

/**
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {number}
 */
Vector4.dot = function(a, b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].dot(a.array, b.array);
};

/**
 * @param  {clay.Vector4} a
 * @return {number}
 */
Vector4.len = function(b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].length(b.array);
};

// Vector4.length = Vector4.len;

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @param  {number}  t
 * @return {clay.Vector4}
 */
Vector4.lerp = function(out, a, b, t) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].lerp(out.array, a.array, b.array, t);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {clay.Vector4}
 */
Vector4.min = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].min(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {clay.Vector4}
 */
Vector4.max = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].max(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {clay.Vector4}
 */
Vector4.mul = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].multiply(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @function
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {clay.Vector4}
 */
Vector4.multiply = Vector4.mul;

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @return {clay.Vector4}
 */
Vector4.negate = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].negate(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @return {clay.Vector4}
 */
Vector4.normalize = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].normalize(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector4} out
 * @param  {number}  scale
 * @return {clay.Vector4}
 */
Vector4.random = function(out, scale) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].random(out.array, scale);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {number}  scale
 * @return {clay.Vector4}
 */
Vector4.scale = function(out, a, scale) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].scale(out.array, a.array, scale);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @param  {number}  scale
 * @return {clay.Vector4}
 */
Vector4.scaleAndAdd = function(out, a, b, scale) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].scaleAndAdd(out.array, a.array, b.array, scale);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {number}
 */
Vector4.sqrDist = function(a, b) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].sqrDist(a.array, b.array);
};

/**
 * @function
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {number}
 */
Vector4.squaredDistance = Vector4.sqrDist;

/**
 * @param  {clay.Vector4} a
 * @return {number}
 */
Vector4.sqrLen = function(a) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].sqrLen(a.array);
};
/**
 * @function
 * @param  {clay.Vector4} a
 * @return {number}
 */
Vector4.squaredLength = Vector4.sqrLen;

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {clay.Vector4}
 */
Vector4.sub = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].subtract(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};
/**
 * @function
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Vector4} b
 * @return {clay.Vector4}
 */
Vector4.subtract = Vector4.sub;

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Matrix4} m
 * @return {clay.Vector4}
 */
Vector4.transformMat4 = function(out, a, m) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].transformMat4(out.array, a.array, m.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Vector4} out
 * @param  {clay.Vector4} a
 * @param  {clay.Quaternion} q
 * @return {clay.Vector4}
 */
Vector4.transformQuat = function(out, a, q) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_vec4__["a" /* default */].transformQuat(out.array, a.array, q.array);
    out._dirty = true;
    return out;
};

/* harmony default export */ __webpack_exports__["a"] = (Vector4);


/***/ }),
/* 138 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__ = __webpack_require__(78);


/**
 * @constructor
 * @alias clay.Matrix2
 */
var Matrix2 = function() {

    /**
     * Storage of Matrix2
     * @name array
     * @type {Float32Array}
     * @memberOf clay.Matrix2#
     */
    this.array = __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].create();

    /**
     * @name _dirty
     * @type {boolean}
     * @memberOf clay.Matrix2#
     */
    this._dirty = true;
};

Matrix2.prototype = {

    constructor: Matrix2,

    /**
     * Set components from array
     * @param  {Float32Array|number[]} arr
     */
    setArray: function (arr) {
        for (var i = 0; i < this.array.length; i++) {
            this.array[i] = arr[i];
        }
        this._dirty = true;
        return this;
    },
    /**
     * Clone a new Matrix2
     * @return {clay.Matrix2}
     */
    clone: function() {
        return (new Matrix2()).copy(this);
    },

    /**
     * Copy from b
     * @param  {clay.Matrix2} b
     * @return {clay.Matrix2}
     */
    copy: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].copy(this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Calculate the adjugate of self, in-place
     * @return {clay.Matrix2}
     */
    adjoint: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].adjoint(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Calculate matrix determinant
     * @return {number}
     */
    determinant: function() {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].determinant(this.array);
    },

    /**
     * Set to a identity matrix
     * @return {clay.Matrix2}
     */
    identity: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].identity(this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Invert self
     * @return {clay.Matrix2}
     */
    invert: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].invert(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for mutiply
     * @param  {clay.Matrix2} b
     * @return {clay.Matrix2}
     */
    mul: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].mul(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for multiplyLeft
     * @param  {clay.Matrix2} a
     * @return {clay.Matrix2}
     */
    mulLeft: function(a) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].mul(this.array, a.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Multiply self and b
     * @param  {clay.Matrix2} b
     * @return {clay.Matrix2}
     */
    multiply: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].multiply(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Multiply a and self, a is on the left
     * @param  {clay.Matrix2} a
     * @return {clay.Matrix2}
     */
    multiplyLeft: function(a) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].multiply(this.array, a.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Rotate self by a given radian
     * @param  {number}   rad
     * @return {clay.Matrix2}
     */
    rotate: function(rad) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].rotate(this.array, this.array, rad);
        this._dirty = true;
        return this;
    },

    /**
     * Scale self by s
     * @param  {clay.Vector2}  s
     * @return {clay.Matrix2}
     */
    scale: function(v) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].scale(this.array, this.array, v.array);
        this._dirty = true;
        return this;
    },
    /**
     * Transpose self, in-place.
     * @return {clay.Matrix2}
     */
    transpose: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].transpose(this.array, this.array);
        this._dirty = true;
        return this;
    },

    toString: function() {
        return '[' + Array.prototype.join.call(this.array, ',') + ']';
    },

    toArray: function () {
        return Array.prototype.slice.call(this.array);
    }
};

/**
 * @param  {Matrix2} out
 * @param  {Matrix2} a
 * @return {Matrix2}
 */
Matrix2.adjoint = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].adjoint(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix2} out
 * @param  {clay.Matrix2} a
 * @return {clay.Matrix2}
 */
Matrix2.copy = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].copy(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix2} a
 * @return {number}
 */
Matrix2.determinant = function(a) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].determinant(a.array);
};

/**
 * @param  {clay.Matrix2} out
 * @return {clay.Matrix2}
 */
Matrix2.identity = function(out) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].identity(out.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix2} out
 * @param  {clay.Matrix2} a
 * @return {clay.Matrix2}
 */
Matrix2.invert = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].invert(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix2} out
 * @param  {clay.Matrix2} a
 * @param  {clay.Matrix2} b
 * @return {clay.Matrix2}
 */
Matrix2.mul = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].mul(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @function
 * @param  {clay.Matrix2} out
 * @param  {clay.Matrix2} a
 * @param  {clay.Matrix2} b
 * @return {clay.Matrix2}
 */
Matrix2.multiply = Matrix2.mul;

/**
 * @param  {clay.Matrix2} out
 * @param  {clay.Matrix2} a
 * @param  {number}   rad
 * @return {clay.Matrix2}
 */
Matrix2.rotate = function(out, a, rad) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].rotate(out.array, a.array, rad);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix2} out
 * @param  {clay.Matrix2} a
 * @param  {clay.Vector2}  v
 * @return {clay.Matrix2}
 */
Matrix2.scale = function(out, a, v) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].scale(out.array, a.array, v.array);
    out._dirty = true;
    return out;
};
/**
 * @param  {Matrix2} out
 * @param  {Matrix2} a
 * @return {Matrix2}
 */
Matrix2.transpose = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2__["a" /* default */].transpose(out.array, a.array);
    out._dirty = true;
    return out;
};

/* harmony default export */ __webpack_exports__["a"] = (Matrix2);


/***/ }),
/* 139 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__ = __webpack_require__(79);


/**
 * @constructor
 * @alias clay.Matrix2d
 */
var Matrix2d = function() {
    /**
     * Storage of Matrix2d
     * @name array
     * @type {Float32Array}
     * @memberOf clay.Matrix2d#
     */
    this.array = __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].create();

    /**
     * @name _dirty
     * @type {boolean}
     * @memberOf clay.Matrix2d#
     */
    this._dirty = true;
};

Matrix2d.prototype = {

    constructor: Matrix2d,

    /**
     * Set components from array
     * @param  {Float32Array|number[]} arr
     */
    setArray: function (arr) {
        for (var i = 0; i < this.array.length; i++) {
            this.array[i] = arr[i];
        }
        this._dirty = true;
        return this;
    },
    /**
     * Clone a new Matrix2d
     * @return {clay.Matrix2d}
     */
    clone: function() {
        return (new Matrix2d()).copy(this);
    },

    /**
     * Copy from b
     * @param  {clay.Matrix2d} b
     * @return {clay.Matrix2d}
     */
    copy: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].copy(this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Calculate matrix determinant
     * @return {number}
     */
    determinant: function() {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].determinant(this.array);
    },

    /**
     * Set to a identity matrix
     * @return {clay.Matrix2d}
     */
    identity: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].identity(this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Invert self
     * @return {clay.Matrix2d}
     */
    invert: function() {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].invert(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for mutiply
     * @param  {clay.Matrix2d} b
     * @return {clay.Matrix2d}
     */
    mul: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].mul(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for multiplyLeft
     * @param  {clay.Matrix2d} a
     * @return {clay.Matrix2d}
     */
    mulLeft: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].mul(this.array, b.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Multiply self and b
     * @param  {clay.Matrix2d} b
     * @return {clay.Matrix2d}
     */
    multiply: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].multiply(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Multiply a and self, a is on the left
     * @param  {clay.Matrix2d} a
     * @return {clay.Matrix2d}
     */
    multiplyLeft: function(b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].multiply(this.array, b.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Rotate self by a given radian
     * @param  {number}   rad
     * @return {clay.Matrix2d}
     */
    rotate: function(rad) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].rotate(this.array, this.array, rad);
        this._dirty = true;
        return this;
    },

    /**
     * Scale self by s
     * @param  {clay.Vector2}  s
     * @return {clay.Matrix2d}
     */
    scale: function(s) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].scale(this.array, this.array, s.array);
        this._dirty = true;
        return this;
    },

    /**
     * Translate self by v
     * @param  {clay.Vector2}  v
     * @return {clay.Matrix2d}
     */
    translate: function(v) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].translate(this.array, this.array, v.array);
        this._dirty = true;
        return this;
    },

    toString: function() {
        return '[' + Array.prototype.join.call(this.array, ',') + ']';
    },

    toArray: function () {
        return Array.prototype.slice.call(this.array);
    }
};

/**
 * @param  {clay.Matrix2d} out
 * @param  {clay.Matrix2d} a
 * @return {clay.Matrix2d}
 */
Matrix2d.copy = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].copy(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix2d} a
 * @return {number}
 */
Matrix2d.determinant = function(a) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].determinant(a.array);
};

/**
 * @param  {clay.Matrix2d} out
 * @return {clay.Matrix2d}
 */
Matrix2d.identity = function(out) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].identity(out.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix2d} out
 * @param  {clay.Matrix2d} a
 * @return {clay.Matrix2d}
 */
Matrix2d.invert = function(out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].invert(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix2d} out
 * @param  {clay.Matrix2d} a
 * @param  {clay.Matrix2d} b
 * @return {clay.Matrix2d}
 */
Matrix2d.mul = function(out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].mul(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @function
 * @param  {clay.Matrix2d} out
 * @param  {clay.Matrix2d} a
 * @param  {clay.Matrix2d} b
 * @return {clay.Matrix2d}
 */
Matrix2d.multiply = Matrix2d.mul;

/**
 * @param  {clay.Matrix2d} out
 * @param  {clay.Matrix2d} a
 * @param  {number}   rad
 * @return {clay.Matrix2d}
 */
Matrix2d.rotate = function(out, a, rad) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].rotate(out.array, a.array, rad);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix2d} out
 * @param  {clay.Matrix2d} a
 * @param  {clay.Vector2}  v
 * @return {clay.Matrix2d}
 */
Matrix2d.scale = function(out, a, v) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].scale(out.array, a.array, v.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix2d} out
 * @param  {clay.Matrix2d} a
 * @param  {clay.Vector2}  v
 * @return {clay.Matrix2d}
 */
Matrix2d.translate = function(out, a, v) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat2d__["a" /* default */].translate(out.array, a.array, v.array);
    out._dirty = true;
    return out;
};

/* harmony default export */ __webpack_exports__["a"] = (Matrix2d);


/***/ }),
/* 140 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__ = __webpack_require__(34);


/**
 * @constructor
 * @alias clay.Matrix3
 */
var Matrix3 = function () {

    /**
     * Storage of Matrix3
     * @name array
     * @type {Float32Array}
     * @memberOf clay.Matrix3#
     */
    this.array = __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].create();

    /**
     * @name _dirty
     * @type {boolean}
     * @memberOf clay.Matrix3#
     */
    this._dirty = true;
};

Matrix3.prototype = {

    constructor: Matrix3,

    /**
     * Set components from array
     * @param  {Float32Array|number[]} arr
     */
    setArray: function (arr) {
        for (var i = 0; i < this.array.length; i++) {
            this.array[i] = arr[i];
        }
        this._dirty = true;
        return this;
    },
    /**
     * Calculate the adjugate of self, in-place
     * @return {clay.Matrix3}
     */
    adjoint: function () {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].adjoint(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Clone a new Matrix3
     * @return {clay.Matrix3}
     */
    clone: function () {
        return (new Matrix3()).copy(this);
    },

    /**
     * Copy from b
     * @param  {clay.Matrix3} b
     * @return {clay.Matrix3}
     */
    copy: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].copy(this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Calculate matrix determinant
     * @return {number}
     */
    determinant: function () {
        return __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].determinant(this.array);
    },

    /**
     * Copy the values from Matrix2d a
     * @param  {clay.Matrix2d} a
     * @return {clay.Matrix3}
     */
    fromMat2d: function (a) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].fromMat2d(this.array, a.array);
        this._dirty = true;
        return this;
    },

    /**
     * Copies the upper-left 3x3 values of Matrix4
     * @param  {clay.Matrix4} a
     * @return {clay.Matrix3}
     */
    fromMat4: function (a) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].fromMat4(this.array, a.array);
        this._dirty = true;
        return this;
    },

    /**
     * Calculates a rotation matrix from the given quaternion
     * @param  {clay.Quaternion} q
     * @return {clay.Matrix3}
     */
    fromQuat: function (q) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].fromQuat(this.array, q.array);
        this._dirty = true;
        return this;
    },

    /**
     * Set to a identity matrix
     * @return {clay.Matrix3}
     */
    identity: function () {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].identity(this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Invert self
     * @return {clay.Matrix3}
     */
    invert: function () {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].invert(this.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for mutiply
     * @param  {clay.Matrix3} b
     * @return {clay.Matrix3}
     */
    mul: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].mul(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Alias for multiplyLeft
     * @param  {clay.Matrix3} a
     * @return {clay.Matrix3}
     */
    mulLeft: function (a) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].mul(this.array, a.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Multiply self and b
     * @param  {clay.Matrix3} b
     * @return {clay.Matrix3}
     */
    multiply: function (b) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].multiply(this.array, this.array, b.array);
        this._dirty = true;
        return this;
    },

    /**
     * Multiply a and self, a is on the left
     * @param  {clay.Matrix3} a
     * @return {clay.Matrix3}
     */
    multiplyLeft: function (a) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].multiply(this.array, a.array, this.array);
        this._dirty = true;
        return this;
    },

    /**
     * Rotate self by a given radian
     * @param  {number}   rad
     * @return {clay.Matrix3}
     */
    rotate: function (rad) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].rotate(this.array, this.array, rad);
        this._dirty = true;
        return this;
    },

    /**
     * Scale self by s
     * @param  {clay.Vector2}  s
     * @return {clay.Matrix3}
     */
    scale: function (v) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].scale(this.array, this.array, v.array);
        this._dirty = true;
        return this;
    },

    /**
     * Translate self by v
     * @param  {clay.Vector2}  v
     * @return {clay.Matrix3}
     */
    translate: function (v) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].translate(this.array, this.array, v.array);
        this._dirty = true;
        return this;
    },
    /**
     * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
     * @param {clay.Matrix4} a
     */
    normalFromMat4: function (a) {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].normalFromMat4(this.array, a.array);
        this._dirty = true;
        return this;
    },

    /**
     * Transpose self, in-place.
     * @return {clay.Matrix2}
     */
    transpose: function () {
        __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].transpose(this.array, this.array);
        this._dirty = true;
        return this;
    },

    toString: function () {
        return '[' + Array.prototype.join.call(this.array, ',') + ']';
    },

    toArray: function () {
        return Array.prototype.slice.call(this.array);
    }
};
/**
 * @param  {clay.Matrix3} out
 * @param  {clay.Matrix3} a
 * @return {clay.Matrix3}
 */
Matrix3.adjoint = function (out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].adjoint(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix3} out
 * @param  {clay.Matrix3} a
 * @return {clay.Matrix3}
 */
Matrix3.copy = function (out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].copy(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix3} a
 * @return {number}
 */
Matrix3.determinant = function (a) {
    return __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].determinant(a.array);
};

/**
 * @param  {clay.Matrix3} out
 * @return {clay.Matrix3}
 */
Matrix3.identity = function (out) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].identity(out.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix3} out
 * @param  {clay.Matrix3} a
 * @return {clay.Matrix3}
 */
Matrix3.invert = function (out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].invert(out.array, a.array);
    return out;
};

/**
 * @param  {clay.Matrix3} out
 * @param  {clay.Matrix3} a
 * @param  {clay.Matrix3} b
 * @return {clay.Matrix3}
 */
Matrix3.mul = function (out, a, b) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].mul(out.array, a.array, b.array);
    out._dirty = true;
    return out;
};

/**
 * @function
 * @param  {clay.Matrix3} out
 * @param  {clay.Matrix3} a
 * @param  {clay.Matrix3} b
 * @return {clay.Matrix3}
 */
Matrix3.multiply = Matrix3.mul;

/**
 * @param  {clay.Matrix3}  out
 * @param  {clay.Matrix2d} a
 * @return {clay.Matrix3}
 */
Matrix3.fromMat2d = function (out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].fromMat2d(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix3} out
 * @param  {clay.Matrix4} a
 * @return {clay.Matrix3}
 */
Matrix3.fromMat4 = function (out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].fromMat4(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix3}    out
 * @param  {clay.Quaternion} a
 * @return {clay.Matrix3}
 */
Matrix3.fromQuat = function (out, q) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].fromQuat(out.array, q.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix3} out
 * @param  {clay.Matrix4} a
 * @return {clay.Matrix3}
 */
Matrix3.normalFromMat4 = function (out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].normalFromMat4(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix3} out
 * @param  {clay.Matrix3} a
 * @param  {number}  rad
 * @return {clay.Matrix3}
 */
Matrix3.rotate = function (out, a, rad) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].rotate(out.array, a.array, rad);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix3} out
 * @param  {clay.Matrix3} a
 * @param  {clay.Vector2} v
 * @return {clay.Matrix3}
 */
Matrix3.scale = function (out, a, v) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].scale(out.array, a.array, v.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix3} out
 * @param  {clay.Matrix3} a
 * @return {clay.Matrix3}
 */
Matrix3.transpose = function (out, a) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].transpose(out.array, a.array);
    out._dirty = true;
    return out;
};

/**
 * @param  {clay.Matrix3} out
 * @param  {clay.Matrix3} a
 * @param  {clay.Vector2} v
 * @return {clay.Matrix3}
 */
Matrix3.translate = function (out, a, v) {
    __WEBPACK_IMPORTED_MODULE_0__glmatrix_mat3__["a" /* default */].translate(out.array, a.array, v.array);
    out._dirty = true;
    return out;
};

/* harmony default export */ __webpack_exports__["a"] = (Matrix3);


/***/ }),
/* 141 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_zrender_lib_animation_Animator__ = __webpack_require__(142);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_zrender_lib_animation_Animator___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_zrender_lib_animation_Animator__);


var animatableMixin = {

    _animators: null,

    getAnimators: function () {
        this._animators = this._animators || [];

        return this._animators;
    },

    animate: function (path, opts) {
        this._animators = this._animators || [];

        var el = this;

        var target;

        if (path) {
            var pathSplitted = path.split('.');
            var prop = el;
            for (var i = 0, l = pathSplitted.length; i < l; i++) {
                if (!prop) {
                    continue;
                }
                prop = prop[pathSplitted[i]];
            }
            if (prop) {
                target = prop;
            }
        }
        else {
            target = el;
        }
        if (target == null) {
            throw new Error('Target ' + path + ' not exists');
        }

        var animators = this._animators;

        var animator = new __WEBPACK_IMPORTED_MODULE_0_zrender_lib_animation_Animator___default.a(target, opts);
        var self = this;
        animator.during(function () {
            if (self.__zr) {
                self.__zr.refresh();
            }
        }).done(function () {
            var idx = animators.indexOf(animator);
            if (idx >= 0) {
                animators.splice(idx, 1);
            }
        });
        animators.push(animator);

        if (this.__zr) {
            this.__zr.animation.addAnimator(animator);
        }

        return animator;
    },

    stopAnimation: function (forwardToLast) {
        this._animators = this._animators || [];

        var animators = this._animators;
        var len = animators.length;
        for (var i = 0; i < len; i++) {
            animators[i].stop(forwardToLast);
        }
        animators.length = 0;

        return this;
    },

    addAnimatorsToZr: function (zr) {
        if (this._animators) {
            for (var i = 0; i < this._animators.length; i++) {
                zr.animation.addAnimator(this._animators[i]);
            }
        }
    },

    removeAnimatorsFromZr: function (zr) {
        if (this._animators) {
            for (var i = 0; i < this._animators.length; i++) {
                zr.animation.removeAnimator(this._animators[i]);
            }
        }
    }
};

/* harmony default export */ __webpack_exports__["a"] = (animatableMixin);

/***/ }),
/* 142 */
/***/ (function(module, exports, __webpack_require__) {

var Clip = __webpack_require__(143);

var color = __webpack_require__(145);

var _util = __webpack_require__(13);

var isArrayLike = _util.isArrayLike;

/**
 * @module echarts/animation/Animator
 */
var arraySlice = Array.prototype.slice;

function defaultGetter(target, key) {
  return target[key];
}

function defaultSetter(target, key, value) {
  target[key] = value;
}
/**
 * @param  {number} p0
 * @param  {number} p1
 * @param  {number} percent
 * @return {number}
 */


function interpolateNumber(p0, p1, percent) {
  return (p1 - p0) * percent + p0;
}
/**
 * @param  {string} p0
 * @param  {string} p1
 * @param  {number} percent
 * @return {string}
 */


function interpolateString(p0, p1, percent) {
  return percent > 0.5 ? p1 : p0;
}
/**
 * @param  {Array} p0
 * @param  {Array} p1
 * @param  {number} percent
 * @param  {Array} out
 * @param  {number} arrDim
 */


function interpolateArray(p0, p1, percent, out, arrDim) {
  var len = p0.length;

  if (arrDim == 1) {
    for (var i = 0; i < len; i++) {
      out[i] = interpolateNumber(p0[i], p1[i], percent);
    }
  } else {
    var len2 = len && p0[0].length;

    for (var i = 0; i < len; i++) {
      for (var j = 0; j < len2; j++) {
        out[i][j] = interpolateNumber(p0[i][j], p1[i][j], percent);
      }
    }
  }
} // arr0 is source array, arr1 is target array.
// Do some preprocess to avoid error happened when interpolating from arr0 to arr1


function fillArr(arr0, arr1, arrDim) {
  var arr0Len = arr0.length;
  var arr1Len = arr1.length;

  if (arr0Len !== arr1Len) {
    // FIXME Not work for TypedArray
    var isPreviousLarger = arr0Len > arr1Len;

    if (isPreviousLarger) {
      // Cut the previous
      arr0.length = arr1Len;
    } else {
      // Fill the previous
      for (var i = arr0Len; i < arr1Len; i++) {
        arr0.push(arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i]));
      }
    }
  } // Handling NaN value


  var len2 = arr0[0] && arr0[0].length;

  for (var i = 0; i < arr0.length; i++) {
    if (arrDim === 1) {
      if (isNaN(arr0[i])) {
        arr0[i] = arr1[i];
      }
    } else {
      for (var j = 0; j < len2; j++) {
        if (isNaN(arr0[i][j])) {
          arr0[i][j] = arr1[i][j];
        }
      }
    }
  }
}
/**
 * @param  {Array} arr0
 * @param  {Array} arr1
 * @param  {number} arrDim
 * @return {boolean}
 */


function isArraySame(arr0, arr1, arrDim) {
  if (arr0 === arr1) {
    return true;
  }

  var len = arr0.length;

  if (len !== arr1.length) {
    return false;
  }

  if (arrDim === 1) {
    for (var i = 0; i < len; i++) {
      if (arr0[i] !== arr1[i]) {
        return false;
      }
    }
  } else {
    var len2 = arr0[0].length;

    for (var i = 0; i < len; i++) {
      for (var j = 0; j < len2; j++) {
        if (arr0[i][j] !== arr1[i][j]) {
          return false;
        }
      }
    }
  }

  return true;
}
/**
 * Catmull Rom interpolate array
 * @param  {Array} p0
 * @param  {Array} p1
 * @param  {Array} p2
 * @param  {Array} p3
 * @param  {number} t
 * @param  {number} t2
 * @param  {number} t3
 * @param  {Array} out
 * @param  {number} arrDim
 */


function catmullRomInterpolateArray(p0, p1, p2, p3, t, t2, t3, out, arrDim) {
  var len = p0.length;

  if (arrDim == 1) {
    for (var i = 0; i < len; i++) {
      out[i] = catmullRomInterpolate(p0[i], p1[i], p2[i], p3[i], t, t2, t3);
    }
  } else {
    var len2 = p0[0].length;

    for (var i = 0; i < len; i++) {
      for (var j = 0; j < len2; j++) {
        out[i][j] = catmullRomInterpolate(p0[i][j], p1[i][j], p2[i][j], p3[i][j], t, t2, t3);
      }
    }
  }
}
/**
 * Catmull Rom interpolate number
 * @param  {number} p0
 * @param  {number} p1
 * @param  {number} p2
 * @param  {number} p3
 * @param  {number} t
 * @param  {number} t2
 * @param  {number} t3
 * @return {number}
 */


function catmullRomInterpolate(p0, p1, p2, p3, t, t2, t3) {
  var v0 = (p2 - p0) * 0.5;
  var v1 = (p3 - p1) * 0.5;
  return (2 * (p1 - p2) + v0 + v1) * t3 + (-3 * (p1 - p2) - 2 * v0 - v1) * t2 + v0 * t + p1;
}

function cloneValue(value) {
  if (isArrayLike(value)) {
    var len = value.length;

    if (isArrayLike(value[0])) {
      var ret = [];

      for (var i = 0; i < len; i++) {
        ret.push(arraySlice.call(value[i]));
      }

      return ret;
    }

    return arraySlice.call(value);
  }

  return value;
}

function rgba2String(rgba) {
  rgba[0] = Math.floor(rgba[0]);
  rgba[1] = Math.floor(rgba[1]);
  rgba[2] = Math.floor(rgba[2]);
  return 'rgba(' + rgba.join(',') + ')';
}

function getArrayDim(keyframes) {
  var lastValue = keyframes[keyframes.length - 1].value;
  return isArrayLike(lastValue && lastValue[0]) ? 2 : 1;
}

function createTrackClip(animator, easing, oneTrackDone, keyframes, propName, forceAnimate) {
  var getter = animator._getter;
  var setter = animator._setter;
  var useSpline = easing === 'spline';
  var trackLen = keyframes.length;

  if (!trackLen) {
    return;
  } // Guess data type


  var firstVal = keyframes[0].value;
  var isValueArray = isArrayLike(firstVal);
  var isValueColor = false;
  var isValueString = false; // For vertices morphing

  var arrDim = isValueArray ? getArrayDim(keyframes) : 0;
  var trackMaxTime; // Sort keyframe as ascending

  keyframes.sort(function (a, b) {
    return a.time - b.time;
  });
  trackMaxTime = keyframes[trackLen - 1].time; // Percents of each keyframe

  var kfPercents = []; // Value of each keyframe

  var kfValues = [];
  var prevValue = keyframes[0].value;
  var isAllValueEqual = true;

  for (var i = 0; i < trackLen; i++) {
    kfPercents.push(keyframes[i].time / trackMaxTime); // Assume value is a color when it is a string

    var value = keyframes[i].value; // Check if value is equal, deep check if value is array

    if (!(isValueArray && isArraySame(value, prevValue, arrDim) || !isValueArray && value === prevValue)) {
      isAllValueEqual = false;
    }

    prevValue = value; // Try converting a string to a color array

    if (typeof value == 'string') {
      var colorArray = color.parse(value);

      if (colorArray) {
        value = colorArray;
        isValueColor = true;
      } else {
        isValueString = true;
      }
    }

    kfValues.push(value);
  }

  if (!forceAnimate && isAllValueEqual) {
    return;
  }

  var lastValue = kfValues[trackLen - 1]; // Polyfill array and NaN value

  for (var i = 0; i < trackLen - 1; i++) {
    if (isValueArray) {
      fillArr(kfValues[i], lastValue, arrDim);
    } else {
      if (isNaN(kfValues[i]) && !isNaN(lastValue) && !isValueString && !isValueColor) {
        kfValues[i] = lastValue;
      }
    }
  }

  isValueArray && fillArr(getter(animator._target, propName), lastValue, arrDim); // Cache the key of last frame to speed up when
  // animation playback is sequency

  var lastFrame = 0;
  var lastFramePercent = 0;
  var start;
  var w;
  var p0;
  var p1;
  var p2;
  var p3;

  if (isValueColor) {
    var rgba = [0, 0, 0, 0];
  }

  var onframe = function (target, percent) {
    // Find the range keyframes
    // kf1-----kf2---------current--------kf3
    // find kf2 and kf3 and do interpolation
    var frame; // In the easing function like elasticOut, percent may less than 0

    if (percent < 0) {
      frame = 0;
    } else if (percent < lastFramePercent) {
      // Start from next key
      // PENDING start from lastFrame ?
      start = Math.min(lastFrame + 1, trackLen - 1);

      for (frame = start; frame >= 0; frame--) {
        if (kfPercents[frame] <= percent) {
          break;
        }
      } // PENDING really need to do this ?


      frame = Math.min(frame, trackLen - 2);
    } else {
      for (frame = lastFrame; frame < trackLen; frame++) {
        if (kfPercents[frame] > percent) {
          break;
        }
      }

      frame = Math.min(frame - 1, trackLen - 2);
    }

    lastFrame = frame;
    lastFramePercent = percent;
    var range = kfPercents[frame + 1] - kfPercents[frame];

    if (range === 0) {
      return;
    } else {
      w = (percent - kfPercents[frame]) / range;
    }

    if (useSpline) {
      p1 = kfValues[frame];
      p0 = kfValues[frame === 0 ? frame : frame - 1];
      p2 = kfValues[frame > trackLen - 2 ? trackLen - 1 : frame + 1];
      p3 = kfValues[frame > trackLen - 3 ? trackLen - 1 : frame + 2];

      if (isValueArray) {
        catmullRomInterpolateArray(p0, p1, p2, p3, w, w * w, w * w * w, getter(target, propName), arrDim);
      } else {
        var value;

        if (isValueColor) {
          value = catmullRomInterpolateArray(p0, p1, p2, p3, w, w * w, w * w * w, rgba, 1);
          value = rgba2String(rgba);
        } else if (isValueString) {
          // String is step(0.5)
          return interpolateString(p1, p2, w);
        } else {
          value = catmullRomInterpolate(p0, p1, p2, p3, w, w * w, w * w * w);
        }

        setter(target, propName, value);
      }
    } else {
      if (isValueArray) {
        interpolateArray(kfValues[frame], kfValues[frame + 1], w, getter(target, propName), arrDim);
      } else {
        var value;

        if (isValueColor) {
          interpolateArray(kfValues[frame], kfValues[frame + 1], w, rgba, 1);
          value = rgba2String(rgba);
        } else if (isValueString) {
          // String is step(0.5)
          return interpolateString(kfValues[frame], kfValues[frame + 1], w);
        } else {
          value = interpolateNumber(kfValues[frame], kfValues[frame + 1], w);
        }

        setter(target, propName, value);
      }
    }
  };

  var clip = new Clip({
    target: animator._target,
    life: trackMaxTime,
    loop: animator._loop,
    delay: animator._delay,
    onframe: onframe,
    ondestroy: oneTrackDone
  });

  if (easing && easing !== 'spline') {
    clip.easing = easing;
  }

  return clip;
}
/**
 * @alias module:zrender/animation/Animator
 * @constructor
 * @param {Object} target
 * @param {boolean} loop
 * @param {Function} getter
 * @param {Function} setter
 */


var Animator = function (target, loop, getter, setter) {
  this._tracks = {};
  this._target = target;
  this._loop = loop || false;
  this._getter = getter || defaultGetter;
  this._setter = setter || defaultSetter;
  this._clipCount = 0;
  this._delay = 0;
  this._doneList = [];
  this._onframeList = [];
  this._clipList = [];
};

Animator.prototype = {
  /**
   * 设置动画关键帧
   * @param  {number} time 关键帧时间，单位是ms
   * @param  {Object} props 关键帧的属性值，key-value表示
   * @return {module:zrender/animation/Animator}
   */
  when: function (time
  /* ms */
  , props) {
    var tracks = this._tracks;

    for (var propName in props) {
      if (!props.hasOwnProperty(propName)) {
        continue;
      }

      if (!tracks[propName]) {
        tracks[propName] = []; // Invalid value

        var value = this._getter(this._target, propName);

        if (value == null) {
          // zrLog('Invalid property ' + propName);
          continue;
        } // If time is 0
        //  Then props is given initialize value
        // Else
        //  Initialize value from current prop value


        if (time !== 0) {
          tracks[propName].push({
            time: 0,
            value: cloneValue(value)
          });
        }
      }

      tracks[propName].push({
        time: time,
        value: props[propName]
      });
    }

    return this;
  },

  /**
   * 添加动画每一帧的回调函数
   * @param  {Function} callback
   * @return {module:zrender/animation/Animator}
   */
  during: function (callback) {
    this._onframeList.push(callback);

    return this;
  },
  pause: function () {
    for (var i = 0; i < this._clipList.length; i++) {
      this._clipList[i].pause();
    }

    this._paused = true;
  },
  resume: function () {
    for (var i = 0; i < this._clipList.length; i++) {
      this._clipList[i].resume();
    }

    this._paused = false;
  },
  isPaused: function () {
    return !!this._paused;
  },
  _doneCallback: function () {
    // Clear all tracks
    this._tracks = {}; // Clear all clips

    this._clipList.length = 0;
    var doneList = this._doneList;
    var len = doneList.length;

    for (var i = 0; i < len; i++) {
      doneList[i].call(this);
    }
  },

  /**
   * 开始执行动画
   * @param  {string|Function} [easing]
   *         动画缓动函数，详见{@link module:zrender/animation/easing}
   * @param  {boolean} forceAnimate
   * @return {module:zrender/animation/Animator}
   */
  start: function (easing, forceAnimate) {
    var self = this;
    var clipCount = 0;

    var oneTrackDone = function () {
      clipCount--;

      if (!clipCount) {
        self._doneCallback();
      }
    };

    var lastClip;

    for (var propName in this._tracks) {
      if (!this._tracks.hasOwnProperty(propName)) {
        continue;
      }

      var clip = createTrackClip(this, easing, oneTrackDone, this._tracks[propName], propName, forceAnimate);

      if (clip) {
        this._clipList.push(clip);

        clipCount++; // If start after added to animation

        if (this.animation) {
          this.animation.addClip(clip);
        }

        lastClip = clip;
      }
    } // Add during callback on the last clip


    if (lastClip) {
      var oldOnFrame = lastClip.onframe;

      lastClip.onframe = function (target, percent) {
        oldOnFrame(target, percent);

        for (var i = 0; i < self._onframeList.length; i++) {
          self._onframeList[i](target, percent);
        }
      };
    } // This optimization will help the case that in the upper application
    // the view may be refreshed frequently, where animation will be
    // called repeatly but nothing changed.


    if (!clipCount) {
      this._doneCallback();
    }

    return this;
  },

  /**
   * 停止动画
   * @param {boolean} forwardToLast If move to last frame before stop
   */
  stop: function (forwardToLast) {
    var clipList = this._clipList;
    var animation = this.animation;

    for (var i = 0; i < clipList.length; i++) {
      var clip = clipList[i];

      if (forwardToLast) {
        // Move to last frame before stop
        clip.onframe(this._target, 1);
      }

      animation && animation.removeClip(clip);
    }

    clipList.length = 0;
  },

  /**
   * 设置动画延迟开始的时间
   * @param  {number} time 单位ms
   * @return {module:zrender/animation/Animator}
   */
  delay: function (time) {
    this._delay = time;
    return this;
  },

  /**
   * 添加动画结束的回调
   * @param  {Function} cb
   * @return {module:zrender/animation/Animator}
   */
  done: function (cb) {
    if (cb) {
      this._doneList.push(cb);
    }

    return this;
  },

  /**
   * @return {Array.<module:zrender/animation/Clip>}
   */
  getClips: function () {
    return this._clipList;
  }
};
var _default = Animator;
module.exports = _default;

/***/ }),
/* 143 */
/***/ (function(module, exports, __webpack_require__) {

var easingFuncs = __webpack_require__(144);

/**
 * 动画主控制器
 * @config target 动画对象，可以是数组，如果是数组的话会批量分发onframe等事件
 * @config life(1000) 动画时长
 * @config delay(0) 动画延迟时间
 * @config loop(true)
 * @config gap(0) 循环的间隔时间
 * @config onframe
 * @config easing(optional)
 * @config ondestroy(optional)
 * @config onrestart(optional)
 *
 * TODO pause
 */
function Clip(options) {
  this._target = options.target; // 生命周期

  this._life = options.life || 1000; // 延时

  this._delay = options.delay || 0; // 开始时间
  // this._startTime = new Date().getTime() + this._delay;// 单位毫秒

  this._initialized = false; // 是否循环

  this.loop = options.loop == null ? false : options.loop;
  this.gap = options.gap || 0;
  this.easing = options.easing || 'Linear';
  this.onframe = options.onframe;
  this.ondestroy = options.ondestroy;
  this.onrestart = options.onrestart;
  this._pausedTime = 0;
  this._paused = false;
}

Clip.prototype = {
  constructor: Clip,
  step: function (globalTime, deltaTime) {
    // Set startTime on first step, or _startTime may has milleseconds different between clips
    // PENDING
    if (!this._initialized) {
      this._startTime = globalTime + this._delay;
      this._initialized = true;
    }

    if (this._paused) {
      this._pausedTime += deltaTime;
      return;
    }

    var percent = (globalTime - this._startTime - this._pausedTime) / this._life; // 还没开始

    if (percent < 0) {
      return;
    }

    percent = Math.min(percent, 1);
    var easing = this.easing;
    var easingFunc = typeof easing == 'string' ? easingFuncs[easing] : easing;
    var schedule = typeof easingFunc === 'function' ? easingFunc(percent) : percent;
    this.fire('frame', schedule); // 结束

    if (percent == 1) {
      if (this.loop) {
        this.restart(globalTime); // 重新开始周期
        // 抛出而不是直接调用事件直到 stage.update 后再统一调用这些事件

        return 'restart';
      } // 动画完成将这个控制器标识为待删除
      // 在Animation.update中进行批量删除


      this._needsRemove = true;
      return 'destroy';
    }

    return null;
  },
  restart: function (globalTime) {
    var remainder = (globalTime - this._startTime - this._pausedTime) % this._life;
    this._startTime = globalTime - remainder + this.gap;
    this._pausedTime = 0;
    this._needsRemove = false;
  },
  fire: function (eventType, arg) {
    eventType = 'on' + eventType;

    if (this[eventType]) {
      this[eventType](this._target, arg);
    }
  },
  pause: function () {
    this._paused = true;
  },
  resume: function () {
    this._paused = false;
  }
};
var _default = Clip;
module.exports = _default;

/***/ }),
/* 144 */
/***/ (function(module, exports) {

/**
 * 缓动代码来自 https://github.com/sole/tween.js/blob/master/src/Tween.js
 * @see http://sole.github.io/tween.js/examples/03_graphs.html
 * @exports zrender/animation/easing
 */
var easing = {
  /**
  * @param {number} k
  * @return {number}
  */
  linear: function (k) {
    return k;
  },

  /**
  * @param {number} k
  * @return {number}
  */
  quadraticIn: function (k) {
    return k * k;
  },

  /**
  * @param {number} k
  * @return {number}
  */
  quadraticOut: function (k) {
    return k * (2 - k);
  },

  /**
  * @param {number} k
  * @return {number}
  */
  quadraticInOut: function (k) {
    if ((k *= 2) < 1) {
      return 0.5 * k * k;
    }

    return -0.5 * (--k * (k - 2) - 1);
  },
  // 三次方的缓动（t^3）

  /**
  * @param {number} k
  * @return {number}
  */
  cubicIn: function (k) {
    return k * k * k;
  },

  /**
  * @param {number} k
  * @return {number}
  */
  cubicOut: function (k) {
    return --k * k * k + 1;
  },

  /**
  * @param {number} k
  * @return {number}
  */
  cubicInOut: function (k) {
    if ((k *= 2) < 1) {
      return 0.5 * k * k * k;
    }

    return 0.5 * ((k -= 2) * k * k + 2);
  },
  // 四次方的缓动（t^4）

  /**
  * @param {number} k
  * @return {number}
  */
  quarticIn: function (k) {
    return k * k * k * k;
  },

  /**
  * @param {number} k
  * @return {number}
  */
  quarticOut: function (k) {
    return 1 - --k * k * k * k;
  },

  /**
  * @param {number} k
  * @return {number}
  */
  quarticInOut: function (k) {
    if ((k *= 2) < 1) {
      return 0.5 * k * k * k * k;
    }

    return -0.5 * ((k -= 2) * k * k * k - 2);
  },
  // 五次方的缓动（t^5）

  /**
  * @param {number} k
  * @return {number}
  */
  quinticIn: function (k) {
    return k * k * k * k * k;
  },

  /**
  * @param {number} k
  * @return {number}
  */
  quinticOut: function (k) {
    return --k * k * k * k * k + 1;
  },

  /**
  * @param {number} k
  * @return {number}
  */
  quinticInOut: function (k) {
    if ((k *= 2) < 1) {
      return 0.5 * k * k * k * k * k;
    }

    return 0.5 * ((k -= 2) * k * k * k * k + 2);
  },
  // 正弦曲线的缓动（sin(t)）

  /**
  * @param {number} k
  * @return {number}
  */
  sinusoidalIn: function (k) {
    return 1 - Math.cos(k * Math.PI / 2);
  },

  /**
  * @param {number} k
  * @return {number}
  */
  sinusoidalOut: function (k) {
    return Math.sin(k * Math.PI / 2);
  },

  /**
  * @param {number} k
  * @return {number}
  */
  sinusoidalInOut: function (k) {
    return 0.5 * (1 - Math.cos(Math.PI * k));
  },
  // 指数曲线的缓动（2^t）

  /**
  * @param {number} k
  * @return {number}
  */
  exponentialIn: function (k) {
    return k === 0 ? 0 : Math.pow(1024, k - 1);
  },

  /**
  * @param {number} k
  * @return {number}
  */
  exponentialOut: function (k) {
    return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
  },

  /**
  * @param {number} k
  * @return {number}
  */
  exponentialInOut: function (k) {
    if (k === 0) {
      return 0;
    }

    if (k === 1) {
      return 1;
    }

    if ((k *= 2) < 1) {
      return 0.5 * Math.pow(1024, k - 1);
    }

    return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);
  },
  // 圆形曲线的缓动（sqrt(1-t^2)）

  /**
  * @param {number} k
  * @return {number}
  */
  circularIn: function (k) {
    return 1 - Math.sqrt(1 - k * k);
  },

  /**
  * @param {number} k
  * @return {number}
  */
  circularOut: function (k) {
    return Math.sqrt(1 - --k * k);
  },

  /**
  * @param {number} k
  * @return {number}
  */
  circularInOut: function (k) {
    if ((k *= 2) < 1) {
      return -0.5 * (Math.sqrt(1 - k * k) - 1);
    }

    return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
  },
  // 创建类似于弹簧在停止前来回振荡的动画

  /**
  * @param {number} k
  * @return {number}
  */
  elasticIn: function (k) {
    var s;
    var a = 0.1;
    var p = 0.4;

    if (k === 0) {
      return 0;
    }

    if (k === 1) {
      return 1;
    }

    if (!a || a < 1) {
      a = 1;
      s = p / 4;
    } else {
      s = p * Math.asin(1 / a) / (2 * Math.PI);
    }

    return -(a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
  },

  /**
  * @param {number} k
  * @return {number}
  */
  elasticOut: function (k) {
    var s;
    var a = 0.1;
    var p = 0.4;

    if (k === 0) {
      return 0;
    }

    if (k === 1) {
      return 1;
    }

    if (!a || a < 1) {
      a = 1;
      s = p / 4;
    } else {
      s = p * Math.asin(1 / a) / (2 * Math.PI);
    }

    return a * Math.pow(2, -10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1;
  },

  /**
  * @param {number} k
  * @return {number}
  */
  elasticInOut: function (k) {
    var s;
    var a = 0.1;
    var p = 0.4;

    if (k === 0) {
      return 0;
    }

    if (k === 1) {
      return 1;
    }

    if (!a || a < 1) {
      a = 1;
      s = p / 4;
    } else {
      s = p * Math.asin(1 / a) / (2 * Math.PI);
    }

    if ((k *= 2) < 1) {
      return -0.5 * (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
    }

    return a * Math.pow(2, -10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;
  },
  // 在某一动画开始沿指示的路径进行动画处理前稍稍收回该动画的移动

  /**
  * @param {number} k
  * @return {number}
  */
  backIn: function (k) {
    var s = 1.70158;
    return k * k * ((s + 1) * k - s);
  },

  /**
  * @param {number} k
  * @return {number}
  */
  backOut: function (k) {
    var s = 1.70158;
    return --k * k * ((s + 1) * k + s) + 1;
  },

  /**
  * @param {number} k
  * @return {number}
  */
  backInOut: function (k) {
    var s = 1.70158 * 1.525;

    if ((k *= 2) < 1) {
      return 0.5 * (k * k * ((s + 1) * k - s));
    }

    return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
  },
  // 创建弹跳效果

  /**
  * @param {number} k
  * @return {number}
  */
  bounceIn: function (k) {
    return 1 - easing.bounceOut(1 - k);
  },

  /**
  * @param {number} k
  * @return {number}
  */
  bounceOut: function (k) {
    if (k < 1 / 2.75) {
      return 7.5625 * k * k;
    } else if (k < 2 / 2.75) {
      return 7.5625 * (k -= 1.5 / 2.75) * k + 0.75;
    } else if (k < 2.5 / 2.75) {
      return 7.5625 * (k -= 2.25 / 2.75) * k + 0.9375;
    } else {
      return 7.5625 * (k -= 2.625 / 2.75) * k + 0.984375;
    }
  },

  /**
  * @param {number} k
  * @return {number}
  */
  bounceInOut: function (k) {
    if (k < 0.5) {
      return easing.bounceIn(k * 2) * 0.5;
    }

    return easing.bounceOut(k * 2 - 1) * 0.5 + 0.5;
  }
};
var _default = easing;
module.exports = _default;

/***/ }),
/* 145 */
/***/ (function(module, exports, __webpack_require__) {

var LRU = __webpack_require__(60);

var kCSSColorTable = {
  'transparent': [0, 0, 0, 0],
  'aliceblue': [240, 248, 255, 1],
  'antiquewhite': [250, 235, 215, 1],
  'aqua': [0, 255, 255, 1],
  'aquamarine': [127, 255, 212, 1],
  'azure': [240, 255, 255, 1],
  'beige': [245, 245, 220, 1],
  'bisque': [255, 228, 196, 1],
  'black': [0, 0, 0, 1],
  'blanchedalmond': [255, 235, 205, 1],
  'blue': [0, 0, 255, 1],
  'blueviolet': [138, 43, 226, 1],
  'brown': [165, 42, 42, 1],
  'burlywood': [222, 184, 135, 1],
  'cadetblue': [95, 158, 160, 1],
  'chartreuse': [127, 255, 0, 1],
  'chocolate': [210, 105, 30, 1],
  'coral': [255, 127, 80, 1],
  'cornflowerblue': [100, 149, 237, 1],
  'cornsilk': [255, 248, 220, 1],
  'crimson': [220, 20, 60, 1],
  'cyan': [0, 255, 255, 1],
  'darkblue': [0, 0, 139, 1],
  'darkcyan': [0, 139, 139, 1],
  'darkgoldenrod': [184, 134, 11, 1],
  'darkgray': [169, 169, 169, 1],
  'darkgreen': [0, 100, 0, 1],
  'darkgrey': [169, 169, 169, 1],
  'darkkhaki': [189, 183, 107, 1],
  'darkmagenta': [139, 0, 139, 1],
  'darkolivegreen': [85, 107, 47, 1],
  'darkorange': [255, 140, 0, 1],
  'darkorchid': [153, 50, 204, 1],
  'darkred': [139, 0, 0, 1],
  'darksalmon': [233, 150, 122, 1],
  'darkseagreen': [143, 188, 143, 1],
  'darkslateblue': [72, 61, 139, 1],
  'darkslategray': [47, 79, 79, 1],
  'darkslategrey': [47, 79, 79, 1],
  'darkturquoise': [0, 206, 209, 1],
  'darkviolet': [148, 0, 211, 1],
  'deeppink': [255, 20, 147, 1],
  'deepskyblue': [0, 191, 255, 1],
  'dimgray': [105, 105, 105, 1],
  'dimgrey': [105, 105, 105, 1],
  'dodgerblue': [30, 144, 255, 1],
  'firebrick': [178, 34, 34, 1],
  'floralwhite': [255, 250, 240, 1],
  'forestgreen': [34, 139, 34, 1],
  'fuchsia': [255, 0, 255, 1],
  'gainsboro': [220, 220, 220, 1],
  'ghostwhite': [248, 248, 255, 1],
  'gold': [255, 215, 0, 1],
  'goldenrod': [218, 165, 32, 1],
  'gray': [128, 128, 128, 1],
  'green': [0, 128, 0, 1],
  'greenyellow': [173, 255, 47, 1],
  'grey': [128, 128, 128, 1],
  'honeydew': [240, 255, 240, 1],
  'hotpink': [255, 105, 180, 1],
  'indianred': [205, 92, 92, 1],
  'indigo': [75, 0, 130, 1],
  'ivory': [255, 255, 240, 1],
  'khaki': [240, 230, 140, 1],
  'lavender': [230, 230, 250, 1],
  'lavenderblush': [255, 240, 245, 1],
  'lawngreen': [124, 252, 0, 1],
  'lemonchiffon': [255, 250, 205, 1],
  'lightblue': [173, 216, 230, 1],
  'lightcoral': [240, 128, 128, 1],
  'lightcyan': [224, 255, 255, 1],
  'lightgoldenrodyellow': [250, 250, 210, 1],
  'lightgray': [211, 211, 211, 1],
  'lightgreen': [144, 238, 144, 1],
  'lightgrey': [211, 211, 211, 1],
  'lightpink': [255, 182, 193, 1],
  'lightsalmon': [255, 160, 122, 1],
  'lightseagreen': [32, 178, 170, 1],
  'lightskyblue': [135, 206, 250, 1],
  'lightslategray': [119, 136, 153, 1],
  'lightslategrey': [119, 136, 153, 1],
  'lightsteelblue': [176, 196, 222, 1],
  'lightyellow': [255, 255, 224, 1],
  'lime': [0, 255, 0, 1],
  'limegreen': [50, 205, 50, 1],
  'linen': [250, 240, 230, 1],
  'magenta': [255, 0, 255, 1],
  'maroon': [128, 0, 0, 1],
  'mediumaquamarine': [102, 205, 170, 1],
  'mediumblue': [0, 0, 205, 1],
  'mediumorchid': [186, 85, 211, 1],
  'mediumpurple': [147, 112, 219, 1],
  'mediumseagreen': [60, 179, 113, 1],
  'mediumslateblue': [123, 104, 238, 1],
  'mediumspringgreen': [0, 250, 154, 1],
  'mediumturquoise': [72, 209, 204, 1],
  'mediumvioletred': [199, 21, 133, 1],
  'midnightblue': [25, 25, 112, 1],
  'mintcream': [245, 255, 250, 1],
  'mistyrose': [255, 228, 225, 1],
  'moccasin': [255, 228, 181, 1],
  'navajowhite': [255, 222, 173, 1],
  'navy': [0, 0, 128, 1],
  'oldlace': [253, 245, 230, 1],
  'olive': [128, 128, 0, 1],
  'olivedrab': [107, 142, 35, 1],
  'orange': [255, 165, 0, 1],
  'orangered': [255, 69, 0, 1],
  'orchid': [218, 112, 214, 1],
  'palegoldenrod': [238, 232, 170, 1],
  'palegreen': [152, 251, 152, 1],
  'paleturquoise': [175, 238, 238, 1],
  'palevioletred': [219, 112, 147, 1],
  'papayawhip': [255, 239, 213, 1],
  'peachpuff': [255, 218, 185, 1],
  'peru': [205, 133, 63, 1],
  'pink': [255, 192, 203, 1],
  'plum': [221, 160, 221, 1],
  'powderblue': [176, 224, 230, 1],
  'purple': [128, 0, 128, 1],
  'red': [255, 0, 0, 1],
  'rosybrown': [188, 143, 143, 1],
  'royalblue': [65, 105, 225, 1],
  'saddlebrown': [139, 69, 19, 1],
  'salmon': [250, 128, 114, 1],
  'sandybrown': [244, 164, 96, 1],
  'seagreen': [46, 139, 87, 1],
  'seashell': [255, 245, 238, 1],
  'sienna': [160, 82, 45, 1],
  'silver': [192, 192, 192, 1],
  'skyblue': [135, 206, 235, 1],
  'slateblue': [106, 90, 205, 1],
  'slategray': [112, 128, 144, 1],
  'slategrey': [112, 128, 144, 1],
  'snow': [255, 250, 250, 1],
  'springgreen': [0, 255, 127, 1],
  'steelblue': [70, 130, 180, 1],
  'tan': [210, 180, 140, 1],
  'teal': [0, 128, 128, 1],
  'thistle': [216, 191, 216, 1],
  'tomato': [255, 99, 71, 1],
  'turquoise': [64, 224, 208, 1],
  'violet': [238, 130, 238, 1],
  'wheat': [245, 222, 179, 1],
  'white': [255, 255, 255, 1],
  'whitesmoke': [245, 245, 245, 1],
  'yellow': [255, 255, 0, 1],
  'yellowgreen': [154, 205, 50, 1]
};

function clampCssByte(i) {
  // Clamp to integer 0 .. 255.
  i = Math.round(i); // Seems to be what Chrome does (vs truncation).

  return i < 0 ? 0 : i > 255 ? 255 : i;
}

function clampCssAngle(i) {
  // Clamp to integer 0 .. 360.
  i = Math.round(i); // Seems to be what Chrome does (vs truncation).

  return i < 0 ? 0 : i > 360 ? 360 : i;
}

function clampCssFloat(f) {
  // Clamp to float 0.0 .. 1.0.
  return f < 0 ? 0 : f > 1 ? 1 : f;
}

function parseCssInt(str) {
  // int or percentage.
  if (str.length && str.charAt(str.length - 1) === '%') {
    return clampCssByte(parseFloat(str) / 100 * 255);
  }

  return clampCssByte(parseInt(str, 10));
}

function parseCssFloat(str) {
  // float or percentage.
  if (str.length && str.charAt(str.length - 1) === '%') {
    return clampCssFloat(parseFloat(str) / 100);
  }

  return clampCssFloat(parseFloat(str));
}

function cssHueToRgb(m1, m2, h) {
  if (h < 0) {
    h += 1;
  } else if (h > 1) {
    h -= 1;
  }

  if (h * 6 < 1) {
    return m1 + (m2 - m1) * h * 6;
  }

  if (h * 2 < 1) {
    return m2;
  }

  if (h * 3 < 2) {
    return m1 + (m2 - m1) * (2 / 3 - h) * 6;
  }

  return m1;
}

function lerpNumber(a, b, p) {
  return a + (b - a) * p;
}

function setRgba(out, r, g, b, a) {
  out[0] = r;
  out[1] = g;
  out[2] = b;
  out[3] = a;
  return out;
}

function copyRgba(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  return out;
}

var colorCache = new LRU(20);
var lastRemovedArr = null;

function putToCache(colorStr, rgbaArr) {
  // Reuse removed array
  if (lastRemovedArr) {
    copyRgba(lastRemovedArr, rgbaArr);
  }

  lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || rgbaArr.slice());
}
/**
 * @param {string} colorStr
 * @param {Array.<number>} out
 * @return {Array.<number>}
 * @memberOf module:zrender/util/color
 */


function parse(colorStr, rgbaArr) {
  if (!colorStr) {
    return;
  }

  rgbaArr = rgbaArr || [];
  var cached = colorCache.get(colorStr);

  if (cached) {
    return copyRgba(rgbaArr, cached);
  } // colorStr may be not string


  colorStr = colorStr + ''; // Remove all whitespace, not compliant, but should just be more accepting.

  var str = colorStr.replace(/ /g, '').toLowerCase(); // Color keywords (and transparent) lookup.

  if (str in kCSSColorTable) {
    copyRgba(rgbaArr, kCSSColorTable[str]);
    putToCache(colorStr, rgbaArr);
    return rgbaArr;
  } // #abc and #abc123 syntax.


  if (str.charAt(0) === '#') {
    if (str.length === 4) {
      var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.

      if (!(iv >= 0 && iv <= 0xfff)) {
        setRgba(rgbaArr, 0, 0, 0, 1);
        return; // Covers NaN.
      }

      setRgba(rgbaArr, (iv & 0xf00) >> 4 | (iv & 0xf00) >> 8, iv & 0xf0 | (iv & 0xf0) >> 4, iv & 0xf | (iv & 0xf) << 4, 1);
      putToCache(colorStr, rgbaArr);
      return rgbaArr;
    } else if (str.length === 7) {
      var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.

      if (!(iv >= 0 && iv <= 0xffffff)) {
        setRgba(rgbaArr, 0, 0, 0, 1);
        return; // Covers NaN.
      }

      setRgba(rgbaArr, (iv & 0xff0000) >> 16, (iv & 0xff00) >> 8, iv & 0xff, 1);
      putToCache(colorStr, rgbaArr);
      return rgbaArr;
    }

    return;
  }

  var op = str.indexOf('('),
      ep = str.indexOf(')');

  if (op !== -1 && ep + 1 === str.length) {
    var fname = str.substr(0, op);
    var params = str.substr(op + 1, ep - (op + 1)).split(',');
    var alpha = 1; // To allow case fallthrough.

    switch (fname) {
      case 'rgba':
        if (params.length !== 4) {
          setRgba(rgbaArr, 0, 0, 0, 1);
          return;
        }

        alpha = parseCssFloat(params.pop());
      // jshint ignore:line
      // Fall through.

      case 'rgb':
        if (params.length !== 3) {
          setRgba(rgbaArr, 0, 0, 0, 1);
          return;
        }

        setRgba(rgbaArr, parseCssInt(params[0]), parseCssInt(params[1]), parseCssInt(params[2]), alpha);
        putToCache(colorStr, rgbaArr);
        return rgbaArr;

      case 'hsla':
        if (params.length !== 4) {
          setRgba(rgbaArr, 0, 0, 0, 1);
          return;
        }

        params[3] = parseCssFloat(params[3]);
        hsla2rgba(params, rgbaArr);
        putToCache(colorStr, rgbaArr);
        return rgbaArr;

      case 'hsl':
        if (params.length !== 3) {
          setRgba(rgbaArr, 0, 0, 0, 1);
          return;
        }

        hsla2rgba(params, rgbaArr);
        putToCache(colorStr, rgbaArr);
        return rgbaArr;

      default:
        return;
    }
  }

  setRgba(rgbaArr, 0, 0, 0, 1);
  return;
}
/**
 * @param {Array.<number>} hsla
 * @param {Array.<number>} rgba
 * @return {Array.<number>} rgba
 */


function hsla2rgba(hsla, rgba) {
  var h = (parseFloat(hsla[0]) % 360 + 360) % 360 / 360; // 0 .. 1
  // NOTE(deanm): According to the CSS spec s/l should only be
  // percentages, but we don't bother and let float or percentage.

  var s = parseCssFloat(hsla[1]);
  var l = parseCssFloat(hsla[2]);
  var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
  var m1 = l * 2 - m2;
  rgba = rgba || [];
  setRgba(rgba, clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255), clampCssByte(cssHueToRgb(m1, m2, h) * 255), clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255), 1);

  if (hsla.length === 4) {
    rgba[3] = hsla[3];
  }

  return rgba;
}
/**
 * @param {Array.<number>} rgba
 * @return {Array.<number>} hsla
 */


function rgba2hsla(rgba) {
  if (!rgba) {
    return;
  } // RGB from 0 to 255


  var R = rgba[0] / 255;
  var G = rgba[1] / 255;
  var B = rgba[2] / 255;
  var vMin = Math.min(R, G, B); // Min. value of RGB

  var vMax = Math.max(R, G, B); // Max. value of RGB

  var delta = vMax - vMin; // Delta RGB value

  var L = (vMax + vMin) / 2;
  var H;
  var S; // HSL results from 0 to 1

  if (delta === 0) {
    H = 0;
    S = 0;
  } else {
    if (L < 0.5) {
      S = delta / (vMax + vMin);
    } else {
      S = delta / (2 - vMax - vMin);
    }

    var deltaR = ((vMax - R) / 6 + delta / 2) / delta;
    var deltaG = ((vMax - G) / 6 + delta / 2) / delta;
    var deltaB = ((vMax - B) / 6 + delta / 2) / delta;

    if (R === vMax) {
      H = deltaB - deltaG;
    } else if (G === vMax) {
      H = 1 / 3 + deltaR - deltaB;
    } else if (B === vMax) {
      H = 2 / 3 + deltaG - deltaR;
    }

    if (H < 0) {
      H += 1;
    }

    if (H > 1) {
      H -= 1;
    }
  }

  var hsla = [H * 360, S, L];

  if (rgba[3] != null) {
    hsla.push(rgba[3]);
  }

  return hsla;
}
/**
 * @param {string} color
 * @param {number} level
 * @return {string}
 * @memberOf module:zrender/util/color
 */


function lift(color, level) {
  var colorArr = parse(color);

  if (colorArr) {
    for (var i = 0; i < 3; i++) {
      if (level < 0) {
        colorArr[i] = colorArr[i] * (1 - level) | 0;
      } else {
        colorArr[i] = (255 - colorArr[i]) * level + colorArr[i] | 0;
      }

      if (colorArr[i] > 255) {
        colorArr[i] = 255;
      } else if (color[i] < 0) {
        colorArr[i] = 0;
      }
    }

    return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
  }
}
/**
 * @param {string} color
 * @return {string}
 * @memberOf module:zrender/util/color
 */


function toHex(color) {
  var colorArr = parse(color);

  if (colorArr) {
    return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + +colorArr[2]).toString(16).slice(1);
  }
}
/**
 * Map value to color. Faster than lerp methods because color is represented by rgba array.
 * @param {number} normalizedValue A float between 0 and 1.
 * @param {Array.<Array.<number>>} colors List of rgba color array
 * @param {Array.<number>} [out] Mapped gba color array
 * @return {Array.<number>} will be null/undefined if input illegal.
 */


function fastLerp(normalizedValue, colors, out) {
  if (!(colors && colors.length) || !(normalizedValue >= 0 && normalizedValue <= 1)) {
    return;
  }

  out = out || [];
  var value = normalizedValue * (colors.length - 1);
  var leftIndex = Math.floor(value);
  var rightIndex = Math.ceil(value);
  var leftColor = colors[leftIndex];
  var rightColor = colors[rightIndex];
  var dv = value - leftIndex;
  out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv));
  out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv));
  out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv));
  out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv));
  return out;
}
/**
 * @deprecated
 */


var fastMapToColor = fastLerp;
/**
 * @param {number} normalizedValue A float between 0 and 1.
 * @param {Array.<string>} colors Color list.
 * @param {boolean=} fullOutput Default false.
 * @return {(string|Object)} Result color. If fullOutput,
 *                           return {color: ..., leftIndex: ..., rightIndex: ..., value: ...},
 * @memberOf module:zrender/util/color
 */

function lerp(normalizedValue, colors, fullOutput) {
  if (!(colors && colors.length) || !(normalizedValue >= 0 && normalizedValue <= 1)) {
    return;
  }

  var value = normalizedValue * (colors.length - 1);
  var leftIndex = Math.floor(value);
  var rightIndex = Math.ceil(value);
  var leftColor = parse(colors[leftIndex]);
  var rightColor = parse(colors[rightIndex]);
  var dv = value - leftIndex;
  var color = stringify([clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)), clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)), clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)), clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv))], 'rgba');
  return fullOutput ? {
    color: color,
    leftIndex: leftIndex,
    rightIndex: rightIndex,
    value: value
  } : color;
}
/**
 * @deprecated
 */


var mapToColor = lerp;
/**
 * @param {string} color
 * @param {number=} h 0 ~ 360, ignore when null.
 * @param {number=} s 0 ~ 1, ignore when null.
 * @param {number=} l 0 ~ 1, ignore when null.
 * @return {string} Color string in rgba format.
 * @memberOf module:zrender/util/color
 */

function modifyHSL(color, h, s, l) {
  color = parse(color);

  if (color) {
    color = rgba2hsla(color);
    h != null && (color[0] = clampCssAngle(h));
    s != null && (color[1] = parseCssFloat(s));
    l != null && (color[2] = parseCssFloat(l));
    return stringify(hsla2rgba(color), 'rgba');
  }
}
/**
 * @param {string} color
 * @param {number=} alpha 0 ~ 1
 * @return {string} Color string in rgba format.
 * @memberOf module:zrender/util/color
 */


function modifyAlpha(color, alpha) {
  color = parse(color);

  if (color && alpha != null) {
    color[3] = clampCssFloat(alpha);
    return stringify(color, 'rgba');
  }
}
/**
 * @param {Array.<number>} arrColor like [12,33,44,0.4]
 * @param {string} type 'rgba', 'hsva', ...
 * @return {string} Result color. (If input illegal, return undefined).
 */


function stringify(arrColor, type) {
  if (!arrColor || !arrColor.length) {
    return;
  }

  var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];

  if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
    colorStr += ',' + arrColor[3];
  }

  return type + '(' + colorStr + ')';
}

exports.parse = parse;
exports.lift = lift;
exports.toHex = toHex;
exports.fastLerp = fastLerp;
exports.fastMapToColor = fastMapToColor;
exports.lerp = lerp;
exports.mapToColor = mapToColor;
exports.modifyHSL = modifyHSL;
exports.modifyAlpha = modifyAlpha;
exports.stringify = stringify;

/***/ }),
/* 146 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("\n@export clay.util.rand\nhighp float rand(vec2 uv) {\n const highp float a = 12.9898, b = 78.233, c = 43758.5453;\n highp float dt = dot(uv.xy, vec2(a,b)), sn = mod(dt, 3.141592653589793);\n return fract(sin(sn) * c);\n}\n@end\n@export clay.util.calculate_attenuation\nuniform float attenuationFactor : 5.0;\nfloat lightAttenuation(float dist, float range)\n{\n float attenuation = 1.0;\n attenuation = dist*dist/(range*range+1.0);\n float att_s = attenuationFactor;\n attenuation = 1.0/(attenuation*att_s+1.0);\n att_s = 1.0/(att_s+1.0);\n attenuation = attenuation - att_s;\n attenuation /= 1.0 - att_s;\n return clamp(attenuation, 0.0, 1.0);\n}\n@end\n@export clay.util.edge_factor\n#ifdef SUPPORT_STANDARD_DERIVATIVES\nfloat edgeFactor(float width)\n{\n vec3 d = fwidth(v_Barycentric);\n vec3 a3 = smoothstep(vec3(0.0), d * width, v_Barycentric);\n return min(min(a3.x, a3.y), a3.z);\n}\n#else\nfloat edgeFactor(float width)\n{\n return 1.0;\n}\n#endif\n@end\n@export clay.util.encode_float\nvec4 encodeFloat(const in float depth)\n{\n const vec4 bitShifts = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);\n vec4 res = fract(depth * bitShifts);\n res -= res.xxyz * bit_mask;\n return res;\n}\n@end\n@export clay.util.decode_float\nfloat decodeFloat(const in vec4 color)\n{\n const vec4 bitShifts = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);\n return dot(color, bitShifts);\n}\n@end\n@export clay.util.float\n@import clay.util.encode_float\n@import clay.util.decode_float\n@end\n@export clay.util.rgbm_decode\nvec3 RGBMDecode(vec4 rgbm, float range) {\n return range * rgbm.rgb * rgbm.a;\n}\n@end\n@export clay.util.rgbm_encode\nvec4 RGBMEncode(vec3 color, float range) {\n if (dot(color, color) == 0.0) {\n return vec4(0.0);\n }\n vec4 rgbm;\n color /= range;\n rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 1e-6)), 0.0, 1.0);\n rgbm.a = ceil(rgbm.a * 255.0) / 255.0;\n rgbm.rgb = color / rgbm.a;\n return rgbm;\n}\n@end\n@export clay.util.rgbm\n@import clay.util.rgbm_decode\n@import clay.util.rgbm_encode\nvec4 decodeHDR(vec4 color)\n{\n#if defined(RGBM_DECODE) || defined(RGBM)\n return vec4(RGBMDecode(color, 8.12), 1.0);\n#else\n return color;\n#endif\n}\nvec4 encodeHDR(vec4 color)\n{\n#if defined(RGBM_ENCODE) || defined(RGBM)\n return RGBMEncode(color.xyz, 8.12);\n#else\n return color;\n#endif\n}\n@end\n@export clay.util.srgb\nvec4 sRGBToLinear(in vec4 value) {\n return vec4(mix(pow(value.rgb * 0.9478672986 + vec3(0.0521327014), vec3(2.4)), value.rgb * 0.0773993808, vec3(lessThanEqual(value.rgb, vec3(0.04045)))), value.w);\n}\nvec4 linearTosRGB(in vec4 value) {\n return vec4(mix(pow(value.rgb, vec3(0.41666)) * 1.055 - vec3(0.055), value.rgb * 12.92, vec3(lessThanEqual(value.rgb, vec3(0.0031308)))), value.w);\n}\n@end\n@export clay.chunk.skinning_header\n#ifdef SKINNING\nattribute vec3 weight : WEIGHT;\nattribute vec4 joint : JOINT;\n#ifdef USE_SKIN_MATRICES_TEXTURE\nuniform sampler2D skinMatricesTexture : ignore;\nuniform float skinMatricesTextureSize: ignore;\nmat4 getSkinMatrix(sampler2D tex, float idx) {\n float j = idx * 4.0;\n float x = mod(j, skinMatricesTextureSize);\n float y = floor(j / skinMatricesTextureSize) + 0.5;\n vec2 scale = vec2(skinMatricesTextureSize);\n return mat4(\n texture2D(tex, vec2(x + 0.5, y) / scale),\n texture2D(tex, vec2(x + 1.5, y) / scale),\n texture2D(tex, vec2(x + 2.5, y) / scale),\n texture2D(tex, vec2(x + 3.5, y) / scale)\n );\n}\nmat4 getSkinMatrix(float idx) {\n return getSkinMatrix(skinMatricesTexture, idx);\n}\n#else\nuniform mat4 skinMatrix[JOINT_COUNT] : SKIN_MATRIX;\nmat4 getSkinMatrix(float idx) {\n return skinMatrix[int(idx)];\n}\n#endif\n#endif\n@end\n@export clay.chunk.skin_matrix\nmat4 skinMatrixWS = getSkinMatrix(joint.x) * weight.x;\nif (weight.y > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.y) * weight.y;\n}\nif (weight.z > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.z) * weight.z;\n}\nfloat weightW = 1.0-weight.x-weight.y-weight.z;\nif (weightW > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.w) * weightW;\n}\n@end\n@export clay.util.parallax_correct\nvec3 parallaxCorrect(in vec3 dir, in vec3 pos, in vec3 boxMin, in vec3 boxMax) {\n vec3 first = (boxMax - pos) / dir;\n vec3 second = (boxMin - pos) / dir;\n vec3 further = max(first, second);\n float dist = min(further.x, min(further.y, further.z));\n vec3 fixedPos = pos + dir * dist;\n vec3 boxCenter = (boxMax + boxMin) * 0.5;\n return normalize(fixedPos - boxCenter);\n}\n@end\n@export clay.util.clamp_sample\nvec4 clampSample(const in sampler2D texture, const in vec2 coord)\n{\n#ifdef STEREO\n float eye = step(0.5, coord.x) * 0.5;\n vec2 coordClamped = clamp(coord, vec2(eye, 0.0), vec2(0.5 + eye, 1.0));\n#else\n vec2 coordClamped = clamp(coord, vec2(0.0), vec2(1.0));\n#endif\n return texture2D(texture, coordClamped);\n}\n@end\n@export clay.util.ACES\nvec3 ACESToneMapping(vec3 color)\n{\n const float A = 2.51;\n const float B = 0.03;\n const float C = 2.43;\n const float D = 0.59;\n const float E = 0.14;\n return (color * (A * color + B)) / (color * (C * color + D) + E);\n}\n@end");


/***/ }),
/* 147 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("\n@export ecgl.common.transformUniforms\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\n@end\n\n@export ecgl.common.attributes\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 normal : NORMAL;\n@end\n\n@export ecgl.common.uv.header\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nuniform vec2 detailUvRepeat : [1.0, 1.0];\nuniform vec2 detailUvOffset : [0.0, 0.0];\n\nvarying vec2 v_Texcoord;\nvarying vec2 v_DetailTexcoord;\n@end\n\n@export ecgl.common.uv.main\nv_Texcoord = texcoord * uvRepeat + uvOffset;\nv_DetailTexcoord = texcoord * detailUvRepeat + detailUvOffset;\n@end\n\n@export ecgl.common.uv.fragmentHeader\nvarying vec2 v_Texcoord;\nvarying vec2 v_DetailTexcoord;\n@end\n\n\n@export ecgl.common.albedo.main\n\n vec4 albedoTexel = vec4(1.0);\n#ifdef DIFFUSEMAP_ENABLED\n albedoTexel = texture2D(diffuseMap, v_Texcoord);\n #ifdef SRGB_DECODE\n albedoTexel = sRGBToLinear(albedoTexel);\n #endif\n#endif\n\n#ifdef DETAILMAP_ENABLED\n vec4 detailTexel = texture2D(detailMap, v_DetailTexcoord);\n #ifdef SRGB_DECODE\n detailTexel = sRGBToLinear(detailTexel);\n #endif\n albedoTexel.rgb = mix(albedoTexel.rgb, detailTexel.rgb, detailTexel.a);\n albedoTexel.a = detailTexel.a + (1.0 - detailTexel.a) * albedoTexel.a;\n#endif\n\n@end\n\n@export ecgl.common.wireframe.vertexHeader\n\n#ifdef WIREFRAME_QUAD\nattribute vec4 barycentric;\nvarying vec4 v_Barycentric;\n#elif defined(WIREFRAME_TRIANGLE)\nattribute vec3 barycentric;\nvarying vec3 v_Barycentric;\n#endif\n\n@end\n\n@export ecgl.common.wireframe.vertexMain\n\n#if defined(WIREFRAME_QUAD) || defined(WIREFRAME_TRIANGLE)\n v_Barycentric = barycentric;\n#endif\n\n@end\n\n\n@export ecgl.common.wireframe.fragmentHeader\n\nuniform float wireframeLineWidth : 1;\nuniform vec4 wireframeLineColor: [0, 0, 0, 0.5];\n\n#ifdef WIREFRAME_QUAD\nvarying vec4 v_Barycentric;\nfloat edgeFactor () {\n vec4 d = fwidth(v_Barycentric);\n vec4 a4 = smoothstep(vec4(0.0), d * wireframeLineWidth, v_Barycentric);\n return min(min(min(a4.x, a4.y), a4.z), a4.w);\n}\n#elif defined(WIREFRAME_TRIANGLE)\nvarying vec3 v_Barycentric;\nfloat edgeFactor () {\n vec3 d = fwidth(v_Barycentric);\n vec3 a3 = smoothstep(vec3(0.0), d * wireframeLineWidth, v_Barycentric);\n return min(min(a3.x, a3.y), a3.z);\n}\n#endif\n\n@end\n\n\n@export ecgl.common.wireframe.fragmentMain\n\n#if defined(WIREFRAME_QUAD) || defined(WIREFRAME_TRIANGLE)\n if (wireframeLineWidth > 0.) {\n vec4 lineColor = wireframeLineColor;\n#ifdef SRGB_DECODE\n lineColor = sRGBToLinear(lineColor);\n#endif\n\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor()) * lineColor.a);\n }\n#endif\n@end\n\n\n\n\n@export ecgl.common.bumpMap.header\n\n#ifdef BUMPMAP_ENABLED\nuniform sampler2D bumpMap;\nuniform float bumpScale : 1.0;\n\n\nvec3 bumpNormal(vec3 surfPos, vec3 surfNormal, vec3 baseNormal)\n{\n vec2 dSTdx = dFdx(v_Texcoord);\n vec2 dSTdy = dFdy(v_Texcoord);\n\n float Hll = bumpScale * texture2D(bumpMap, v_Texcoord).x;\n float dHx = bumpScale * texture2D(bumpMap, v_Texcoord + dSTdx).x - Hll;\n float dHy = bumpScale * texture2D(bumpMap, v_Texcoord + dSTdy).x - Hll;\n\n vec3 vSigmaX = dFdx(surfPos);\n vec3 vSigmaY = dFdy(surfPos);\n vec3 vN = surfNormal;\n\n vec3 R1 = cross(vSigmaY, vN);\n vec3 R2 = cross(vN, vSigmaX);\n\n float fDet = dot(vSigmaX, R1);\n\n vec3 vGrad = sign(fDet) * (dHx * R1 + dHy * R2);\n return normalize(abs(fDet) * baseNormal - vGrad);\n\n}\n#endif\n\n@end\n\n@export ecgl.common.normalMap.vertexHeader\n\n#ifdef NORMALMAP_ENABLED\nattribute vec4 tangent : TANGENT;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\n#endif\n\n@end\n\n@export ecgl.common.normalMap.vertexMain\n\n#ifdef NORMALMAP_ENABLED\n if (dot(tangent, tangent) > 0.0) {\n v_Tangent = normalize((worldInverseTranspose * vec4(tangent.xyz, 0.0)).xyz);\n v_Bitangent = normalize(cross(v_Normal, v_Tangent) * tangent.w);\n }\n#endif\n\n@end\n\n\n@export ecgl.common.normalMap.fragmentHeader\n\n#ifdef NORMALMAP_ENABLED\nuniform sampler2D normalMap;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\n#endif\n\n@end\n\n@export ecgl.common.normalMap.fragmentMain\n#ifdef NORMALMAP_ENABLED\n if (dot(v_Tangent, v_Tangent) > 0.0) {\n vec3 normalTexel = texture2D(normalMap, v_DetailTexcoord).xyz;\n if (dot(normalTexel, normalTexel) > 0.0) { N = normalTexel * 2.0 - 1.0;\n mat3 tbn = mat3(v_Tangent, v_Bitangent, v_Normal);\n N = normalize(tbn * N);\n }\n }\n#endif\n@end\n\n\n\n@export ecgl.common.vertexAnimation.header\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nattribute vec3 prevNormal;\nuniform float percent;\n#endif\n\n@end\n\n@export ecgl.common.vertexAnimation.main\n\n#ifdef VERTEX_ANIMATION\n vec3 pos = mix(prevPosition, position, percent);\n vec3 norm = mix(prevNormal, normal, percent);\n#else\n vec3 pos = position;\n vec3 norm = normal;\n#endif\n\n@end\n\n\n@export ecgl.common.ssaoMap.header\n#ifdef SSAOMAP_ENABLED\nuniform sampler2D ssaoMap;\nuniform vec4 viewport : VIEWPORT;\n#endif\n@end\n\n@export ecgl.common.ssaoMap.main\n float ao = 1.0;\n#ifdef SSAOMAP_ENABLED\n ao = texture2D(ssaoMap, (gl_FragCoord.xy - viewport.xy) / viewport.zw).r;\n#endif\n@end\n\n\n\n\n@export ecgl.common.diffuseLayer.header\n\n#if (LAYER_DIFFUSEMAP_COUNT > 0)\nuniform float layerDiffuseIntensity[LAYER_DIFFUSEMAP_COUNT];\nuniform sampler2D layerDiffuseMap[LAYER_DIFFUSEMAP_COUNT];\n#endif\n\n@end\n\n@export ecgl.common.emissiveLayer.header\n\n#if (LAYER_EMISSIVEMAP_COUNT > 0)\nuniform float layerEmissionIntensity[LAYER_EMISSIVEMAP_COUNT];\nuniform sampler2D layerEmissiveMap[LAYER_EMISSIVEMAP_COUNT];\n#endif\n\n@end\n\n@export ecgl.common.layers.header\n@import ecgl.common.diffuseLayer.header\n@import ecgl.common.emissiveLayer.header\n@end\n\n@export ecgl.common.diffuseLayer.main\n\n#if (LAYER_DIFFUSEMAP_COUNT > 0)\n for (int _idx_ = 0; _idx_ < LAYER_DIFFUSEMAP_COUNT; _idx_++) {{\n float intensity = layerDiffuseIntensity[_idx_];\n vec4 texel2 = texture2D(layerDiffuseMap[_idx_], v_Texcoord);\n #ifdef SRGB_DECODE\n texel2 = sRGBToLinear(texel2);\n #endif\n albedoTexel.rgb = mix(albedoTexel.rgb, texel2.rgb * intensity, texel2.a);\n albedoTexel.a = texel2.a + (1.0 - texel2.a) * albedoTexel.a;\n }}\n#endif\n\n@end\n\n@export ecgl.common.emissiveLayer.main\n\n#if (LAYER_EMISSIVEMAP_COUNT > 0)\n for (int _idx_ = 0; _idx_ < LAYER_EMISSIVEMAP_COUNT; _idx_++)\n {{\n vec4 texel2 = texture2D(layerEmissiveMap[_idx_], v_Texcoord) * layerEmissionIntensity[_idx_];\n #ifdef SRGB_DECODE\n texel2 = sRGBToLinear(texel2);\n #endif\n float intensity = layerEmissionIntensity[_idx_];\n gl_FragColor.rgb += texel2.rgb * texel2.a * intensity;\n }}\n#endif\n\n@end\n");


/***/ }),
/* 148 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.color.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\n@import ecgl.common.uv.header\n\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 position: POSITION;\n\n@import ecgl.common.wireframe.vertexHeader\n\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nuniform float percent : 1.0;\n#endif\n\nvoid main()\n{\n#ifdef VERTEX_ANIMATION\n vec3 pos = mix(prevPosition, position, percent);\n#else\n vec3 pos = position;\n#endif\n\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n\n @import ecgl.common.uv.main\n\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n\n @import ecgl.common.wireframe.vertexMain\n\n}\n\n@end\n\n@export ecgl.color.fragment\n\n#define LAYER_DIFFUSEMAP_COUNT 0\n#define LAYER_EMISSIVEMAP_COUNT 0\n\nuniform sampler2D diffuseMap;\nuniform sampler2D detailMap;\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\n@import ecgl.common.layers.header\n\n@import ecgl.common.uv.fragmentHeader\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.util.srgb\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color);\n#else\n gl_FragColor = color;\n#endif\n\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n\n @import ecgl.common.albedo.main\n\n @import ecgl.common.diffuseLayer.main\n\n gl_FragColor *= albedoTexel;\n\n @import ecgl.common.emissiveLayer.main\n\n @import ecgl.common.wireframe.fragmentMain\n\n}\n@end");


/***/ }),
/* 149 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("/**\n * http: */\n\n@export ecgl.lambert.vertex\n\n@import ecgl.common.transformUniforms\n\n@import ecgl.common.uv.header\n\n\n@import ecgl.common.attributes\n\n@import ecgl.common.wireframe.vertexHeader\n\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n\n\n@import ecgl.common.vertexAnimation.header\n\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nvoid main()\n{\n @import ecgl.common.uv.main\n\n @import ecgl.common.vertexAnimation.main\n\n\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n\n v_Normal = normalize((worldInverseTranspose * vec4(norm, 0.0)).xyz);\n v_WorldPosition = (world * vec4(pos, 1.0)).xyz;\n\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n\n @import ecgl.common.wireframe.vertexMain\n}\n\n@end\n\n\n@export ecgl.lambert.fragment\n\n#define LAYER_DIFFUSEMAP_COUNT 0\n#define LAYER_EMISSIVEMAP_COUNT 0\n\n#define NORMAL_UP_AXIS 1\n#define NORMAL_FRONT_AXIS 2\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform sampler2D diffuseMap;\nuniform sampler2D detailMap;\n\n@import ecgl.common.layers.header\n\nuniform float emissionIntensity: 1.0;\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nuniform mat4 viewInverse : VIEWINVERSE;\n\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\n\n@import ecgl.common.ssaoMap.header\n\n@import ecgl.common.bumpMap.header\n\n@import clay.util.srgb\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.plugin.compute_shadow_map\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color);\n#else\n gl_FragColor = color;\n#endif\n\n#ifdef VERTEX_COLOR\n #ifdef SRGB_DECODE\n gl_FragColor *= sRGBToLinear(v_Color);\n #else\n gl_FragColor *= v_Color;\n #endif\n#endif\n\n @import ecgl.common.albedo.main\n\n @import ecgl.common.diffuseLayer.main\n\n gl_FragColor *= albedoTexel;\n\n vec3 N = v_Normal;\n#ifdef DOUBLE_SIDED\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n#endif\n\n float ambientFactor = 1.0;\n\n#ifdef BUMPMAP_ENABLED\n N = bumpNormal(v_WorldPosition, v_Normal, N);\n ambientFactor = dot(v_Normal, N);\n#endif\n\n vec3 N2 = vec3(N.x, N[NORMAL_UP_AXIS], N[NORMAL_FRONT_AXIS]);\n\n vec3 diffuseColor = vec3(0.0, 0.0, 0.0);\n\n @import ecgl.common.ssaoMap.main\n\n#ifdef AMBIENT_LIGHT_COUNT\n for(int i = 0; i < AMBIENT_LIGHT_COUNT; i++)\n {\n diffuseColor += ambientLightColor[i] * ambientFactor * ao;\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseColor += calcAmbientSHLight(_idx_, N2) * ambientSHLightColor[_idx_] * ao;\n }}\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n vec3 lightColor = directionalLightColor[i];\n\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if (shadowEnabled)\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n\n float ndl = dot(N, normalize(lightDirection)) * shadowContrib;\n\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0);\n }\n#endif\n\n gl_FragColor.rgb *= diffuseColor;\n\n @import ecgl.common.emissiveLayer.main\n\n @import ecgl.common.wireframe.fragmentMain\n}\n\n@end");


/***/ }),
/* 150 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.realistic.vertex\n\n@import ecgl.common.transformUniforms\n\n@import ecgl.common.uv.header\n\n@import ecgl.common.attributes\n\n\n@import ecgl.common.wireframe.vertexHeader\n\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n\n#ifdef NORMALMAP_ENABLED\nattribute vec4 tangent : TANGENT;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\n#endif\n\n@import ecgl.common.vertexAnimation.header\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nvoid main()\n{\n\n @import ecgl.common.uv.main\n\n @import ecgl.common.vertexAnimation.main\n\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n\n v_Normal = normalize((worldInverseTranspose * vec4(norm, 0.0)).xyz);\n v_WorldPosition = (world * vec4(pos, 1.0)).xyz;\n\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n\n#ifdef NORMALMAP_ENABLED\n v_Tangent = normalize((worldInverseTranspose * vec4(tangent.xyz, 0.0)).xyz);\n v_Bitangent = normalize(cross(v_Normal, v_Tangent) * tangent.w);\n#endif\n\n @import ecgl.common.wireframe.vertexMain\n\n}\n\n@end\n\n\n\n@export ecgl.realistic.fragment\n\n#define LAYER_DIFFUSEMAP_COUNT 0\n#define LAYER_EMISSIVEMAP_COUNT 0\n#define PI 3.14159265358979\n#define ROUGHNESS_CHANEL 0\n#define METALNESS_CHANEL 1\n\n#define NORMAL_UP_AXIS 1\n#define NORMAL_FRONT_AXIS 2\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform sampler2D diffuseMap;\n\nuniform sampler2D detailMap;\nuniform sampler2D metalnessMap;\nuniform sampler2D roughnessMap;\n\n@import ecgl.common.layers.header\n\nuniform float emissionIntensity: 1.0;\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nuniform float metalness : 0.0;\nuniform float roughness : 0.5;\n\nuniform mat4 viewInverse : VIEWINVERSE;\n\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n\n#ifdef AMBIENT_CUBEMAP_LIGHT_COUNT\n@import clay.header.ambient_cubemap_light\n#endif\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n\n@import ecgl.common.normalMap.fragmentHeader\n\n@import ecgl.common.ssaoMap.header\n\n@import ecgl.common.bumpMap.header\n\n@import clay.util.srgb\n\n@import clay.util.rgbm\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.plugin.compute_shadow_map\n\nvec3 F_Schlick(float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\n\nfloat D_Phong(float g, float ndh) {\n float a = pow(8192.0, g);\n return (a + 2.0) / 8.0 * pow(ndh, a);\n}\n\nvoid main()\n{\n vec4 albedoColor = color;\n\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n#ifdef VERTEX_COLOR\n #ifdef SRGB_DECODE\n albedoColor *= sRGBToLinear(v_Color);\n #else\n albedoColor *= v_Color;\n #endif\n#endif\n\n @import ecgl.common.albedo.main\n\n @import ecgl.common.diffuseLayer.main\n\n albedoColor *= albedoTexel;\n\n float m = metalness;\n\n#ifdef METALNESSMAP_ENABLED\n float m2 = texture2D(metalnessMap, v_DetailTexcoord)[METALNESS_CHANEL];\n m = clamp(m2 + (m - 0.5) * 2.0, 0.0, 1.0);\n#endif\n\n vec3 baseColor = albedoColor.rgb;\n albedoColor.rgb = baseColor * (1.0 - m);\n vec3 specFactor = mix(vec3(0.04), baseColor, m);\n\n float g = 1.0 - roughness;\n\n#ifdef ROUGHNESSMAP_ENABLED\n float g2 = 1.0 - texture2D(roughnessMap, v_DetailTexcoord)[ROUGHNESS_CHANEL];\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n#endif\n\n vec3 N = v_Normal;\n\n#ifdef DOUBLE_SIDED\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n#endif\n\n float ambientFactor = 1.0;\n\n#ifdef BUMPMAP_ENABLED\n N = bumpNormal(v_WorldPosition, v_Normal, N);\n ambientFactor = dot(v_Normal, N);\n#endif\n\n@import ecgl.common.normalMap.fragmentMain\n\n vec3 N2 = vec3(N.x, N[NORMAL_UP_AXIS], N[NORMAL_FRONT_AXIS]);\n\n vec3 diffuseTerm = vec3(0.0);\n vec3 specularTerm = vec3(0.0);\n\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n vec3 fresnelTerm = F_Schlick(ndv, specFactor);\n\n @import ecgl.common.ssaoMap.main\n\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {{\n diffuseTerm += ambientLightColor[_idx_] * ambientFactor * ao;\n }}\n#endif\n\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseTerm += calcAmbientSHLight(_idx_, N2) * ambientSHLightColor[_idx_] * ao;\n }}\n#endif\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int _idx_ = 0; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++)\n {{\n vec3 L = -directionalLightDirection[_idx_];\n vec3 lc = directionalLightColor[_idx_];\n\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, normalize(L)), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if (shadowEnabled)\n {\n shadowContrib = shadowContribsDir[_idx_];\n }\n#endif\n\n vec3 li = lc * ndl * shadowContrib;\n\n diffuseTerm += li;\n specularTerm += li * fresnelTerm * D_Phong(g, ndh);\n }}\n#endif\n\n\n#ifdef AMBIENT_CUBEMAP_LIGHT_COUNT\n vec3 L = reflect(-V, N);\n L = vec3(L.x, L[NORMAL_UP_AXIS], L[NORMAL_FRONT_AXIS]);\n float rough2 = clamp(1.0 - g, 0.0, 1.0);\n float bias2 = rough2 * 5.0;\n vec2 brdfParam2 = texture2D(ambientCubemapLightBRDFLookup[0], vec2(rough2, ndv)).xy;\n vec3 envWeight2 = specFactor * brdfParam2.x + brdfParam2.y;\n vec3 envTexel2;\n for(int _idx_ = 0; _idx_ < AMBIENT_CUBEMAP_LIGHT_COUNT; _idx_++)\n {{\n envTexel2 = RGBMDecode(textureCubeLodEXT(ambientCubemapLightCubemap[_idx_], L, bias2), 8.12);\n specularTerm += ambientCubemapLightColor[_idx_] * envTexel2 * envWeight2 * ao;\n }}\n#endif\n\n gl_FragColor.rgb = albedoColor.rgb * diffuseTerm + specularTerm;\n gl_FragColor.a = albedoColor.a;\n\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n\n @import ecgl.common.emissiveLayer.main\n\n @import ecgl.common.wireframe.fragmentMain\n}\n\n@end");


/***/ }),
/* 151 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.hatching.vertex\n\n@import ecgl.realistic.vertex\n\n@end\n\n\n@export ecgl.hatching.fragment\n\n#define NORMAL_UP_AXIS 1\n#define NORMAL_FRONT_AXIS 2\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform vec4 color : [0.0, 0.0, 0.0, 1.0];\nuniform vec4 paperColor : [1.0, 1.0, 1.0, 1.0];\n\nuniform mat4 viewInverse : VIEWINVERSE;\n\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\n\n@import ecgl.common.ssaoMap.header\n\n@import ecgl.common.bumpMap.header\n\n@import clay.util.srgb\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.plugin.compute_shadow_map\n\nuniform sampler2D hatch1;\nuniform sampler2D hatch2;\nuniform sampler2D hatch3;\nuniform sampler2D hatch4;\nuniform sampler2D hatch5;\nuniform sampler2D hatch6;\n\nfloat shade(in float tone) {\n vec4 c = vec4(1. ,1., 1., 1.);\n float step = 1. / 6.;\n vec2 uv = v_DetailTexcoord;\n if (tone <= step / 2.0) {\n c = mix(vec4(0.), texture2D(hatch6, uv), 12. * tone);\n }\n else if (tone <= step) {\n c = mix(texture2D(hatch6, uv), texture2D(hatch5, uv), 6. * tone);\n }\n if(tone > step && tone <= 2. * step){\n c = mix(texture2D(hatch5, uv), texture2D(hatch4, uv) , 6. * (tone - step));\n }\n if(tone > 2. * step && tone <= 3. * step){\n c = mix(texture2D(hatch4, uv), texture2D(hatch3, uv), 6. * (tone - 2. * step));\n }\n if(tone > 3. * step && tone <= 4. * step){\n c = mix(texture2D(hatch3, uv), texture2D(hatch2, uv), 6. * (tone - 3. * step));\n }\n if(tone > 4. * step && tone <= 5. * step){\n c = mix(texture2D(hatch2, uv), texture2D(hatch1, uv), 6. * (tone - 4. * step));\n }\n if(tone > 5. * step){\n c = mix(texture2D(hatch1, uv), vec4(1.), 6. * (tone - 5. * step));\n }\n\n return c.r;\n}\n\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n vec4 inkColor = sRGBToLinear(color);\n#else\n vec4 inkColor = color;\n#endif\n\n#ifdef VERTEX_COLOR\n #ifdef SRGB_DECODE\n inkColor *= sRGBToLinear(v_Color);\n #else\n inkColor *= v_Color;\n #endif\n#endif\n\n vec3 N = v_Normal;\n#ifdef DOUBLE_SIDED\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n#endif\n\n float tone = 0.0;\n\n float ambientFactor = 1.0;\n\n#ifdef BUMPMAP_ENABLED\n N = bumpNormal(v_WorldPosition, v_Normal, N);\n ambientFactor = dot(v_Normal, N);\n#endif\n\n vec3 N2 = vec3(N.x, N[NORMAL_UP_AXIS], N[NORMAL_FRONT_AXIS]);\n\n @import ecgl.common.ssaoMap.main\n\n#ifdef AMBIENT_LIGHT_COUNT\n for(int i = 0; i < AMBIENT_LIGHT_COUNT; i++)\n {\n tone += dot(ambientLightColor[i], w) * ambientFactor * ao;\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n tone += dot(calcAmbientSHLight(_idx_, N2) * ambientSHLightColor[_idx_], w) * ao;\n }}\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n float lightTone = dot(directionalLightColor[i], w);\n\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if (shadowEnabled)\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n\n float ndl = dot(N, normalize(lightDirection)) * shadowContrib;\n\n tone += lightTone * clamp(ndl, 0.0, 1.0);\n }\n#endif\n\n gl_FragColor = mix(inkColor, paperColor, shade(clamp(tone, 0.0, 1.0)));\n }\n@end\n");


/***/ }),
/* 152 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.sm.depth.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nuniform float percent : 1.0;\n#endif\n\nvarying vec4 v_ViewPosition;\nvarying vec2 v_Texcoord;\n\nvoid main(){\n\n#ifdef VERTEX_ANIMATION\n vec3 pos = mix(prevPosition, position, percent);\n#else\n vec3 pos = position;\n#endif\n\n v_ViewPosition = worldViewProjection * vec4(pos, 1.0);\n gl_Position = v_ViewPosition;\n\n v_Texcoord = texcoord;\n\n}\n@end\n\n\n\n@export ecgl.sm.depth.fragment\n\n@import clay.sm.depth.fragment\n\n@end");


/***/ }),
/* 153 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


var GL_SERIES = ['bar3D', 'line3D', 'map3D', 'scatter3D', 'surface', 'lines3D', 'scatterGL', 'scatter3D'];

function convertNormalEmphasis(option, optType) {
    if (option && option[optType] && (option[optType].normal || option[optType].emphasis)) {
        var normalOpt = option[optType].normal;
        var emphasisOpt = option[optType].emphasis;

        if (normalOpt) {
            option[optType] = normalOpt;
        }
        if (emphasisOpt) {
            option.emphasis = option.emphasis || {};
            option.emphasis[optType] = emphasisOpt;
        }
    }
}

function convertNormalEmphasisForEach(option) {
    convertNormalEmphasis(option, 'itemStyle');
    convertNormalEmphasis(option, 'lineStyle');
    convertNormalEmphasis(option, 'areaStyle');
    convertNormalEmphasis(option, 'label');
}

function removeTextStyleInAxis(axesOpt) {
    if (!axesOpt) {
        return;
    }
    if (!(axesOpt instanceof Array)) {
        axesOpt = [axesOpt];
    }
    __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(axesOpt, function (axisOpt) {
        if (axisOpt.axisLabel) {
            var labelOpt = axisOpt.axisLabel;
            __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.extend(labelOpt, labelOpt.textStyle);
            labelOpt.textStyle = null;
        }
    });
}

/* harmony default export */ __webpack_exports__["a"] = (function (option) {
    __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(option.series, function (series) {
        if (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.indexOf(GL_SERIES, series.type) >= 0) {
            convertNormalEmphasisForEach(series);

            // Compatitable with original mapbox
            if (series.coordinateSystem === 'mapbox') {
                series.coordinateSystem = 'mapbox3D';
                option.mapbox3D = option.mapbox;
            }
        }
    });

    removeTextStyleInAxis(option.xAxis3D);
    removeTextStyleInAxis(option.yAxis3D);
    removeTextStyleInAxis(option.zAxis3D);
    removeTextStyleInAxis(option.grid3D);

    convertNormalEmphasis(option.geo3D);
});;

/***/ }),
/* 154 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__grid3D_Axis3DModel__ = __webpack_require__(155);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__grid3D_Grid3DModel__ = __webpack_require__(159);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__grid3D_Grid3DView__ = __webpack_require__(160);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__coord_grid3DCreator__ = __webpack_require__(167);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_echarts_lib_echarts__);







__WEBPACK_IMPORTED_MODULE_4_echarts_lib_echarts___default.a.registerAction({
    type: 'grid3DChangeCamera',
    event: 'grid3dcamerachanged',
    update: 'series:updateCamera'
}, function (payload, ecModel) {
    ecModel.eachComponent({
        mainType: 'grid3D', query: payload
    }, function (componentModel) {
        componentModel.setView(payload);
    });
});

__WEBPACK_IMPORTED_MODULE_4_echarts_lib_echarts___default.a.registerAction({
    type: 'grid3DShowAxisPointer',
    event: 'grid3dshowaxispointer',
    update: 'grid3D:showAxisPointer'
}, function (payload, ecModel) {
});

__WEBPACK_IMPORTED_MODULE_4_echarts_lib_echarts___default.a.registerAction({
    type: 'grid3DHideAxisPointer',
    event: 'grid3dhideaxispointer',
    update: 'grid3D:hideAxisPointer'
}, function (payload, ecModel) {
});

/***/ }),
/* 155 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__createAxis3DModel__ = __webpack_require__(156);



var Axis3DModel = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentModel({

    type: 'cartesian3DAxis',

    axis: null,

    /**
     * @override
     */
    getCoordSysModel: function () {
        return this.ecModel.queryComponents({
            mainType: 'grid3D',
            index: this.option.gridIndex,
            id: this.option.gridId
        })[0];
    }
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.mixinAxisModelCommonMethods(Axis3DModel);

function getAxisType(axisDim, option) {
    // Default axis with data is category axis
    return option.type || (option.data ? 'category' : 'value');
}

Object(__WEBPACK_IMPORTED_MODULE_1__createAxis3DModel__["a" /* default */])('x', Axis3DModel, getAxisType, {
    name: 'X'
});
Object(__WEBPACK_IMPORTED_MODULE_1__createAxis3DModel__["a" /* default */])('y', Axis3DModel, getAxisType, {
    name: 'Y'
});
Object(__WEBPACK_IMPORTED_MODULE_1__createAxis3DModel__["a" /* default */])('z', Axis3DModel, getAxisType, {
    name: 'Z'
});

/***/ }),
/* 156 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__axis3DDefault__ = __webpack_require__(157);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_OrdinalMeta__ = __webpack_require__(158);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_OrdinalMeta___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_OrdinalMeta__);





var AXIS_TYPES = ['value', 'category', 'time', 'log'];
/**
 * Generate sub axis model class
 * @param {string} dim 'x' 'y' 'radius' 'angle' 'parallel'
 * @param {module:echarts/model/Component} BaseAxisModelClass
 * @param {Function} axisTypeDefaulter
 * @param {Object} [extraDefaultOption]
 */
/* harmony default export */ __webpack_exports__["a"] = (function (dim, BaseAxisModelClass, axisTypeDefaulter, extraDefaultOption) {

    __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(AXIS_TYPES, function (axisType) {

        BaseAxisModelClass.extend({

            type: dim + 'Axis3D.' + axisType,

            /**
             * @type readOnly
             */
            __ordinalMeta: null,

            mergeDefaultAndTheme: function (option, ecModel) {

                var themeModel = ecModel.getTheme();
                __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(option, themeModel.get(axisType + 'Axis3D'));
                __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(option, this.getDefaultOption());

                option.type = axisTypeDefaulter(dim, option);
            },

            /**
             * @override
             */
            optionUpdated: function () {
                var thisOption = this.option;

                if (thisOption.type === 'category') {
                    this.__ordinalMeta = __WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_OrdinalMeta___default.a.createByAxisModel(this);
                }
            },

            getCategories: function () {
                if (this.option.type === 'category') {
                    return this.__ordinalMeta.categories;
                }
            },

            getOrdinalMeta: function () {
                return this.__ordinalMeta;
            },

            defaultOption: __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(
                __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.clone(__WEBPACK_IMPORTED_MODULE_1__axis3DDefault__["a" /* default */][axisType + 'Axis3D']),
                extraDefaultOption || {},
                true
            )
        });
    });

    // TODO
    BaseAxisModelClass.superClass.registerSubTypeDefaulter(
        dim + 'Axis3D',
        __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.curry(axisTypeDefaulter, dim)
    );
});;

/***/ }),
/* 157 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


var defaultOption = {
    show: true,

    grid3DIndex: 0,
    // 反向坐标轴
    inverse: false,

    // 坐标轴名字
    name: '',
    // 坐标轴名字位置
    nameLocation: 'middle',

    nameTextStyle: {
        fontSize: 16
    },
    // 文字与轴线距离
    nameGap: 20,

    axisPointer: {},

    axisLine: {},
    // 坐标轴小标记
    axisTick: {},
    axisLabel: {},
    // 分隔区域
    splitArea: {}
};

var categoryAxis = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge({
    // 类目起始和结束两端空白策略
    boundaryGap: true,
    // splitArea: {
        // show: false
    // },
    // 坐标轴小标记
    axisTick: {
        // If tick is align with label when boundaryGap is true
        // Default with axisTick
        alignWithLabel: false,
        interval: 'auto'
    },
    // 坐标轴文本标签，详见axis.axisLabel
    axisLabel: {
        interval: 'auto'
    },
    axisPointer: {
        label: {
            show: false
        }
    }
}, defaultOption);

var valueAxis = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge({
    // 数值起始和结束两端空白策略
    boundaryGap: [0, 0],
    // 最小值, 设置成 'dataMin' 则从数据中计算最小值
    // min: null,
    // 最大值，设置成 'dataMax' 则从数据中计算最大值
    // max: null,
    // 脱离0值比例，放大聚焦到最终_min，_max区间
    // scale: false,
    // 分割段数，默认为5
    splitNumber: 5,
    // Minimum interval
    // minInterval: null

    axisPointer: {
        label: {
        }
    }
}, defaultOption);

// FIXME
var timeAxis = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.defaults({
    scale: true,
    min: 'dataMin',
    max: 'dataMax'
}, valueAxis);
var logAxis = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.defaults({
    logBase: 10
}, valueAxis);
logAxis.scale = true;

/* harmony default export */ __webpack_exports__["a"] = ({
    categoryAxis3D: categoryAxis,
    valueAxis3D: valueAxis,
    timeAxis3D: timeAxis,
    logAxis3D: logAxis
});

/***/ }),
/* 158 */
/***/ (function(module, exports, __webpack_require__) {

var _util = __webpack_require__(13);

var createHashMap = _util.createHashMap;
var isObject = _util.isObject;
var map = _util.map;

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

/**
 * @constructor
 * @param {Object} [opt]
 * @param {Object} [opt.categories=[]]
 * @param {Object} [opt.needCollect=false]
 * @param {Object} [opt.deduplication=false]
 */
function OrdinalMeta(opt) {
  /**
   * @readOnly
   * @type {Array.<string>}
   */
  this.categories = opt.categories || [];
  /**
   * @private
   * @type {boolean}
   */

  this._needCollect = opt.needCollect;
  /**
   * @private
   * @type {boolean}
   */

  this._deduplication = opt.deduplication;
  /**
   * @private
   * @type {boolean}
   */

  this._map;
}
/**
 * @param {module:echarts/model/Model} axisModel
 * @return {module:echarts/data/OrdinalMeta}
 */


OrdinalMeta.createByAxisModel = function (axisModel) {
  var option = axisModel.option;
  var data = option.data;
  var categories = data && map(data, getName);
  return new OrdinalMeta({
    categories: categories,
    needCollect: !categories,
    // deduplication is default in axis.
    deduplication: option.dedplication !== false
  });
};

var proto = OrdinalMeta.prototype;
/**
 * @param {string} category
 * @return {number} ordinal
 */

proto.getOrdinal = function (category) {
  return getOrCreateMap(this).get(category);
};
/**
 * @param {*} category
 * @return {number} The ordinal. If not found, return NaN.
 */


proto.parseAndCollect = function (category) {
  var index;
  var needCollect = this._needCollect; // The value of category dim can be the index of the given category set.
  // This feature is only supported when !needCollect, because we should
  // consider a common case: a value is 2017, which is a number but is
  // expected to be tread as a category. This case usually happen in dataset,
  // where it happent to be no need of the index feature.

  if (typeof category !== 'string' && !needCollect) {
    return category;
  } // Optimize for the scenario:
  // category is ['2012-01-01', '2012-01-02', ...], where the input
  // data has been ensured not duplicate and is large data.
  // Notice, if a dataset dimension provide categroies, usually echarts
  // should remove duplication except user tell echarts dont do that
  // (set axis.deduplication = false), because echarts do not know whether
  // the values in the category dimension has duplication (consider the
  // parallel-aqi example)


  if (needCollect && !this._deduplication) {
    index = this.categories.length;
    this.categories[index] = category;
    return index;
  }

  var map = getOrCreateMap(this);
  index = map.get(category);

  if (index == null) {
    if (needCollect) {
      index = this.categories.length;
      this.categories[index] = category;
      map.set(category, index);
    } else {
      index = NaN;
    }
  }

  return index;
}; // Consider big data, do not create map until needed.


function getOrCreateMap(ordinalMeta) {
  return ordinalMeta._map || (ordinalMeta._map = createHashMap(ordinalMeta.categories));
}

function getName(obj) {
  if (isObject(obj) && obj.value != null) {
    return obj.value;
  } else {
    return obj + '';
  }
}

var _default = OrdinalMeta;
module.exports = _default;

/***/ }),
/* 159 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_componentViewControlMixin__ = __webpack_require__(44);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_componentPostEffectMixin__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_componentLightMixin__ = __webpack_require__(29);





var Grid3DModel = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentModel({

    type: 'grid3D',

    dependencies: ['xAxis3D', 'yAxis3D', 'zAxis3D'],

    defaultOption: {

        show: true,

        zlevel: -10,

        // Layout used for viewport
        left: 0,
        top: 0,
        width: '100%',
        height: '100%',

        environment: 'auto',

        // Dimension of grid3D
        boxWidth: 100,
        boxHeight: 100,
        boxDepth: 100,

        // Common axis options.
        axisPointer: {
            show: true,
            lineStyle: {
                color: 'rgba(0, 0, 0, 0.8)',
                width: 1
            },

            label: {
                show: true,
                // (dimValue: number, value: Array) => string
                formatter: null,

                // TODO, Consider boxWidth
                margin: 8,
                // backgroundColor: '#ffbd67',
                // borderColor: '#000',
                // borderWidth: 0,

                textStyle: {
                    fontSize: 14,
                    color: '#fff',
                    backgroundColor: 'rgba(0,0,0,0.5)',
                    padding: 3,
                    borderRadius: 3
                }
            }
        },

        axisLine: {
            show: true,
            lineStyle: {
                color: '#333',
                width: 2,
                type: 'solid'
            }
        },

        axisTick: {
            show: true,
            inside: false,
            length: 3,
            lineStyle: {
                width: 1
            }
        },
        axisLabel: {
            show: true,
            inside: false,
            rotate: 0,
            margin: 8,
            textStyle: {
                fontSize: 12
            }
        },
        splitLine: {
            show: true,
            lineStyle: {
                color: ['#ccc'],
                width: 1,
                type: 'solid'
            }
        },
        splitArea: {
            show: false,
            areaStyle: {
                color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)']
            }
        },

        // Light options
        light: {
            main: {
                // Alpha angle for top-down rotation
                // Positive to rotate to top.
                alpha: 30,
                // beta angle for left-right rotation
                // Positive to rotate to right.
                beta: 40
            },
            ambient: {
                intensity: 0.4
            }
        },

        viewControl: {
            // Small damping for precise control.
            // damping: 0.1,

            // Alpha angle for top-down rotation
            // Positive to rotate to top.
            alpha: 20,
            // beta angle for left-right rotation
            // Positive to rotate to right.
            beta: 40,

            autoRotate: false,

            // Distance to the surface of grid3D.
            distance: 200,

            // Min distance to the surface of grid3D
            minDistance: 40,
            // Max distance to the surface of grid3D
            maxDistance: 400
        }
    }
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Grid3DModel.prototype, __WEBPACK_IMPORTED_MODULE_1__common_componentViewControlMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Grid3DModel.prototype, __WEBPACK_IMPORTED_MODULE_2__common_componentPostEffectMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Grid3DModel.prototype, __WEBPACK_IMPORTED_MODULE_3__common_componentLightMixin__["a" /* default */]);

/* unused harmony default export */ var _unused_webpack_default_export = (Grid3DModel);



/***/ }),
/* 160 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_OrbitControl__ = __webpack_require__(45);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_ZRTextureAtlasSurface__ = __webpack_require__(81);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__common_SceneHelper__ = __webpack_require__(30);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Grid3DFace__ = __webpack_require__(162);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Grid3DAxis__ = __webpack_require__(164);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__util_mesh_LabelsMesh__ = __webpack_require__(63);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__util_shader_lines3D_glsl_js__ = __webpack_require__(46);
// TODO orthographic camera






var firstNotNull = __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull;







__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_10__util_shader_lines3D_glsl_js__["a" /* default */]);

['x', 'y', 'z'].forEach(function (dim) {
    __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentView({
        type: dim + 'Axis3D'
    });
});

var dimIndicesMap = {
    // Left to right
    x: 0,
    // Far to near
    y: 2,
    // Bottom to up
    z: 1
};

/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentView({

    type: 'grid3D',

    __ecgl__: true,

    init: function (ecModel, api) {

        var FACES = [
            // planeDim0, planeDim1, offsetDim, dir on dim3 axis(gl), plane.
            ['y', 'z', 'x', -1, 'left'],
            ['y', 'z', 'x',  1, 'right'],
            ['x', 'y', 'z', -1, 'bottom'],
            ['x', 'y','z',  1, 'top'],
            ['x', 'z', 'y', -1, 'far'],
            ['x', 'z','y',  1, 'near']
        ];

        var DIMS = ['x', 'y', 'z'];

        var quadsMaterial = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
            // transparent: true,
            shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.color'),
            depthMask: false,
            transparent: true
        });
        var linesMaterial = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
            // transparent: true,
            shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.meshLines3D'),
            depthMask: false,
            transparent: true
        });
        quadsMaterial.define('fragment', 'DOUBLE_SIDED');
        quadsMaterial.define('both', 'VERTEX_COLOR');

        this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();

        this._control = new __WEBPACK_IMPORTED_MODULE_2__util_OrbitControl__["a" /* default */]({
            zr: api.getZr()
        });
        this._control.init();

        // Save mesh and other infos for each face.
        this._faces = FACES.map(function (faceInfo) {
            var face = new __WEBPACK_IMPORTED_MODULE_7__Grid3DFace__["a" /* default */](faceInfo, linesMaterial, quadsMaterial);
            this.groupGL.add(face.rootNode);
            return face;
        }, this);

        // Save mesh and other infos for each axis.
        this._axes = DIMS.map(function (dim) {
            var axis = new __WEBPACK_IMPORTED_MODULE_8__Grid3DAxis__["a" /* default */](dim, linesMaterial);
            this.groupGL.add(axis.rootNode);
            return axis;
        }, this);

        var dpr = api.getDevicePixelRatio();
        // Texture surface for label.
        this._axisLabelSurface = new __WEBPACK_IMPORTED_MODULE_5__util_ZRTextureAtlasSurface__["a" /* default */]({
            width: 256, height: 256,
            devicePixelRatio: dpr
        });
        this._axisLabelSurface.onupdate = function () {
            api.getZr().refresh();
        };

        this._axisPointerLineMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
            geometry: new __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__["a" /* default */]({ useNativeLine: false }),
            material: linesMaterial,
            castShadow: false,
            // PENDING
            ignorePicking: true,
            renderOrder: 3
        });
        this.groupGL.add(this._axisPointerLineMesh);

        this._axisPointerLabelsSurface = new __WEBPACK_IMPORTED_MODULE_5__util_ZRTextureAtlasSurface__["a" /* default */]({
            width: 128, height: 128,
            devicePixelRatio: dpr
        });
        this._axisPointerLabelsMesh = new __WEBPACK_IMPORTED_MODULE_9__util_mesh_LabelsMesh__["a" /* default */]({
            ignorePicking: true, renderOrder: 4,
            castShadow: false
        });
        this._axisPointerLabelsMesh.material.set('textureAtlas', this._axisPointerLabelsSurface.getTexture());
        this.groupGL.add(this._axisPointerLabelsMesh);

        this._lightRoot = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
        this._sceneHelper = new __WEBPACK_IMPORTED_MODULE_6__common_SceneHelper__["a" /* default */]();
        this._sceneHelper.initLight(this._lightRoot);
    },

    render: function (grid3DModel, ecModel, api) {

        this._model = grid3DModel;
        this._api = api;

        var cartesian = grid3DModel.coordinateSystem;

        // Always have light.
        cartesian.viewGL.add(this._lightRoot);

        if (grid3DModel.get('show')) {
            cartesian.viewGL.add(this.groupGL);
        }
        else {
            cartesian.viewGL.remove(this.groupGL);
        }

        // cartesian.viewGL.setCameraType(grid3DModel.get('viewControl.projection'));

        var control = this._control;
        control.setViewGL(cartesian.viewGL);

        var viewControlModel = grid3DModel.getModel('viewControl');
        control.setFromViewControlModel(viewControlModel, 0);

        this._axisLabelSurface.clear();

        control.off('update');
        if (grid3DModel.get('show')) {
            this._faces.forEach(function (face) {
                face.update(grid3DModel, ecModel, api);
            }, this);
            this._axes.forEach(function (axis) {
                axis.update(grid3DModel, this._axisLabelSurface, api);
            }, this);
        }

        control.on('update', this._onCameraChange.bind(this, grid3DModel, api), this);

        this._sceneHelper.setScene(cartesian.viewGL.scene);
        this._sceneHelper.updateLight(grid3DModel);

        // Set post effect
        cartesian.viewGL.setPostEffect(grid3DModel.getModel('postEffect'), api);
        cartesian.viewGL.setTemporalSuperSampling(grid3DModel.getModel('temporalSuperSampling'));

        this._initMouseHandler(grid3DModel);
    },

    afterRender: function (grid3DModel, ecModel, api, layerGL) {
        // Create ambient cubemap after render because we need to know the renderer.
        // TODO
        var renderer = layerGL.renderer;

        this._sceneHelper.updateAmbientCubemap(renderer, grid3DModel, api);

        this._sceneHelper.updateSkybox(renderer, grid3DModel, api);
    },

    /**
     * showAxisPointer will be triggered by action.
     */
    showAxisPointer: function (grid3dModel, ecModel, api, payload) {
        this._doShowAxisPointer();
        this._updateAxisPointer(payload.value);
    },

    /**
     * hideAxisPointer will be triggered by action.
     */
    hideAxisPointer: function (grid3dModel, ecModel, api, payload) {
        this._doHideAxisPointer();
    },

    _initMouseHandler: function (grid3DModel) {
        var cartesian = grid3DModel.coordinateSystem;
        var viewGL = cartesian.viewGL;

        // TODO xAxis3D.axisPointer.show ?
        if (grid3DModel.get('show') && grid3DModel.get('axisPointer.show')) {
            viewGL.on('mousemove', this._updateAxisPointerOnMousePosition, this);
        }
        else {
            viewGL.off('mousemove', this._updateAxisPointerOnMousePosition);
        }
    },

    /**
     * Try find and show axisPointer on the intersect point
     * of mouse ray with grid plane.
     */
    _updateAxisPointerOnMousePosition: function (e) {
        // Ignore if mouse is on the element.
        if (e.target) {
            return;
        }
        var grid3DModel = this._model;
        var cartesian = grid3DModel.coordinateSystem;
        var viewGL = cartesian.viewGL;

        var ray = viewGL.castRay(e.offsetX, e.offsetY, new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Ray());

        var nearestIntersectPoint;
        for (var i = 0; i < this._faces.length; i++) {
            var face = this._faces[i];
            if (face.rootNode.invisible) {
                continue;
            }

            // Plane is not face the camera. flip it
            if (face.plane.normal.dot(viewGL.camera.worldTransform.z) < 0) {
                face.plane.normal.negate();
            }

            var point = ray.intersectPlane(face.plane);
            if (!point) {
                continue;
            }
            var axis0 = cartesian.getAxis(face.faceInfo[0]);
            var axis1 = cartesian.getAxis(face.faceInfo[1]);
            var idx0 = dimIndicesMap[face.faceInfo[0]];
            var idx1 = dimIndicesMap[face.faceInfo[1]];
            if (axis0.contain(point.array[idx0]) && axis1.contain(point.array[idx1])) {
                nearestIntersectPoint = point;
            }
        }

        if (nearestIntersectPoint) {
            var data = cartesian.pointToData(nearestIntersectPoint.array, [], true);
            this._updateAxisPointer(data);

            this._doShowAxisPointer();
        }
        else {
            this._doHideAxisPointer();
        }
    },

    _onCameraChange: function (grid3DModel, api) {

        if (grid3DModel.get('show')) {
            this._updateFaceVisibility();
            this._updateAxisLinePosition();
        }

        var control = this._control;

        api.dispatchAction({
            type: 'grid3DChangeCamera',
            alpha: control.getAlpha(),
            beta: control.getBeta(),
            distance: control.getDistance(),
            center: control.getCenter(),
            from: this.uid,
            grid3DId: grid3DModel.id
        });
    },

    /**
     * Update visibility of each face when camera view changed, front face will be invisible.
     * @private
     */
    _updateFaceVisibility: function () {
        var camera = this._control.getCamera();
        var viewSpacePos = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Vector3();
        camera.update();
        for (var idx = 0; idx < this._faces.length / 2; idx++) {
            var depths = [];
            for (var k = 0; k < 2; k++) {
                var face = this._faces[idx * 2 + k];
                face.rootNode.getWorldPosition(viewSpacePos);
                viewSpacePos.transformMat4(camera.viewMatrix);
                depths[k] = viewSpacePos.z;
            }
            // Set the front face invisible
            var frontIndex = depths[0] > depths[1] ? 0 : 1;
            var frontFace = this._faces[idx * 2 + frontIndex];
            var backFace = this._faces[idx * 2 + 1 - frontIndex];
            // Update rotation.
            frontFace.rootNode.invisible = true;
            backFace.rootNode.invisible = false;
        }
    },

    /**
     * Update axis line position when camera view changed.
     * @private
     */
    _updateAxisLinePosition: function () {
        // Put xAxis, yAxis on x, y visible plane.
        // Put zAxis on the left.
        // TODO
        var cartesian = this._model.coordinateSystem;
        var xAxis = cartesian.getAxis('x');
        var yAxis = cartesian.getAxis('y');
        var zAxis = cartesian.getAxis('z');
        var top = zAxis.getExtentMax();
        var bottom = zAxis.getExtentMin();
        var left = xAxis.getExtentMin();
        var right = xAxis.getExtentMax();
        var near = yAxis.getExtentMax();
        var far = yAxis.getExtentMin();

        var xAxisNode = this._axes[0].rootNode;
        var yAxisNode = this._axes[1].rootNode;
        var zAxisNode = this._axes[2].rootNode;

        var faces = this._faces;
        // Notice: in cartesian up axis is z, but in webgl up axis is y.
        var xAxisZOffset = (faces[4].rootNode.invisible ? far : near);
        var xAxisYOffset = (faces[2].rootNode.invisible ? top : bottom);
        var yAxisXOffset = (faces[0].rootNode.invisible ? left : right);
        var yAxisYOffset = (faces[2].rootNode.invisible ? top : bottom);
        var zAxisXOffset = (faces[0].rootNode.invisible ? right : left);
        var zAxisZOffset = (faces[4].rootNode.invisible ? far : near);

        xAxisNode.rotation.identity();
        yAxisNode.rotation.identity();
        zAxisNode.rotation.identity();
        if (faces[4].rootNode.invisible) {
            this._axes[0].flipped = true;
            xAxisNode.rotation.rotateX(Math.PI);
        }
        if (faces[0].rootNode.invisible) {
            this._axes[1].flipped = true;
            yAxisNode.rotation.rotateZ(Math.PI);
        }
        if (faces[4].rootNode.invisible) {
            this._axes[2].flipped = true;
            zAxisNode.rotation.rotateY(Math.PI);
        }

        xAxisNode.position.set(0, xAxisYOffset, xAxisZOffset);
        yAxisNode.position.set(yAxisXOffset, yAxisYOffset, 0); // Actually z
        zAxisNode.position.set(zAxisXOffset, 0, zAxisZOffset); // Actually y

        xAxisNode.update();
        yAxisNode.update();
        zAxisNode.update();

        this._updateAxisLabelAlign();
    },

    /**
     * Update label align on axis when axisLine position changed.
     * @private
     */
    _updateAxisLabelAlign: function () {
        // var cartesian = this._model.coordinateSystem;
        var camera = this._control.getCamera();
        var coords = [new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Vector4(), new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Vector4()];
        var center = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Vector4();
        this.groupGL.getWorldPosition(center);
        center.w = 1.0;
        center.transformMat4(camera.viewMatrix)
            .transformMat4(camera.projectionMatrix);
        center.x /= center.w;
        center.y /= center.w;
        this._axes.forEach(function (axisInfo) {
            var lineCoords = axisInfo.axisLineCoords;
            var labelGeo = axisInfo.labelsMesh.geometry;
            for (var i = 0; i < coords.length; i++) {
                coords[i].setArray(lineCoords[i]);
                coords[i].w = 1.0;
                coords[i].transformMat4(axisInfo.rootNode.worldTransform)
                    .transformMat4(camera.viewMatrix)
                    .transformMat4(camera.projectionMatrix);
                coords[i].x /= coords[i].w;
                coords[i].y /= coords[i].w;
            }
            var dx = coords[1].x - coords[0].x;
            var dy = coords[1].y - coords[0].y;
            var cx = (coords[1].x + coords[0].x) / 2;
            var cy = (coords[1].y + coords[0].y) / 2;
            var textAlign;
            var verticalAlign;
            if (Math.abs(dy / dx) < 0.5) {
                textAlign = 'center';
                verticalAlign = cy > center.y ? 'bottom' : 'top';
            }
            else {
                verticalAlign = 'middle';
                textAlign = cx > center.x ? 'left' : 'right';
            }

            // axis labels
            axisInfo.setSpriteAlign(textAlign, verticalAlign, this._api);
        }, this);
    },

    _doShowAxisPointer: function () {
        if (!this._axisPointerLineMesh.invisible) {
            return;
        }

        this._axisPointerLineMesh.invisible = false;
        this._axisPointerLabelsMesh.invisible = false;
        this._api.getZr().refresh();
    },

    _doHideAxisPointer: function () {
        if (this._axisPointerLineMesh.invisible) {
            return;
        }

        this._axisPointerLineMesh.invisible = true;
        this._axisPointerLabelsMesh.invisible = true;
        this._api.getZr().refresh();
    },
    /**
     * @private updateAxisPointer.
     */
    _updateAxisPointer: function (data) {
        var cartesian = this._model.coordinateSystem;
        var point = cartesian.dataToPoint(data);

        var axisPointerLineMesh = this._axisPointerLineMesh;
        var linesGeo = axisPointerLineMesh.geometry;

        var axisPointerParentModel = this._model.getModel('axisPointer');

        var dpr = this._api.getDevicePixelRatio();
        linesGeo.convertToDynamicArray(true);


        function ifShowAxisPointer(axis) {
            return __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(
                axis.model.get('axisPointer.show'),
                axisPointerParentModel.get('show')
            );
        }
        function getAxisColorAndLineWidth(axis) {
            var axisPointerModel = axis.model.getModel('axisPointer', axisPointerParentModel);
            var lineStyleModel = axisPointerModel.getModel('lineStyle');

            var color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(lineStyleModel.get('color'));
            var lineWidth = firstNotNull(lineStyleModel.get('width'), 1);
            var opacity = firstNotNull(lineStyleModel.get('opacity'), 1);
            color[3] *= opacity;

            return {
                color: color,
                lineWidth: lineWidth
            };
        }
        for (var k = 0; k < this._faces.length; k++) {
            var face = this._faces[k];
            if (face.rootNode.invisible) {
                continue;
            }

            var faceInfo = face.faceInfo;
            var otherCoord = faceInfo[3] < 0
                ? cartesian.getAxis(faceInfo[2]).getExtentMin()
                : cartesian.getAxis(faceInfo[2]).getExtentMax();
            var otherDimIdx = dimIndicesMap[faceInfo[2]];

            // Line on face.
            for (var i = 0; i < 2; i++) {
                var dim = faceInfo[i];
                var faceOtherDim = faceInfo[1 - i];
                var axis = cartesian.getAxis(dim);
                var faceOtherAxis = cartesian.getAxis(faceOtherDim);

                if (!ifShowAxisPointer(axis)) {
                    continue;
                }

                var p0 = [0, 0, 0]; var p1 = [0, 0, 0];
                var dimIdx = dimIndicesMap[dim];
                var faceOtherDimIdx = dimIndicesMap[faceOtherDim];
                p0[dimIdx] = p1[dimIdx] = point[dimIdx];

                p0[otherDimIdx] = p1[otherDimIdx] = otherCoord;
                p0[faceOtherDimIdx] = faceOtherAxis.getExtentMin();
                p1[faceOtherDimIdx] = faceOtherAxis.getExtentMax();

                var colorAndLineWidth = getAxisColorAndLineWidth(axis);
                linesGeo.addLine(p0, p1, colorAndLineWidth.color, colorAndLineWidth.lineWidth * dpr);
            }

            // Project line.
            if (ifShowAxisPointer(cartesian.getAxis(faceInfo[2]))) {
                var p0 = point.slice();
                var p1 = point.slice();
                p1[otherDimIdx] = otherCoord;
                var colorAndLineWidth = getAxisColorAndLineWidth(cartesian.getAxis(faceInfo[2]));
                linesGeo.addLine(p0, p1, colorAndLineWidth.color, colorAndLineWidth.lineWidth * dpr);
            }
        }
        linesGeo.convertToTypedArray();

        this._updateAxisPointerLabelsMesh(data);

        this._api.getZr().refresh();
    },

    _updateAxisPointerLabelsMesh: function (data) {
        var grid3dModel = this._model;
        var axisPointerLabelsMesh = this._axisPointerLabelsMesh;
        var axisPointerLabelsSurface = this._axisPointerLabelsSurface;
        var cartesian = grid3dModel.coordinateSystem;

        var axisPointerParentModel = grid3dModel.getModel('axisPointer');

        axisPointerLabelsMesh.geometry.convertToDynamicArray(true);
        axisPointerLabelsSurface.clear();

        var otherDim = {
            x: 'y', y: 'x', z: 'y'
        };
        this._axes.forEach(function (axisInfo, idx) {
            var axis = cartesian.getAxis(axisInfo.dim);
            var axisModel = axis.model;
            var axisPointerModel = axisModel.getModel('axisPointer', axisPointerParentModel);
            var labelModel = axisPointerModel.getModel('label');
            var lineColor = axisPointerModel.get('lineStyle.color');
            if (!labelModel.get('show') || !axisPointerModel.get('show')) {
                return;
            }
            var val = data[idx];
            var formatter = labelModel.get('formatter');
            var text = axis.scale.getLabel(val);
            if (formatter != null) {
                text = formatter(text, data);
            }
            else {
                if (axis.scale.type === 'interval' || axis.scale.type === 'log') {
                    var precision = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.getPrecisionSafe(axis.scale.getTicks()[0]);
                    text = val.toFixed(precision + 2);
                }
            }

            var textStyleModel = labelModel.getModel('textStyle');
            var labelColor = textStyleModel.get('color');
            var textEl = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.Text();
            __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.setTextStyle(textEl.style, textStyleModel, {
                text: text,
                textFill: labelColor || lineColor,
                textAlign: 'left',
                textVerticalAlign: 'top'
            });
            var coords = axisPointerLabelsSurface.add(textEl);
            var rect = textEl.getBoundingRect();
            var dpr = this._api.getDevicePixelRatio();
            var pos = axisInfo.rootNode.position.toArray();
            var otherIdx = dimIndicesMap[otherDim[axisInfo.dim]];
            pos[otherIdx] += (axisInfo.flipped ? -1 : 1) * labelModel.get('margin');
            pos[dimIndicesMap[axisInfo.dim]] = axis.dataToCoord(data[idx]);

            axisPointerLabelsMesh.geometry.addSprite(
                pos, [rect.width * dpr, rect.height * dpr], coords,
                axisInfo.textAlign, axisInfo.textVerticalAlign
            );
        }, this);
        axisPointerLabelsSurface.getZr().refreshImmediately();
        axisPointerLabelsMesh.material.set('uvScale', axisPointerLabelsSurface.getCoordsScale());
        axisPointerLabelsMesh.geometry.convertToTypedArray();
    },

    dispose: function () {
        this.groupGL.removeAll();
        this._control.dispose();
    }
}));

/***/ }),
/* 161 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__vec2__ = __webpack_require__(70);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__vec3__ = __webpack_require__(12);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__vec4__ = __webpack_require__(33);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__mat2__ = __webpack_require__(78);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__mat2d__ = __webpack_require__(79);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__mat3__ = __webpack_require__(34);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__mat4__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__quat__ = __webpack_require__(55);
/**
 * @fileoverview gl-matrix - High performance matrix and vector operations
 * @author Brandon Jones
 * @author Colin MacKenzie IV
 * @version 2.2.2
 */

/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */










/* harmony default export */ __webpack_exports__["a"] = ({
    vec2: __WEBPACK_IMPORTED_MODULE_0__vec2__["a" /* default */],
    vec3: __WEBPACK_IMPORTED_MODULE_1__vec3__["a" /* default */],
    vec4: __WEBPACK_IMPORTED_MODULE_2__vec4__["a" /* default */],
    mat2: __WEBPACK_IMPORTED_MODULE_3__mat2__["a" /* default */],
    mat2d: __WEBPACK_IMPORTED_MODULE_4__mat2d__["a" /* default */],
    mat3: __WEBPACK_IMPORTED_MODULE_5__mat3__["a" /* default */],
    mat4: __WEBPACK_IMPORTED_MODULE_6__mat4__["a" /* default */],
    quat: __WEBPACK_IMPORTED_MODULE_7__quat__["a" /* default */]
});


/***/ }),
/* 162 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_geometry_Quads__ = __webpack_require__(163);





var firstNotNull = __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].firstNotNull;

var dimIndicesMap = {
    // Left to right
    x: 0,
    // Far to near
    y: 2,
    // Bottom to up
    z: 1
};

function updateFacePlane(node, plane, otherAxis, dir) {
    var coord = [0, 0, 0];
    var distance = dir < 0 ? otherAxis.getExtentMin() : otherAxis.getExtentMax();
    coord[dimIndicesMap[otherAxis.dim]] = distance;
    node.position.setArray(coord);
    node.rotation.identity();

    // Negative distance because on the opposite of normal direction.
    plane.distance = -Math.abs(distance);
    plane.normal.set(0, 0, 0);
    if (otherAxis.dim === 'x') {
        node.rotation.rotateY(dir * Math.PI / 2);
        plane.normal.x = -dir;
    }
    else if (otherAxis.dim === 'z') {
        node.rotation.rotateX(-dir * Math.PI / 2);
        plane.normal.y = -dir;
    }
    else {
        if (dir > 0) {
            node.rotation.rotateY(Math.PI);
        }
        plane.normal.z = -dir;
    }
}


function Grid3DFace(faceInfo, linesMaterial, quadsMaterial) {
    this.rootNode = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();

    var linesMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
        geometry: new __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__["a" /* default */]({ useNativeLine: false }),
        material: linesMaterial,
        castShadow: false,
        ignorePicking: true,
        $ignorePicking: true,
        renderOrder: 1
    });
    var quadsMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
        geometry: new __WEBPACK_IMPORTED_MODULE_4__util_geometry_Quads__["a" /* default */](),
        material: quadsMaterial,
        castShadow: false,
        culling: false,
        ignorePicking: true,
        $ignorePicking: true,
        renderOrder: 0
    });
    // Quads are behind lines.
    this.rootNode.add(quadsMesh);
    this.rootNode.add(linesMesh);

    this.faceInfo = faceInfo;
    this.plane =new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Plane();
    this.linesMesh =linesMesh;
    this.quadsMesh =quadsMesh;
}

Grid3DFace.prototype.update = function (grid3DModel, ecModel, api) {
    var cartesian = grid3DModel.coordinateSystem;
    var axes = [
        cartesian.getAxis(this.faceInfo[0]),
        cartesian.getAxis(this.faceInfo[1])
    ];
    var lineGeometry = this.linesMesh.geometry;
    var quadsGeometry = this.quadsMesh.geometry;

    lineGeometry.convertToDynamicArray(true);
    quadsGeometry.convertToDynamicArray(true);
    this._updateSplitLines(lineGeometry, axes, grid3DModel, api);
    this._udpateSplitAreas(quadsGeometry, axes, grid3DModel, api);
    lineGeometry.convertToTypedArray();
    quadsGeometry.convertToTypedArray();


    var otherAxis = cartesian.getAxis(this.faceInfo[2]);
    updateFacePlane(this.rootNode, this.plane, otherAxis, this.faceInfo[3]);
};

Grid3DFace.prototype._updateSplitLines = function (geometry, axes, grid3DModel, api) {
    var dpr = api.getDevicePixelRatio();
    axes.forEach(function (axis, idx) {
        var axisModel = axis.model;
        var otherExtent = axes[1 - idx].getExtent();

        if (axis.scale.isBlank()) {
            return;
        }

        var splitLineModel = axisModel.getModel('splitLine', grid3DModel.getModel('splitLine'));
        // Render splitLines
        if (splitLineModel.get('show')) {
            var lineStyleModel = splitLineModel.getModel('lineStyle');
            var lineColors = lineStyleModel.get('color');
            var opacity = firstNotNull(lineStyleModel.get('opacity'), 1.0);
            var lineWidth = firstNotNull(lineStyleModel.get('width'), 1.0);

            lineColors = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(lineColors) ? lineColors : [lineColors];

            var ticksCoords = axis.getTicksCoords({
                tickModel: splitLineModel
            });

            var count = 0;
            for (var i = 0; i < ticksCoords.length; i++) {
                var tickCoord = ticksCoords[i].coord;
                var lineColor = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(lineColors[count % lineColors.length]);
                lineColor[3] *= opacity;

                var p0 = [0, 0, 0]; var p1 = [0, 0, 0];
                // 0 - x, 1 - y
                p0[idx] = p1[idx] = tickCoord;
                p0[1 - idx] = otherExtent[0];
                p1[1 - idx] = otherExtent[1];

                geometry.addLine(p0, p1, lineColor, lineWidth * dpr);

                count++;
            }
        }
    });
};

Grid3DFace.prototype._udpateSplitAreas = function (geometry, axes, grid3DModel, api) {
    axes.forEach(function (axis, idx) {
        var axisModel = axis.model;
        var otherExtent = axes[1 - idx].getExtent();

        if (axis.scale.isBlank()) {
            return;
        }

        var splitAreaModel = axisModel.getModel('splitArea', grid3DModel.getModel('splitArea'));
        // Render splitAreas
        if (splitAreaModel.get('show')) {
            var areaStyleModel = splitAreaModel.getModel('areaStyle');
            var colors = areaStyleModel.get('color');
            var opacity = firstNotNull(areaStyleModel.get('opacity'), 1.0);

            colors = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(colors) ? colors : [colors];

            var ticksCoords = axis.getTicksCoords({
                tickModel: splitAreaModel,
                clamp: true
            });

            var count = 0;
            var prevP0 = [0, 0, 0];
            var prevP1 = [0, 0, 0];
            // 0 - x, 1 - y
            for (var i = 0; i < ticksCoords.length; i++) {
                var tickCoord = ticksCoords[i].coord;

                var p0 = [0, 0, 0]; var p1 = [0, 0, 0];
                // 0 - x, 1 - y
                p0[idx] = p1[idx] = tickCoord;
                p0[1 - idx] = otherExtent[0];
                p1[1 - idx] = otherExtent[1];

                if (i === 0) {
                    prevP0 = p0;
                    prevP1 = p1;
                    continue;
                }

                var color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(colors[count % colors.length]);
                color[3] *= opacity;
                geometry.addQuad([prevP0, p0, p1, prevP1], color);

                prevP0 = p0;
                prevP1 = p1;

                count++;
            }
        }
    });
};

/* harmony default export */ __webpack_exports__["a"] = (Grid3DFace);

/***/ }),
/* 163 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__ = __webpack_require__(38);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__ = __webpack_require__(6);
/**
 * @module echarts-gl/util/geometry/QuadsGeometry
 * @author Yi Shen(http://github.com/pissang)
 */





var vec3 = __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__["a" /* default */].vec3;

/**
 * @constructor
 * @alias module:echarts-gl/util/geometry/QuadsGeometry
 * @extends clay.Geometry
 */

var QuadsGeometry = __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].extend(function () {
    return {

        segmentScale: 1,

        /**
         * Need to use mesh to expand lines if lineWidth > MAX_LINE_WIDTH
         */
        useNativeLine: true,

        attributes: {
            position: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('position', 'float', 3, 'POSITION'),
            normal: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('normal', 'float', 3, 'NORMAL'),
            color: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('color', 'float', 4, 'COLOR')
        }
    };
},
/** @lends module: echarts-gl/util/geometry/QuadsGeometry.prototype */
{

    /**
     * Reset offset
     */
    resetOffset: function () {
        this._vertexOffset = 0;
        this._faceOffset = 0;
    },

    /**
     * @param {number} nQuad
     */
    setQuadCount: function (nQuad) {
        var attributes = this.attributes;
        var vertexCount = this.getQuadVertexCount() * nQuad;
        var triangleCount = this.getQuadTriangleCount() * nQuad;
        if (this.vertexCount !== vertexCount) {
            attributes.position.init(vertexCount);
            attributes.normal.init(vertexCount);
            attributes.color.init(vertexCount);
        }
        if (this.triangleCount !== triangleCount) {
            this.indices = vertexCount > 0xffff ? new Uint32Array(triangleCount * 3) : new Uint16Array(triangleCount * 3);
        }
    },

    getQuadVertexCount: function () {
        return 4;
    },

    getQuadTriangleCount: function () {
        return 2;
    },

    /**
     * Add a quad, which in following order:
     * 0-----1
     * 3-----2
     */
    addQuad: (function () {
        var a = vec3.create();
        var b = vec3.create();
        var normal = vec3.create();
        var indices = [0, 3, 1, 3, 2, 1];
        return function (coords,  color) {
            var positionAttr = this.attributes.position;
            var normalAttr = this.attributes.normal;
            var colorAttr = this.attributes.color;

            vec3.sub(a, coords[1], coords[0]);
            vec3.sub(b, coords[2], coords[1]);
            vec3.cross(normal, a, b);
            vec3.normalize(normal, normal);

            for (var i = 0; i < 4; i++) {
                positionAttr.set(this._vertexOffset + i, coords[i]);
                colorAttr.set(this._vertexOffset + i, color);
                normalAttr.set(this._vertexOffset + i, normal);
            }
            var idx = this._faceOffset * 3;
            for (var i = 0; i < 6; i++) {
                this.indices[idx + i] = indices[i] + this._vertexOffset;
            }
            this._vertexOffset += 4;
            this._faceOffset += 2;
        };
    })()
});

__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.util.defaults(QuadsGeometry.prototype, __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__["a" /* default */]);

/* harmony default export */ __webpack_exports__["a"] = (QuadsGeometry);

/***/ }),
/* 164 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_geometry_Lines3D__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_mesh_LabelsMesh__ = __webpack_require__(63);





var firstNotNull = __WEBPACK_IMPORTED_MODULE_3__util_retrieve__["a" /* default */].firstNotNull;

var dimIndicesMap = {
    // Left to right
    x: 0,
    // Far to near
    y: 2,
    // Bottom to up
    z: 1
};

function Grid3DAxis(dim, linesMaterial) {
    var linesMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
        geometry: new __WEBPACK_IMPORTED_MODULE_2__util_geometry_Lines3D__["a" /* default */]({ useNativeLine: false }),
        material: linesMaterial,
        castShadow: false,
        ignorePicking: true, renderOrder: 2
    });
    var axisLabelsMesh = new __WEBPACK_IMPORTED_MODULE_4__util_mesh_LabelsMesh__["a" /* default */]();
    axisLabelsMesh.material.depthMask = false;

    var rootNode = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
    rootNode.add(linesMesh);
    rootNode.add(axisLabelsMesh);

    this.rootNode = rootNode;
    this.dim = dim;

    this.linesMesh = linesMesh;
    this.labelsMesh = axisLabelsMesh;
    this.axisLineCoords = null;
    this.labelElements = [];
}

var otherDim = {
    x: 'y', y: 'x', z: 'y'
};
Grid3DAxis.prototype.update = function (
    grid3DModel, axisLabelSurface, api
) {
    var cartesian = grid3DModel.coordinateSystem;
    var axis = cartesian.getAxis(this.dim);

    var linesGeo = this.linesMesh.geometry;
    var labelsGeo = this.labelsMesh.geometry;
    linesGeo.convertToDynamicArray(true);
    labelsGeo.convertToDynamicArray(true);
    var axisModel = axis.model;
    var extent = axis.getExtent();

    var dpr = api.getDevicePixelRatio();
    var axisLineModel = axisModel.getModel('axisLine', grid3DModel.getModel('axisLine'));
    var axisTickModel = axisModel.getModel('axisTick', grid3DModel.getModel('axisTick'));
    var axisLabelModel = axisModel.getModel('axisLabel', grid3DModel.getModel('axisLabel'));
    var axisLineColor = axisLineModel.get('lineStyle.color');
    // Render axisLine
    if (axisLineModel.get('show')) {
        var axisLineStyleModel = axisLineModel.getModel('lineStyle');
        var p0 = [0, 0, 0]; var p1 = [0, 0, 0];
        var idx = dimIndicesMap[axis.dim];
        p0[idx] = extent[0];
        p1[idx] = extent[1];

        // Save some useful info.
        this.axisLineCoords =[p0, p1];

        var color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(axisLineColor);
        var lineWidth = firstNotNull(axisLineStyleModel.get('width'), 1.0);
        var opacity = firstNotNull(axisLineStyleModel.get('opacity'), 1.0);
        color[3] *= opacity;
        linesGeo.addLine(p0, p1, color, lineWidth * dpr);
    }
    // Render axis ticksCoords
    if (axisTickModel.get('show')) {
        var lineStyleModel = axisTickModel.getModel('lineStyle');
        var lineColor = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(
            firstNotNull(lineStyleModel.get('color'), axisLineColor)
        );
        var lineWidth = firstNotNull(lineStyleModel.get('width'), 1.0);
        lineColor[3] *= firstNotNull(lineStyleModel.get('opacity'), 1.0);
        var ticksCoords = axis.getTicksCoords();
        var tickLength = axisTickModel.get('length');

        for (var i = 0; i < ticksCoords.length; i++) {
            var tickCoord = ticksCoords[i].coord;

            var p0 = [0, 0, 0]; var p1 = [0, 0, 0];
            var idx = dimIndicesMap[axis.dim];
            var otherIdx = dimIndicesMap[otherDim[axis.dim]];
            // 0 : x, 1 : y
            p0[idx] = p1[idx] = tickCoord;
            p1[otherIdx] = tickLength;

            linesGeo.addLine(p0, p1, lineColor, lineWidth * dpr);
        }
    }

    this.labelElements = [];
    var dpr = api.getDevicePixelRatio();
    if (axisLabelModel.get('show')) {
        var ticksCoords = axis.getTicksCoords();
        var categoryData = axisModel.get('data');

        var labelMargin = axisLabelModel.get('margin');
        var labels = axis.getViewLabels();

        for (var i = 0; i < labels.length; i++) {
            var tickValue = labels[i].tickValue;
            var formattedLabel = labels[i].formattedLabel;
            var rawLabel = labels[i].rawLabel;

            var tickCoord = axis.dataToCoord(tickValue);

            var p = [0, 0, 0];
            var idx = dimIndicesMap[axis.dim];
            var otherIdx = dimIndicesMap[otherDim[axis.dim]];
            // 0 : x, 1 : y
            p[idx] = p[idx] = tickCoord;
            p[otherIdx] = labelMargin;

            var itemTextStyleModel = axisLabelModel;
            if (categoryData && categoryData[tickValue] && categoryData[tickValue].textStyle) {
                itemTextStyleModel = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Model(
                    categoryData[tickValue].textStyle, axisLabelModel, axisModel.ecModel
                );
            }
            var textColor = firstNotNull(itemTextStyleModel.get('color'), axisLineColor);

            var textEl = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.Text();
            __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.setTextStyle(textEl.style, itemTextStyleModel, {
                text: formattedLabel,
                textFill: typeof textColor === 'function'
                    ? textColor(
                        // (1) In category axis with data zoom, tick is not the original
                        // index of axis.data. So tick should not be exposed to user
                        // in category axis.
                        // (2) Compatible with previous version, which always returns labelStr.
                        // But in interval scale labelStr is like '223,445', which maked
                        // user repalce ','. So we modify it to return original val but remain
                        // it as 'string' to avoid error in replacing.
                        axis.type === 'category' ? rawLabel : axis.type === 'value' ? tickValue + '' : tickValue,
                        i
                    )
                    : textColor,
                textVerticalAlign: 'top',
                textAlign: 'left'
            });
            var coords = axisLabelSurface.add(textEl);
            var rect = textEl.getBoundingRect();
            labelsGeo.addSprite(p, [rect.width * dpr, rect.height * dpr], coords);

            this.labelElements.push(textEl);
        }
    }

    if (axisModel.get('name')) {
        var nameTextStyleModel = axisModel.getModel('nameTextStyle');
        var p = [0, 0, 0];
        var idx = dimIndicesMap[axis.dim];
        var otherIdx = dimIndicesMap[otherDim[axis.dim]];
        var labelColor = firstNotNull(nameTextStyleModel.get('color'), axisLineColor);
        var strokeColor = nameTextStyleModel.get('borderColor');
        var lineWidth = nameTextStyleModel.get('borderWidth');
        // TODO start and end
        p[idx] = p[idx] = (extent[0] + extent[1]) / 2;
        p[otherIdx] = axisModel.get('nameGap');

        var textEl = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.Text();
        __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.setTextStyle(textEl.style, nameTextStyleModel, {
            text: axisModel.get('name'),
            textFill: labelColor,
            textStroke: strokeColor,
            lineWidth: lineWidth
        });
        var coords = axisLabelSurface.add(textEl);
        var rect = textEl.getBoundingRect();
        labelsGeo.addSprite(p, [rect.width * dpr, rect.height * dpr], coords);

        textEl.__idx = this.labelElements.length;
        this.nameLabelElement = textEl;
    }

    this.labelsMesh.material.set('textureAtlas', axisLabelSurface.getTexture());
    this.labelsMesh.material.set('uvScale', axisLabelSurface.getCoordsScale());

    linesGeo.convertToTypedArray();
    labelsGeo.convertToTypedArray();
};

Grid3DAxis.prototype.setSpriteAlign = function (textAlign, textVerticalAlign, api) {
    var dpr = api.getDevicePixelRatio();
    var labelGeo = this.labelsMesh.geometry;
    for (var i = 0; i < this.labelElements.length; i++) {
        var labelEl = this.labelElements[i];
        var rect = labelEl.getBoundingRect();

        labelGeo.setSpriteAlign(i, [rect.width * dpr, rect.height * dpr], textAlign, textVerticalAlign);
    }
    // name label
    var nameLabelEl = this.nameLabelElement;
    if (nameLabelEl) {
        var rect = nameLabelEl.getBoundingRect();
        labelGeo.setSpriteAlign(nameLabelEl.__idx, [rect.width * dpr, rect.height * dpr], textAlign, textVerticalAlign);
        labelGeo.dirty();
    }

    this.textAlign = textAlign;
    this.textVerticalAlign = textVerticalAlign;
};

/* harmony default export */ __webpack_exports__["a"] = (Grid3DAxis);

/***/ }),
/* 165 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__ = __webpack_require__(38);
/**
 * Geometry collecting sprites
 *
 * @module echarts-gl/util/geometry/Sprites
 * @author Yi Shen(https://github.com/pissang)
 */




var squareTriangles = [
    0, 1, 2, 0, 2, 3
];

var SpritesGeometry = __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__["a" /* default */].extend(function () {
    return {
        attributes: {
            position: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__["a" /* default */].Attribute('position', 'float', 3, 'POSITION'),
            texcoord: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__["a" /* default */].Attribute('texcoord', 'float', 2, 'TEXCOORD_0'),
            offset: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__["a" /* default */].Attribute('offset', 'float', 2),
            color: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__["a" /* default */].Attribute('color', 'float', 4, 'COLOR')
        }
    };
}, {
    resetOffset: function () {
        this._vertexOffset = 0;
        this._faceOffset = 0;
    },
    setSpriteCount: function (spriteCount) {
        this._spriteCount = spriteCount;

        var vertexCount = spriteCount * 4;
        var triangleCount = spriteCount * 2;

        if (this.vertexCount !== vertexCount) {
            this.attributes.position.init(vertexCount);
            this.attributes.offset.init(vertexCount);
            this.attributes.color.init(vertexCount);
        }
        if (this.triangleCount !== triangleCount) {
            this.indices = vertexCount > 0xffff ? new Uint32Array(triangleCount * 3) : new Uint16Array(triangleCount * 3);
        }
    },

    setSpriteAlign: function (spriteOffset, size, align, verticalAlign, margin) {
        if (align == null) {
            align = 'left';
        }
        if (verticalAlign == null) {
            verticalAlign = 'top';
        }

        var leftOffset, topOffset, rightOffset, bottomOffset;
        margin = margin || 0;
        switch (align) {
            case 'left':
                leftOffset = margin;
                rightOffset = size[0] + margin;
                break;
            case 'center':
            case 'middle':
                leftOffset = -size[0] / 2;
                rightOffset = size[0] / 2;
                break;
            case 'right':
                leftOffset = -size[0] - margin;
                rightOffset = -margin;
                break;
        }
        switch (verticalAlign) {
            case 'bottom':
                topOffset = margin;
                bottomOffset = size[1] + margin;
                break;
            case 'middle':
                topOffset = -size[1] / 2;
                bottomOffset = size[1] / 2;
                break;
            case 'top':
                topOffset = -size[1] - margin;
                bottomOffset = -margin;
                break;
        }
        // 3----2
        // 0----1
        var vertexOffset = spriteOffset * 4;
        var offsetAttr = this.attributes.offset;
        offsetAttr.set(vertexOffset, [leftOffset, bottomOffset]);
        offsetAttr.set(vertexOffset + 1, [rightOffset, bottomOffset]);
        offsetAttr.set(vertexOffset + 2, [rightOffset, topOffset]);
        offsetAttr.set(vertexOffset + 3, [leftOffset, topOffset]);
    },
    /**
     * Add sprite
     * @param {Array.<number>} position
     * @param {Array.<number>} size [width, height]
     * @param {Array.<Array>} coords [leftBottom, rightTop]
     * @param {string} [align='left'] 'left' 'center' 'right'
     * @param {string} [verticalAlign='top'] 'top' 'middle' 'bottom'
     * @param {number} [screenMargin=0]
     */
    addSprite: function (position, size, coords, align, verticalAlign, screenMargin) {
        var vertexOffset = this._vertexOffset;
        this.setSprite(
            this._vertexOffset / 4, position, size, coords, align, verticalAlign, screenMargin
        )
        for (var i = 0; i < squareTriangles.length; i++) {
            this.indices[this._faceOffset * 3 + i] = squareTriangles[i] + vertexOffset;
        }
        this._faceOffset += 2;
        this._vertexOffset += 4;

        return vertexOffset / 4;
    },

    setSprite: function (spriteOffset, position, size, coords, align, verticalAlign, screenMargin) {
        var vertexOffset = spriteOffset * 4;

        var attributes = this.attributes;
        for (var i = 0; i < 4; i++) {
            attributes.position.set(vertexOffset + i, position);
        }
        // 3----2
        // 0----1
        var texcoordAttr = attributes.texcoord;

        texcoordAttr.set(vertexOffset, [coords[0][0], coords[0][1]]);
        texcoordAttr.set(vertexOffset + 1, [coords[1][0], coords[0][1]]);
        texcoordAttr.set(vertexOffset + 2, [coords[1][0], coords[1][1]]);
        texcoordAttr.set(vertexOffset + 3, [coords[0][0], coords[1][1]]);

        this.setSpriteAlign(spriteOffset, size, align, verticalAlign, screenMargin);
    }
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.defaults(SpritesGeometry.prototype, __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__["a" /* default */]);

/* harmony default export */ __webpack_exports__["a"] = (SpritesGeometry);

/***/ }),
/* 166 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.labels.vertex\n\nattribute vec3 position: POSITION;\nattribute vec2 texcoord: TEXCOORD_0;\nattribute vec2 offset;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec4 viewport : VIEWPORT;\n\nvarying vec2 v_Texcoord;\n\nvoid main()\n{\n vec4 proj = worldViewProjection * vec4(position, 1.0);\n\n vec2 screen = (proj.xy / abs(proj.w) + 1.0) * 0.5 * viewport.zw;\n\n screen += offset;\n\n proj.xy = (screen / viewport.zw - 0.5) * 2.0 * abs(proj.w);\n gl_Position = proj;\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n v_Texcoord = texcoord;\n}\n@end\n\n\n@export ecgl.labels.fragment\n\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform float alpha : 1.0;\nuniform sampler2D textureAtlas;\nuniform vec2 uvScale: [1.0, 1.0];\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\nvarying float v_Miter;\n\nvarying vec2 v_Texcoord;\n\nvoid main()\n{\n gl_FragColor = vec4(color, alpha) * texture2D(textureAtlas, v_Texcoord * uvScale);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n}\n\n@end");


/***/ }),
/* 167 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__grid3D_Cartesian3D__ = __webpack_require__(168);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__grid3D_Axis3D__ = __webpack_require__(170);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_util_layout__ = __webpack_require__(47);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_util_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_util_layout__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__core_ViewGL__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_retrieve__ = __webpack_require__(2);







function resizeCartesian3D(grid3DModel, api) {
    // Use left/top/width/height
    var boxLayoutOption = grid3DModel.getBoxLayoutParams();

    var viewport = __WEBPACK_IMPORTED_MODULE_3_echarts_lib_util_layout___default.a.getLayoutRect(boxLayoutOption, {
        width: api.getWidth(),
        height: api.getHeight()
    });

    // Flip Y
    viewport.y = api.getHeight() - viewport.y - viewport.height;

    this.viewGL.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, api.getDevicePixelRatio());

    var boxWidth = grid3DModel.get('boxWidth');
    var boxHeight = grid3DModel.get('boxHeight');
    var boxDepth = grid3DModel.get('boxDepth');

    if (true) {
        ['x', 'y', 'z'].forEach(function (dim) {
            if (!this.getAxis(dim)) {
                throw new Error('Grid' + grid3DModel.id + ' don\'t have ' + dim + 'Axis');
            }
        }, this);
    }
    this.getAxis('x').setExtent(-boxWidth / 2, boxWidth / 2);
    // From near to far
    this.getAxis('y').setExtent(boxDepth / 2, -boxDepth / 2);
    this.getAxis('z').setExtent(-boxHeight / 2, boxHeight / 2);

    this.size = [boxWidth, boxHeight, boxDepth];
}

function updateCartesian3D(ecModel, api) {
    var dataExtents = {};
    function unionDataExtents(dim, extent) {
        dataExtents[dim] = dataExtents[dim] || [Infinity, -Infinity];
        dataExtents[dim][0] = Math.min(extent[0], dataExtents[dim][0]);
        dataExtents[dim][1] = Math.max(extent[1], dataExtents[dim][1]);
    }
    // Get data extents for scale.
    ecModel.eachSeries(function (seriesModel) {
        if (seriesModel.coordinateSystem !== this) {
            return;
        }
        var data = seriesModel.getData();
        ['x', 'y', 'z'].forEach(function (coordDim) {
            data.mapDimension(coordDim, true).forEach(function (dataDim) {
                unionDataExtents(
                    coordDim, data.getDataExtent(dataDim, true)
                );
            });
        });
    }, this);

    ['xAxis3D', 'yAxis3D', 'zAxis3D'].forEach(function (axisType) {
        ecModel.eachComponent(axisType, function (axisModel) {
            var dim = axisType.charAt(0);
            var grid3DModel = axisModel.getReferringComponents('grid3D')[0];

            var cartesian3D = grid3DModel.coordinateSystem;
            if (cartesian3D !== this) {
                return;
            }

            var axis = cartesian3D.getAxis(dim);
            if (axis) {
                if (true) {
                    console.warn('Can\'t have two %s in one grid3D', axisType);
                }
                return;
            }
            var scale = __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default.a.helper.createScale(
                dataExtents[dim] || [Infinity, -Infinity], axisModel
            );
            axis = new __WEBPACK_IMPORTED_MODULE_1__grid3D_Axis3D__["a" /* default */](dim, scale);
            axis.type = axisModel.get('type');
            var isCategory = axis.type === 'category';
            axis.onBand = isCategory && axisModel.get('boundaryGap');
            axis.inverse = axisModel.get('inverse');

            axisModel.axis = axis;
            axis.model = axisModel;

            // override `echarts/coord/Axis#getLabelModel`
            axis.getLabelModel = function () {
                return axisModel.getModel('axisLabel', grid3DModel.getModel('axisLabel'));
            };
            // override `echarts/coord/Axis#getTickModel`
            axis.getTickModel = function () {
                return axisModel.getModel('axisTick', grid3DModel.getModel('axisTick'));
            };

            cartesian3D.addAxis(axis);
        }, this);
    }, this);

    this.resize(this.model, api);
}

var grid3DCreator = {

    dimensions: __WEBPACK_IMPORTED_MODULE_0__grid3D_Cartesian3D__["a" /* default */].prototype.dimensions,

    create: function (ecModel, api) {

        var cartesian3DList = [];

        ecModel.eachComponent('grid3D', function (grid3DModel) {
            // FIXME
            grid3DModel.__viewGL = grid3DModel.__viewGL || new __WEBPACK_IMPORTED_MODULE_4__core_ViewGL__["a" /* default */]();

            var cartesian3D = new __WEBPACK_IMPORTED_MODULE_0__grid3D_Cartesian3D__["a" /* default */]();
            cartesian3D.model = grid3DModel;
            cartesian3D.viewGL = grid3DModel.__viewGL;

            grid3DModel.coordinateSystem = cartesian3D;
            cartesian3DList.push(cartesian3D);

            // Inject resize and update
            cartesian3D.resize = resizeCartesian3D;

            cartesian3D.update = updateCartesian3D;
        });

        var axesTypes = ['xAxis3D', 'yAxis3D', 'zAxis3D'];
        function findAxesModels(seriesModel, ecModel) {
            return axesTypes.map(function (axisType) {
                var axisModel = seriesModel.getReferringComponents(axisType)[0];
                if (axisModel == null) {
                    axisModel = ecModel.getComponent(axisType);
                }
                if (true) {
                    if (!axisModel) {
                        throw new Error(axisType + ' "' + __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(
                            seriesModel.get(axisType + 'Index'),
                            seriesModel.get(axisType + 'Id'),
                            0
                        ) + '" not found');
                    }
                }
                return axisModel;
            });
        }

        ecModel.eachSeries(function (seriesModel) {
            if (seriesModel.get('coordinateSystem') !== 'cartesian3D') {
                return;
            }
            var firstGridModel = seriesModel.getReferringComponents('grid3D')[0];

            if (firstGridModel == null) {
                var axesModels = findAxesModels(seriesModel, ecModel);
                var firstGridModel = axesModels[0].getCoordSysModel();
                axesModels.forEach(function (axisModel) {
                    var grid3DModel = axisModel.getCoordSysModel();
                    if (true) {
                        if (!grid3DModel) {
                            throw new Error(
                                'grid3D "' + __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(
                                    axisModel.get('gridIndex'),
                                    axisModel.get('gridId'),
                                    0
                                ) + '" not found'
                            );
                        }
                        if (grid3DModel !== firstGridModel) {
                            throw new Error('xAxis3D, yAxis3D, zAxis3D must use the same grid');
                        }
                    }
                });
            }

            var coordSys = firstGridModel.coordinateSystem;
            seriesModel.coordinateSystem = coordSys;
        });

        return cartesian3DList;
    }
};

__WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default.a.registerCoordinateSystem('grid3D', grid3DCreator);

/* unused harmony default export */ var _unused_webpack_default_export = (grid3DCreator);

/***/ }),
/* 168 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_coord_cartesian_Cartesian__ = __webpack_require__(169);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_coord_cartesian_Cartesian___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_coord_cartesian_Cartesian__);



function Cartesian3D(name) {

    __WEBPACK_IMPORTED_MODULE_1_echarts_lib_coord_cartesian_Cartesian___default.a.call(this, name);

    this.size = [0, 0, 0];
}

Cartesian3D.prototype = {

    constructor: Cartesian3D,

    type: 'cartesian3D',

    dimensions: ['x', 'y', 'z'],

    model: null,

    containPoint: function (point) {
        return this.getAxis('x').contain(point[0])
            && this.getAxis('y').contain(point[2])
            && this.getAxis('z').contain(point[1]);
    },

    containData: function (data) {
        return this.getAxis('x').containData(data[0])
            && this.getAxis('y').containData(data[1])
            && this.getAxis('z').containData(data[2]);
    },

    dataToPoint: function (data, out, clamp) {
        out = out || [];
        out[0] = this.getAxis('x').dataToCoord(data[0], clamp);
        out[2] = this.getAxis('y').dataToCoord(data[1], clamp);
        out[1] = this.getAxis('z').dataToCoord(data[2], clamp);
        return out;
    },

    pointToData: function (point, out, clamp) {
        out = out || [];
        out[0] = this.getAxis('x').coordToData(point[0], clamp);
        out[1] = this.getAxis('y').coordToData(point[2], clamp);
        out[2] = this.getAxis('z').coordToData(point[1], clamp);
        return out;
    }
};

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.inherits(Cartesian3D, __WEBPACK_IMPORTED_MODULE_1_echarts_lib_coord_cartesian_Cartesian___default.a);

/* harmony default export */ __webpack_exports__["a"] = (Cartesian3D);

/***/ }),
/* 169 */
/***/ (function(module, exports, __webpack_require__) {

var zrUtil = __webpack_require__(13);

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

/**
 * Cartesian coordinate system
 * @module  echarts/coord/Cartesian
 *
 */
function dimAxisMapper(dim) {
  return this._axes[dim];
}
/**
 * @alias module:echarts/coord/Cartesian
 * @constructor
 */


var Cartesian = function (name) {
  this._axes = {};
  this._dimList = [];
  /**
   * @type {string}
   */

  this.name = name || '';
};

Cartesian.prototype = {
  constructor: Cartesian,
  type: 'cartesian',

  /**
   * Get axis
   * @param  {number|string} dim
   * @return {module:echarts/coord/Cartesian~Axis}
   */
  getAxis: function (dim) {
    return this._axes[dim];
  },

  /**
   * Get axes list
   * @return {Array.<module:echarts/coord/Cartesian~Axis>}
   */
  getAxes: function () {
    return zrUtil.map(this._dimList, dimAxisMapper, this);
  },

  /**
   * Get axes list by given scale type
   */
  getAxesByScale: function (scaleType) {
    scaleType = scaleType.toLowerCase();
    return zrUtil.filter(this.getAxes(), function (axis) {
      return axis.scale.type === scaleType;
    });
  },

  /**
   * Add axis
   * @param {module:echarts/coord/Cartesian.Axis}
   */
  addAxis: function (axis) {
    var dim = axis.dim;
    this._axes[dim] = axis;

    this._dimList.push(dim);
  },

  /**
   * Convert data to coord in nd space
   * @param {Array.<number>|Object.<string, number>} val
   * @return {Array.<number>|Object.<string, number>}
   */
  dataToCoord: function (val) {
    return this._dataCoordConvert(val, 'dataToCoord');
  },

  /**
   * Convert coord in nd space to data
   * @param  {Array.<number>|Object.<string, number>} val
   * @return {Array.<number>|Object.<string, number>}
   */
  coordToData: function (val) {
    return this._dataCoordConvert(val, 'coordToData');
  },
  _dataCoordConvert: function (input, method) {
    var dimList = this._dimList;
    var output = input instanceof Array ? [] : {};

    for (var i = 0; i < dimList.length; i++) {
      var dim = dimList[i];
      var axis = this._axes[dim];
      output[dim] = axis[method](input[dim]);
    }

    return output;
  }
};
var _default = Cartesian;
module.exports = _default;

/***/ }),
/* 170 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


function Axis3D(dim, scale, extent) {

    __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Axis.call(this, dim, scale, extent);
}

Axis3D.prototype = {
    constructor: Axis3D,

    getExtentMin: function () {
        var extent = this._extent;
        return Math.min(extent[0], extent[1]);
    },

    getExtentMax: function () {
        var extent = this._extent;
        return Math.max(extent[0], extent[1]);
    },

    calculateCategoryInterval: function () {
        // TODO consider label length
        return Math.floor(this.scale.count() / 8);
    }
};

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.inherits(Axis3D, __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Axis);

/* harmony default export */ __webpack_exports__["a"] = (Axis3D);

/***/ }),
/* 171 */
/***/ (function(module, exports, __webpack_require__) {

var zrUtil = __webpack_require__(13);

var textContain = __webpack_require__(172);

var numberUtil = __webpack_require__(85);

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

/**
 * 每三位默认加,格式化
 * @param {string|number} x
 * @return {string}
 */
function addCommas(x) {
  if (isNaN(x)) {
    return '-';
  }

  x = (x + '').split('.');
  return x[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g, '$1,') + (x.length > 1 ? '.' + x[1] : '');
}
/**
 * @param {string} str
 * @param {boolean} [upperCaseFirst=false]
 * @return {string} str
 */


function toCamelCase(str, upperCaseFirst) {
  str = (str || '').toLowerCase().replace(/-(.)/g, function (match, group1) {
    return group1.toUpperCase();
  });

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

  return str;
}

var normalizeCssArray = zrUtil.normalizeCssArray;
var replaceReg = /([&<>"'])/g;
var replaceMap = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  '\'': '&#39;'
};

function encodeHTML(source) {
  return source == null ? '' : (source + '').replace(replaceReg, function (str, c) {
    return replaceMap[c];
  });
}

var TPL_VAR_ALIAS = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

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


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

  var seriesLen = paramsList.length;

  if (!seriesLen) {
    return '';
  }

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

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

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

  return tpl;
}
/**
 * simple Template formatter
 *
 * @param {string} tpl
 * @param {Object} param
 * @param {boolean} [encode=false]
 * @return {string}
 */


function formatTplSimple(tpl, param, encode) {
  zrUtil.each(param, function (value, key) {
    tpl = tpl.replace('{' + key + '}', encode ? encodeHTML(value) : value);
  });
  return tpl;
}
/**
 * @param {Object|string} [opt] If string, means color.
 * @param {string} [opt.color]
 * @param {string} [opt.extraCssText]
 * @param {string} [opt.type='item'] 'item' or 'subItem'
 * @return {string}
 */


function getTooltipMarker(opt, extraCssText) {
  opt = zrUtil.isString(opt) ? {
    color: opt,
    extraCssText: extraCssText
  } : opt || {};
  var color = opt.color;
  var type = opt.type;
  var extraCssText = opt.extraCssText;

  if (!color) {
    return '';
  }

  return type === 'subItem' ? '<span style="display:inline-block;vertical-align:middle;margin-right:8px;margin-left:3px;' + 'border-radius:4px;width:4px;height:4px;background-color:' + encodeHTML(color) + ';' + (extraCssText || '') + '"></span>' : '<span style="display:inline-block;margin-right:5px;' + 'border-radius:10px;width:10px;height:10px;background-color:' + encodeHTML(color) + ';' + (extraCssText || '') + '"></span>';
}

function pad(str, len) {
  str += '';
  return '0000'.substr(0, len - str.length) + str;
}
/**
 * ISO Date format
 * @param {string} tpl
 * @param {number} value
 * @param {boolean} [isUTC=false] Default in local time.
 *           see `module:echarts/scale/Time`
 *           and `module:echarts/util/number#parseDate`.
 * @inner
 */


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

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


function capitalFirst(str) {
  return str ? str.charAt(0).toUpperCase() + str.substr(1) : str;
}

var truncateText = textContain.truncateText;
var getTextRect = textContain.getBoundingRect;
exports.addCommas = addCommas;
exports.toCamelCase = toCamelCase;
exports.normalizeCssArray = normalizeCssArray;
exports.encodeHTML = encodeHTML;
exports.formatTpl = formatTpl;
exports.formatTplSimple = formatTplSimple;
exports.getTooltipMarker = getTooltipMarker;
exports.formatTime = formatTime;
exports.capitalFirst = capitalFirst;
exports.truncateText = truncateText;
exports.getTextRect = getTextRect;

/***/ }),
/* 172 */
/***/ (function(module, exports, __webpack_require__) {

var BoundingRect = __webpack_require__(82);

var imageHelper = __webpack_require__(173);

var _util = __webpack_require__(13);

var getContext = _util.getContext;
var extend = _util.extend;
var retrieve2 = _util.retrieve2;
var retrieve3 = _util.retrieve3;
var trim = _util.trim;
var textWidthCache = {};
var textWidthCacheCounter = 0;
var TEXT_CACHE_MAX = 5000;
var STYLE_REG = /\{([a-zA-Z0-9_]+)\|([^}]*)\}/g;
var DEFAULT_FONT = '12px sans-serif'; // Avoid assign to an exported variable, for transforming to cjs.

var methods = {};

function $override(name, fn) {
  methods[name] = fn;
}
/**
 * @public
 * @param {string} text
 * @param {string} font
 * @return {number} width
 */


function getWidth(text, font) {
  font = font || DEFAULT_FONT;
  var key = text + ':' + font;

  if (textWidthCache[key]) {
    return textWidthCache[key];
  }

  var textLines = (text + '').split('\n');
  var width = 0;

  for (var i = 0, l = textLines.length; i < l; i++) {
    // textContain.measureText may be overrided in SVG or VML
    width = Math.max(measureText(textLines[i], font).width, width);
  }

  if (textWidthCacheCounter > TEXT_CACHE_MAX) {
    textWidthCacheCounter = 0;
    textWidthCache = {};
  }

  textWidthCacheCounter++;
  textWidthCache[key] = width;
  return width;
}
/**
 * @public
 * @param {string} text
 * @param {string} font
 * @param {string} [textAlign='left']
 * @param {string} [textVerticalAlign='top']
 * @param {Array.<number>} [textPadding]
 * @param {Object} [rich]
 * @param {Object} [truncate]
 * @return {Object} {x, y, width, height, lineHeight}
 */


function getBoundingRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) {
  return rich ? getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) : getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, truncate);
}

function getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, truncate) {
  var contentBlock = parsePlainText(text, font, textPadding, truncate);
  var outerWidth = getWidth(text, font);

  if (textPadding) {
    outerWidth += textPadding[1] + textPadding[3];
  }

  var outerHeight = contentBlock.outerHeight;
  var x = adjustTextX(0, outerWidth, textAlign);
  var y = adjustTextY(0, outerHeight, textVerticalAlign);
  var rect = new BoundingRect(x, y, outerWidth, outerHeight);
  rect.lineHeight = contentBlock.lineHeight;
  return rect;
}

function getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) {
  var contentBlock = parseRichText(text, {
    rich: rich,
    truncate: truncate,
    font: font,
    textAlign: textAlign,
    textPadding: textPadding
  });
  var outerWidth = contentBlock.outerWidth;
  var outerHeight = contentBlock.outerHeight;
  var x = adjustTextX(0, outerWidth, textAlign);
  var y = adjustTextY(0, outerHeight, textVerticalAlign);
  return new BoundingRect(x, y, outerWidth, outerHeight);
}
/**
 * @public
 * @param {number} x
 * @param {number} width
 * @param {string} [textAlign='left']
 * @return {number} Adjusted x.
 */


function adjustTextX(x, width, textAlign) {
  // FIXME Right to left language
  if (textAlign === 'right') {
    x -= width;
  } else if (textAlign === 'center') {
    x -= width / 2;
  }

  return x;
}
/**
 * @public
 * @param {number} y
 * @param {number} height
 * @param {string} [textVerticalAlign='top']
 * @return {number} Adjusted y.
 */


function adjustTextY(y, height, textVerticalAlign) {
  if (textVerticalAlign === 'middle') {
    y -= height / 2;
  } else if (textVerticalAlign === 'bottom') {
    y -= height;
  }

  return y;
}
/**
 * @public
 * @param {stirng} textPosition
 * @param {Object} rect {x, y, width, height}
 * @param {number} distance
 * @return {Object} {x, y, textAlign, textVerticalAlign}
 */


function adjustTextPositionOnRect(textPosition, rect, distance) {
  var x = rect.x;
  var y = rect.y;
  var height = rect.height;
  var width = rect.width;
  var halfHeight = height / 2;
  var textAlign = 'left';
  var textVerticalAlign = 'top';

  switch (textPosition) {
    case 'left':
      x -= distance;
      y += halfHeight;
      textAlign = 'right';
      textVerticalAlign = 'middle';
      break;

    case 'right':
      x += distance + width;
      y += halfHeight;
      textVerticalAlign = 'middle';
      break;

    case 'top':
      x += width / 2;
      y -= distance;
      textAlign = 'center';
      textVerticalAlign = 'bottom';
      break;

    case 'bottom':
      x += width / 2;
      y += height + distance;
      textAlign = 'center';
      break;

    case 'inside':
      x += width / 2;
      y += halfHeight;
      textAlign = 'center';
      textVerticalAlign = 'middle';
      break;

    case 'insideLeft':
      x += distance;
      y += halfHeight;
      textVerticalAlign = 'middle';
      break;

    case 'insideRight':
      x += width - distance;
      y += halfHeight;
      textAlign = 'right';
      textVerticalAlign = 'middle';
      break;

    case 'insideTop':
      x += width / 2;
      y += distance;
      textAlign = 'center';
      break;

    case 'insideBottom':
      x += width / 2;
      y += height - distance;
      textAlign = 'center';
      textVerticalAlign = 'bottom';
      break;

    case 'insideTopLeft':
      x += distance;
      y += distance;
      break;

    case 'insideTopRight':
      x += width - distance;
      y += distance;
      textAlign = 'right';
      break;

    case 'insideBottomLeft':
      x += distance;
      y += height - distance;
      textVerticalAlign = 'bottom';
      break;

    case 'insideBottomRight':
      x += width - distance;
      y += height - distance;
      textAlign = 'right';
      textVerticalAlign = 'bottom';
      break;
  }

  return {
    x: x,
    y: y,
    textAlign: textAlign,
    textVerticalAlign: textVerticalAlign
  };
}
/**
 * Show ellipsis if overflow.
 *
 * @public
 * @param  {string} text
 * @param  {string} containerWidth
 * @param  {string} font
 * @param  {number} [ellipsis='...']
 * @param  {Object} [options]
 * @param  {number} [options.maxIterations=3]
 * @param  {number} [options.minChar=0] If truncate result are less
 *                  then minChar, ellipsis will not show, which is
 *                  better for user hint in some cases.
 * @param  {number} [options.placeholder=''] When all truncated, use the placeholder.
 * @return {string}
 */


function truncateText(text, containerWidth, font, ellipsis, options) {
  if (!containerWidth) {
    return '';
  }

  var textLines = (text + '').split('\n');
  options = prepareTruncateOptions(containerWidth, font, ellipsis, options); // FIXME
  // It is not appropriate that every line has '...' when truncate multiple lines.

  for (var i = 0, len = textLines.length; i < len; i++) {
    textLines[i] = truncateSingleLine(textLines[i], options);
  }

  return textLines.join('\n');
}

function prepareTruncateOptions(containerWidth, font, ellipsis, options) {
  options = extend({}, options);
  options.font = font;
  var ellipsis = retrieve2(ellipsis, '...');
  options.maxIterations = retrieve2(options.maxIterations, 2);
  var minChar = options.minChar = retrieve2(options.minChar, 0); // FIXME
  // Other languages?

  options.cnCharWidth = getWidth('国', font); // FIXME
  // Consider proportional font?

  var ascCharWidth = options.ascCharWidth = getWidth('a', font);
  options.placeholder = retrieve2(options.placeholder, ''); // Example 1: minChar: 3, text: 'asdfzxcv', truncate result: 'asdf', but not: 'a...'.
  // Example 2: minChar: 3, text: '维度', truncate result: '维', but not: '...'.

  var contentWidth = containerWidth = Math.max(0, containerWidth - 1); // Reserve some gap.

  for (var i = 0; i < minChar && contentWidth >= ascCharWidth; i++) {
    contentWidth -= ascCharWidth;
  }

  var ellipsisWidth = getWidth(ellipsis);

  if (ellipsisWidth > contentWidth) {
    ellipsis = '';
    ellipsisWidth = 0;
  }

  contentWidth = containerWidth - ellipsisWidth;
  options.ellipsis = ellipsis;
  options.ellipsisWidth = ellipsisWidth;
  options.contentWidth = contentWidth;
  options.containerWidth = containerWidth;
  return options;
}

function truncateSingleLine(textLine, options) {
  var containerWidth = options.containerWidth;
  var font = options.font;
  var contentWidth = options.contentWidth;

  if (!containerWidth) {
    return '';
  }

  var lineWidth = getWidth(textLine, font);

  if (lineWidth <= containerWidth) {
    return textLine;
  }

  for (var j = 0;; j++) {
    if (lineWidth <= contentWidth || j >= options.maxIterations) {
      textLine += options.ellipsis;
      break;
    }

    var subLength = j === 0 ? estimateLength(textLine, contentWidth, options.ascCharWidth, options.cnCharWidth) : lineWidth > 0 ? Math.floor(textLine.length * contentWidth / lineWidth) : 0;
    textLine = textLine.substr(0, subLength);
    lineWidth = getWidth(textLine, font);
  }

  if (textLine === '') {
    textLine = options.placeholder;
  }

  return textLine;
}

function estimateLength(text, contentWidth, ascCharWidth, cnCharWidth) {
  var width = 0;
  var i = 0;

  for (var len = text.length; i < len && width < contentWidth; i++) {
    var charCode = text.charCodeAt(i);
    width += 0 <= charCode && charCode <= 127 ? ascCharWidth : cnCharWidth;
  }

  return i;
}
/**
 * @public
 * @param {string} font
 * @return {number} line height
 */


function getLineHeight(font) {
  // FIXME A rough approach.
  return getWidth('国', font);
}
/**
 * @public
 * @param {string} text
 * @param {string} font
 * @return {Object} width
 */


function measureText(text, font) {
  return methods.measureText(text, font);
} // Avoid assign to an exported variable, for transforming to cjs.


methods.measureText = function (text, font) {
  var ctx = getContext();
  ctx.font = font || DEFAULT_FONT;
  return ctx.measureText(text);
};
/**
 * @public
 * @param {string} text
 * @param {string} font
 * @param {Object} [truncate]
 * @return {Object} block: {lineHeight, lines, height, outerHeight}
 *  Notice: for performance, do not calculate outerWidth util needed.
 */


function parsePlainText(text, font, padding, truncate) {
  text != null && (text += '');
  var lineHeight = getLineHeight(font);
  var lines = text ? text.split('\n') : [];
  var height = lines.length * lineHeight;
  var outerHeight = height;

  if (padding) {
    outerHeight += padding[0] + padding[2];
  }

  if (text && truncate) {
    var truncOuterHeight = truncate.outerHeight;
    var truncOuterWidth = truncate.outerWidth;

    if (truncOuterHeight != null && outerHeight > truncOuterHeight) {
      text = '';
      lines = [];
    } else if (truncOuterWidth != null) {
      var options = prepareTruncateOptions(truncOuterWidth - (padding ? padding[1] + padding[3] : 0), font, truncate.ellipsis, {
        minChar: truncate.minChar,
        placeholder: truncate.placeholder
      }); // FIXME
      // It is not appropriate that every line has '...' when truncate multiple lines.

      for (var i = 0, len = lines.length; i < len; i++) {
        lines[i] = truncateSingleLine(lines[i], options);
      }
    }
  }

  return {
    lines: lines,
    height: height,
    outerHeight: outerHeight,
    lineHeight: lineHeight
  };
}
/**
 * For example: 'some text {a|some text}other text{b|some text}xxx{c|}xxx'
 * Also consider 'bbbb{a|xxx\nzzz}xxxx\naaaa'.
 *
 * @public
 * @param {string} text
 * @param {Object} style
 * @return {Object} block
 * {
 *      width,
 *      height,
 *      lines: [{
 *          lineHeight,
 *          width,
 *          tokens: [[{
 *              styleName,
 *              text,
 *              width,      // include textPadding
 *              height,     // include textPadding
 *              textWidth, // pure text width
 *              textHeight, // pure text height
 *              lineHeihgt,
 *              font,
 *              textAlign,
 *              textVerticalAlign
 *          }], [...], ...]
 *      }, ...]
 * }
 * If styleName is undefined, it is plain text.
 */


function parseRichText(text, style) {
  var contentBlock = {
    lines: [],
    width: 0,
    height: 0
  };
  text != null && (text += '');

  if (!text) {
    return contentBlock;
  }

  var lastIndex = STYLE_REG.lastIndex = 0;
  var result;

  while ((result = STYLE_REG.exec(text)) != null) {
    var matchedIndex = result.index;

    if (matchedIndex > lastIndex) {
      pushTokens(contentBlock, text.substring(lastIndex, matchedIndex));
    }

    pushTokens(contentBlock, result[2], result[1]);
    lastIndex = STYLE_REG.lastIndex;
  }

  if (lastIndex < text.length) {
    pushTokens(contentBlock, text.substring(lastIndex, text.length));
  }

  var lines = contentBlock.lines;
  var contentHeight = 0;
  var contentWidth = 0; // For `textWidth: 100%`

  var pendingList = [];
  var stlPadding = style.textPadding;
  var truncate = style.truncate;
  var truncateWidth = truncate && truncate.outerWidth;
  var truncateHeight = truncate && truncate.outerHeight;

  if (stlPadding) {
    truncateWidth != null && (truncateWidth -= stlPadding[1] + stlPadding[3]);
    truncateHeight != null && (truncateHeight -= stlPadding[0] + stlPadding[2]);
  } // Calculate layout info of tokens.


  for (var i = 0; i < lines.length; i++) {
    var line = lines[i];
    var lineHeight = 0;
    var lineWidth = 0;

    for (var j = 0; j < line.tokens.length; j++) {
      var token = line.tokens[j];
      var tokenStyle = token.styleName && style.rich[token.styleName] || {}; // textPadding should not inherit from style.

      var textPadding = token.textPadding = tokenStyle.textPadding; // textFont has been asigned to font by `normalizeStyle`.

      var font = token.font = tokenStyle.font || style.font; // textHeight can be used when textVerticalAlign is specified in token.

      var tokenHeight = token.textHeight = retrieve2( // textHeight should not be inherited, consider it can be specified
      // as box height of the block.
      tokenStyle.textHeight, getLineHeight(font));
      textPadding && (tokenHeight += textPadding[0] + textPadding[2]);
      token.height = tokenHeight;
      token.lineHeight = retrieve3(tokenStyle.textLineHeight, style.textLineHeight, tokenHeight);
      token.textAlign = tokenStyle && tokenStyle.textAlign || style.textAlign;
      token.textVerticalAlign = tokenStyle && tokenStyle.textVerticalAlign || 'middle';

      if (truncateHeight != null && contentHeight + token.lineHeight > truncateHeight) {
        return {
          lines: [],
          width: 0,
          height: 0
        };
      }

      token.textWidth = getWidth(token.text, font);
      var tokenWidth = tokenStyle.textWidth;
      var tokenWidthNotSpecified = tokenWidth == null || tokenWidth === 'auto'; // Percent width, can be `100%`, can be used in drawing separate
      // line when box width is needed to be auto.

      if (typeof tokenWidth === 'string' && tokenWidth.charAt(tokenWidth.length - 1) === '%') {
        token.percentWidth = tokenWidth;
        pendingList.push(token);
        tokenWidth = 0; // Do not truncate in this case, because there is no user case
        // and it is too complicated.
      } else {
        if (tokenWidthNotSpecified) {
          tokenWidth = token.textWidth; // FIXME: If image is not loaded and textWidth is not specified, calling
          // `getBoundingRect()` will not get correct result.

          var textBackgroundColor = tokenStyle.textBackgroundColor;
          var bgImg = textBackgroundColor && textBackgroundColor.image; // Use cases:
          // (1) If image is not loaded, it will be loaded at render phase and call
          // `dirty()` and `textBackgroundColor.image` will be replaced with the loaded
          // image, and then the right size will be calculated here at the next tick.
          // See `graphic/helper/text.js`.
          // (2) If image loaded, and `textBackgroundColor.image` is image src string,
          // use `imageHelper.findExistImage` to find cached image.
          // `imageHelper.findExistImage` will always be called here before
          // `imageHelper.createOrUpdateImage` in `graphic/helper/text.js#renderRichText`
          // which ensures that image will not be rendered before correct size calcualted.

          if (bgImg) {
            bgImg = imageHelper.findExistImage(bgImg);

            if (imageHelper.isImageReady(bgImg)) {
              tokenWidth = Math.max(tokenWidth, bgImg.width * tokenHeight / bgImg.height);
            }
          }
        }

        var paddingW = textPadding ? textPadding[1] + textPadding[3] : 0;
        tokenWidth += paddingW;
        var remianTruncWidth = truncateWidth != null ? truncateWidth - lineWidth : null;

        if (remianTruncWidth != null && remianTruncWidth < tokenWidth) {
          if (!tokenWidthNotSpecified || remianTruncWidth < paddingW) {
            token.text = '';
            token.textWidth = tokenWidth = 0;
          } else {
            token.text = truncateText(token.text, remianTruncWidth - paddingW, font, truncate.ellipsis, {
              minChar: truncate.minChar
            });
            token.textWidth = getWidth(token.text, font);
            tokenWidth = token.textWidth + paddingW;
          }
        }
      }

      lineWidth += token.width = tokenWidth;
      tokenStyle && (lineHeight = Math.max(lineHeight, token.lineHeight));
    }

    line.width = lineWidth;
    line.lineHeight = lineHeight;
    contentHeight += lineHeight;
    contentWidth = Math.max(contentWidth, lineWidth);
  }

  contentBlock.outerWidth = contentBlock.width = retrieve2(style.textWidth, contentWidth);
  contentBlock.outerHeight = contentBlock.height = retrieve2(style.textHeight, contentHeight);

  if (stlPadding) {
    contentBlock.outerWidth += stlPadding[1] + stlPadding[3];
    contentBlock.outerHeight += stlPadding[0] + stlPadding[2];
  }

  for (var i = 0; i < pendingList.length; i++) {
    var token = pendingList[i];
    var percentWidth = token.percentWidth; // Should not base on outerWidth, because token can not be placed out of padding.

    token.width = parseInt(percentWidth, 10) / 100 * contentWidth;
  }

  return contentBlock;
}

function pushTokens(block, str, styleName) {
  var isEmptyStr = str === '';
  var strs = str.split('\n');
  var lines = block.lines;

  for (var i = 0; i < strs.length; i++) {
    var text = strs[i];
    var token = {
      styleName: styleName,
      text: text,
      isLineHolder: !text && !isEmptyStr
    }; // The first token should be appended to the last line.

    if (!i) {
      var tokens = (lines[lines.length - 1] || (lines[0] = {
        tokens: []
      })).tokens; // Consider cases:
      // (1) ''.split('\n') => ['', '\n', ''], the '' at the first item
      // (which is a placeholder) should be replaced by new token.
      // (2) A image backage, where token likes {a|}.
      // (3) A redundant '' will affect textAlign in line.
      // (4) tokens with the same tplName should not be merged, because
      // they should be displayed in different box (with border and padding).

      var tokensLen = tokens.length;
      tokensLen === 1 && tokens[0].isLineHolder ? tokens[0] = token : // Consider text is '', only insert when it is the "lineHolder" or
      // "emptyStr". Otherwise a redundant '' will affect textAlign in line.
      (text || !tokensLen || isEmptyStr) && tokens.push(token);
    } // Other tokens always start a new line.
    else {
        // If there is '', insert it as a placeholder.
        lines.push({
          tokens: [token]
        });
      }
  }
}

function makeFont(style) {
  // FIXME in node-canvas fontWeight is before fontStyle
  // Use `fontSize` `fontFamily` to check whether font properties are defined.
  var font = (style.fontSize || style.fontFamily) && [style.fontStyle, style.fontWeight, (style.fontSize || 12) + 'px', // If font properties are defined, `fontFamily` should not be ignored.
  style.fontFamily || 'sans-serif'].join(' ');
  return font && trim(font) || style.textFont || style.font;
}

exports.DEFAULT_FONT = DEFAULT_FONT;
exports.$override = $override;
exports.getWidth = getWidth;
exports.getBoundingRect = getBoundingRect;
exports.adjustTextX = adjustTextX;
exports.adjustTextY = adjustTextY;
exports.adjustTextPositionOnRect = adjustTextPositionOnRect;
exports.truncateText = truncateText;
exports.getLineHeight = getLineHeight;
exports.measureText = measureText;
exports.parsePlainText = parsePlainText;
exports.parseRichText = parseRichText;
exports.makeFont = makeFont;

/***/ }),
/* 173 */
/***/ (function(module, exports, __webpack_require__) {

var LRU = __webpack_require__(60);

var globalImageCache = new LRU(50);
/**
 * @param {string|HTMLImageElement|HTMLCanvasElement|Canvas} newImageOrSrc
 * @return {HTMLImageElement|HTMLCanvasElement|Canvas} image
 */

function findExistImage(newImageOrSrc) {
  if (typeof newImageOrSrc === 'string') {
    var cachedImgObj = globalImageCache.get(newImageOrSrc);
    return cachedImgObj && cachedImgObj.image;
  } else {
    return newImageOrSrc;
  }
}
/**
 * Caution: User should cache loaded images, but not just count on LRU.
 * Consider if required images more than LRU size, will dead loop occur?
 *
 * @param {string|HTMLImageElement|HTMLCanvasElement|Canvas} newImageOrSrc
 * @param {HTMLImageElement|HTMLCanvasElement|Canvas} image Existent image.
 * @param {module:zrender/Element} [hostEl] For calling `dirty`.
 * @param {Function} [cb] params: (image, cbPayload)
 * @param {Object} [cbPayload] Payload on cb calling.
 * @return {HTMLImageElement|HTMLCanvasElement|Canvas} image
 */


function createOrUpdateImage(newImageOrSrc, image, hostEl, cb, cbPayload) {
  if (!newImageOrSrc) {
    return image;
  } else if (typeof newImageOrSrc === 'string') {
    // Image should not be loaded repeatly.
    if (image && image.__zrImageSrc === newImageOrSrc || !hostEl) {
      return image;
    } // Only when there is no existent image or existent image src
    // is different, this method is responsible for load.


    var cachedImgObj = globalImageCache.get(newImageOrSrc);
    var pendingWrap = {
      hostEl: hostEl,
      cb: cb,
      cbPayload: cbPayload
    };

    if (cachedImgObj) {
      image = cachedImgObj.image;
      !isImageReady(image) && cachedImgObj.pending.push(pendingWrap);
    } else {
      !image && (image = new Image());
      image.onload = imageOnLoad;
      globalImageCache.put(newImageOrSrc, image.__cachedImgObj = {
        image: image,
        pending: [pendingWrap]
      });
      image.src = image.__zrImageSrc = newImageOrSrc;
    }

    return image;
  } // newImageOrSrc is an HTMLImageElement or HTMLCanvasElement or Canvas
  else {
      return newImageOrSrc;
    }
}

function imageOnLoad() {
  var cachedImgObj = this.__cachedImgObj;
  this.onload = this.__cachedImgObj = null;

  for (var i = 0; i < cachedImgObj.pending.length; i++) {
    var pendingWrap = cachedImgObj.pending[i];
    var cb = pendingWrap.cb;
    cb && cb(this, pendingWrap.cbPayload);
    pendingWrap.hostEl.dirty();
  }

  cachedImgObj.pending.length = 0;
}

function isImageReady(image) {
  return image && image.width && image.height;
}

exports.findExistImage = findExistImage;
exports.createOrUpdateImage = createOrUpdateImage;
exports.isImageReady = isImageReady;

/***/ }),
/* 174 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__math_Frustum__ = __webpack_require__(59);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__Renderer__ = __webpack_require__(52);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Material__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__TextureCube__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__ = __webpack_require__(41);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__camera_Orthographic__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__compositor_Pass__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__compositor_TexturePool__ = __webpack_require__(86);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__glmatrix_mat4__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__shader_source_shadowmap_glsl_js__ = __webpack_require__(175);





















var targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz'];


__WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_18__shader_source_shadowmap_glsl_js__["a" /* default */]);

function getDepthMaterialUniform(renderable, depthMaterial, symbol) {
    if (symbol === 'alphaMap') {
        return renderable.material.get('diffuseMap');
    }
    else if (symbol === 'alphaCutoff') {
        if (renderable.material.isDefined('fragment', 'ALPHA_TEST')
            && renderable.material.get('diffuseMap')
        ) {
            var alphaCutoff = renderable.material.get('alphaCutoff');
            return alphaCutoff || 0;
        }
        return 0;
    }
    else {
        return depthMaterial.get(symbol);
    }
}

function isDepthMaterialChanged(renderable, prevRenderable) {
    var matA = renderable.material;
    var matB = prevRenderable.material;
    return matA.get('diffuseMap') !== matB.get('diffuseMap')
        || (matA.get('alphaCutoff') || 0) !== (matB.get('alphaCutoff') || 0);
}

/**
 * Pass rendering shadow map.
 *
 * @constructor clay.prePass.ShadowMap
 * @extends clay.core.Base
 * @example
 *     var shadowMapPass = new clay.prePass.ShadowMap({
 *         softShadow: clay.prePass.ShadowMap.VSM
 *     });
 *     ...
 *     animation.on('frame', function (frameTime) {
 *         shadowMapPass.render(renderer, scene, camera);
 *         renderer.render(scene, camera);
 *     });
 */
var ShadowMapPass = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
    return /** @lends clay.prePass.ShadowMap# */ {
        /**
         * Soft shadow technique.
         * Can be {@link clay.prePass.ShadowMap.PCF} or {@link clay.prePass.ShadowMap.VSM}
         * @type {number}
         */
        softShadow: ShadowMapPass.PCF,

        /**
         * Soft shadow blur size
         * @type {number}
         */
        shadowBlur: 1.0,

        lightFrustumBias: 'auto',

        kernelPCF: new Float32Array([
            1, 0,
            1, 1,
            -1, 1,
            0, 1,
            -1, 0,
            -1, -1,
            1, -1,
            0, -1
        ]),

        precision: 'highp',

        _lastRenderNotCastShadow: false,

        _frameBuffer: new __WEBPACK_IMPORTED_MODULE_9__FrameBuffer__["a" /* default */](),

        _textures: {},
        _shadowMapNumber: {
            'POINT_LIGHT': 0,
            'DIRECTIONAL_LIGHT': 0,
            'SPOT_LIGHT': 0
        },

        _depthMaterials: {},
        _distanceMaterials: {},

        _receivers: [],
        _lightsCastShadow: [],

        _lightCameras: {},
        _lightMaterials: {},

        _texturePool: new __WEBPACK_IMPORTED_MODULE_16__compositor_TexturePool__["a" /* default */]()
    };
}, function () {
    // Gaussian filter pass for VSM
    this._gaussianPassH = new __WEBPACK_IMPORTED_MODULE_15__compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */].source('clay.compositor.gaussian_blur')
    });
    this._gaussianPassV = new __WEBPACK_IMPORTED_MODULE_15__compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */].source('clay.compositor.gaussian_blur')
    });
    this._gaussianPassH.setUniform('blurSize', this.shadowBlur);
    this._gaussianPassH.setUniform('blurDir', 0.0);
    this._gaussianPassV.setUniform('blurSize', this.shadowBlur);
    this._gaussianPassV.setUniform('blurDir', 1.0);

    this._outputDepthPass = new __WEBPACK_IMPORTED_MODULE_15__compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */].source('clay.sm.debug_depth')
    });
}, {
    /**
     * Render scene to shadow textures
     * @param  {clay.Renderer} renderer
     * @param  {clay.Scene} scene
     * @param  {clay.Camera} sceneCamera
     * @param  {boolean} [notUpdateScene=false]
     * @memberOf clay.prePass.ShadowMap.prototype
     */
    render: function (renderer, scene, sceneCamera, notUpdateScene) {
        if (!sceneCamera) {
            sceneCamera = scene.getMainCamera();
        }
        this.trigger('beforerender', this, renderer, scene, sceneCamera);
        this._renderShadowPass(renderer, scene, sceneCamera, notUpdateScene);
        this.trigger('afterrender', this, renderer, scene, sceneCamera);
    },

    /**
     * Debug rendering of shadow textures
     * @param  {clay.Renderer} renderer
     * @param  {number} size
     * @memberOf clay.prePass.ShadowMap.prototype
     */
    renderDebug: function (renderer, size) {
        renderer.saveClear();
        var viewport = renderer.viewport;
        var x = 0, y = 0;
        var width = size || viewport.width / 4;
        var height = width;
        if (this.softShadow === ShadowMapPass.VSM) {
            this._outputDepthPass.material.define('fragment', 'USE_VSM');
        }
        else {
            this._outputDepthPass.material.undefine('fragment', 'USE_VSM');
        }
        for (var name in this._textures) {
            var texture = this._textures[name];
            renderer.setViewport(x, y, width * texture.width / texture.height, height);
            this._outputDepthPass.setUniform('depthMap', texture);
            this._outputDepthPass.render(renderer);
            x += width * texture.width / texture.height;
        }
        renderer.setViewport(viewport);
        renderer.restoreClear();
    },

    _updateReceivers: function (renderer, mesh) {
        if (mesh.receiveShadow) {
            this._receivers.push(mesh);
            mesh.material.set('shadowEnabled', 1);

            mesh.material.set('pcfKernel', this.kernelPCF);
        }
        else {
            mesh.material.set('shadowEnabled', 0);
        }

        if (this.softShadow === ShadowMapPass.VSM) {
            mesh.material.define('fragment', 'USE_VSM');
            mesh.material.undefine('fragment', 'PCF_KERNEL_SIZE');
        }
        else {
            mesh.material.undefine('fragment', 'USE_VSM');
            var kernelPCF = this.kernelPCF;
            if (kernelPCF && kernelPCF.length) {
                mesh.material.define('fragment', 'PCF_KERNEL_SIZE', kernelPCF.length / 2);
            }
            else {
                mesh.material.undefine('fragment', 'PCF_KERNEL_SIZE');
            }
        }
    },

    _update: function (renderer, scene) {
        var self = this;
        scene.traverse(function (renderable) {
            if (renderable.isRenderable()) {
                self._updateReceivers(renderer, renderable);
            }
        });

        for (var i = 0; i < scene.lights.length; i++) {
            var light = scene.lights[i];
            if (light.castShadow && !light.invisible) {
                this._lightsCastShadow.push(light);
            }
        }
    },

    _renderShadowPass: function (renderer, scene, sceneCamera, notUpdateScene) {
        // reset
        for (var name in this._shadowMapNumber) {
            this._shadowMapNumber[name] = 0;
        }
        this._lightsCastShadow.length = 0;
        this._receivers.length = 0;

        var _gl = renderer.gl;

        if (!notUpdateScene) {
            scene.update();
        }
        if (sceneCamera) {
            sceneCamera.update();
        }

        scene.updateLights();
        this._update(renderer, scene);

        // Needs to update the receivers again if shadows come from 1 to 0.
        if (!this._lightsCastShadow.length && this._lastRenderNotCastShadow) {
            return;
        }

        this._lastRenderNotCastShadow = this._lightsCastShadow === 0;

        _gl.enable(_gl.DEPTH_TEST);
        _gl.depthMask(true);
        _gl.disable(_gl.BLEND);

        // Clear with high-z, so the part not rendered will not been shadowed
        // TODO
        // TODO restore
        _gl.clearColor(1.0, 1.0, 1.0, 1.0);

        // Shadow uniforms
        var spotLightShadowMaps = [];
        var spotLightMatrices = [];
        var directionalLightShadowMaps = [];
        var directionalLightMatrices = [];
        var shadowCascadeClips = [];
        var pointLightShadowMaps = [];

        var dirLightHasCascade;
        // Create textures for shadow map
        for (var i = 0; i < this._lightsCastShadow.length; i++) {
            var light = this._lightsCastShadow[i];
            if (light.type === 'DIRECTIONAL_LIGHT') {

                if (dirLightHasCascade) {
                    console.warn('Only one direectional light supported with shadow cascade');
                    continue;
                }
                if (light.shadowCascade > 4) {
                    console.warn('Support at most 4 cascade');
                    continue;
                }
                if (light.shadowCascade > 1) {
                    dirLightHasCascade = light;
                }

                this.renderDirectionalLightShadow(
                    renderer,
                    scene,
                    sceneCamera,
                    light,
                    shadowCascadeClips,
                    directionalLightMatrices,
                    directionalLightShadowMaps
                );
            }
            else if (light.type === 'SPOT_LIGHT') {
                this.renderSpotLightShadow(
                    renderer,
                    scene,
                    light,
                    spotLightMatrices,
                    spotLightShadowMaps
                );
            }
            else if (light.type === 'POINT_LIGHT') {
                this.renderPointLightShadow(
                    renderer,
                    scene,
                    light,
                    pointLightShadowMaps
                );
            }

            this._shadowMapNumber[light.type]++;
        }

        for (var lightType in this._shadowMapNumber) {
            var number = this._shadowMapNumber[lightType];
            var key = lightType + '_SHADOWMAP_COUNT';
            for (var i = 0; i < this._receivers.length; i++) {
                var mesh = this._receivers[i];
                var material = mesh.material;
                if (material.fragmentDefines[key] !== number) {
                    if (number > 0) {
                        material.define('fragment', key, number);
                    }
                    else if (material.isDefined('fragment', key)) {
                        material.undefine('fragment', key);
                    }
                }
            }
        }
        for (var i = 0; i < this._receivers.length; i++) {
            var mesh = this._receivers[i];
            var material = mesh.material;
            if (dirLightHasCascade) {
                material.define('fragment', 'SHADOW_CASCADE', dirLightHasCascade.shadowCascade);
            }
            else {
                material.undefine('fragment', 'SHADOW_CASCADE');
            }
        }

        var shadowUniforms = scene.shadowUniforms;

        function getSize(texture) {
            return texture.height;
        }
        if (directionalLightShadowMaps.length > 0) {
            var directionalLightShadowMapSizes = directionalLightShadowMaps.map(getSize);
            shadowUniforms.directionalLightShadowMaps = { value: directionalLightShadowMaps, type: 'tv' };
            shadowUniforms.directionalLightMatrices = { value: directionalLightMatrices, type: 'm4v' };
            shadowUniforms.directionalLightShadowMapSizes = { value: directionalLightShadowMapSizes, type: '1fv' };
            if (dirLightHasCascade) {
                var shadowCascadeClipsNear = shadowCascadeClips.slice();
                var shadowCascadeClipsFar = shadowCascadeClips.slice();
                shadowCascadeClipsNear.pop();
                shadowCascadeClipsFar.shift();

                // Iterate from far to near
                shadowCascadeClipsNear.reverse();
                shadowCascadeClipsFar.reverse();
                // directionalLightShadowMaps.reverse();
                directionalLightMatrices.reverse();
                shadowUniforms.shadowCascadeClipsNear = { value: shadowCascadeClipsNear, type: '1fv' };
                shadowUniforms.shadowCascadeClipsFar = { value: shadowCascadeClipsFar, type: '1fv' };
            }
        }

        if (spotLightShadowMaps.length > 0) {
            var spotLightShadowMapSizes = spotLightShadowMaps.map(getSize);
            var shadowUniforms = scene.shadowUniforms;
            shadowUniforms.spotLightShadowMaps = { value: spotLightShadowMaps, type: 'tv' };
            shadowUniforms.spotLightMatrices = { value: spotLightMatrices, type: 'm4v' };
            shadowUniforms.spotLightShadowMapSizes = { value: spotLightShadowMapSizes, type: '1fv' };
        }

        if (pointLightShadowMaps.length > 0) {
            shadowUniforms.pointLightShadowMaps = { value: pointLightShadowMaps, type: 'tv' };
        }
    },

    renderDirectionalLightShadow: (function () {

        var splitFrustum = new __WEBPACK_IMPORTED_MODULE_4__math_Frustum__["a" /* default */]();
        var splitProjMatrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
        var cropBBox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
        var cropMatrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
        var lightViewMatrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
        var lightViewProjMatrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
        var lightProjMatrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();

        return function (renderer, scene, sceneCamera, light, shadowCascadeClips, directionalLightMatrices, directionalLightShadowMaps) {

            var defaultShadowMaterial = this._getDepthMaterial(light);
            var passConfig = {
                getMaterial: function (renderable) {
                    return renderable.shadowDepthMaterial || defaultShadowMaterial;
                },
                isMaterialChanged: isDepthMaterialChanged,
                getUniform: getDepthMaterialUniform,
                ifRender: function (renderable) {
                    return renderable.castShadow;
                },
                sortCompare: __WEBPACK_IMPORTED_MODULE_6__Renderer__["a" /* default */].opaqueSortCompare
            };

            // First frame
            if (!scene.viewBoundingBoxLastFrame.isFinite()) {
                var boundingBox = scene.getBoundingBox();
                scene.viewBoundingBoxLastFrame
                    .copy(boundingBox).applyTransform(sceneCamera.viewMatrix);
            }
            // Considering moving speed since the bounding box is from last frame
            // TODO: add a bias
            var clippedFar = Math.min(-scene.viewBoundingBoxLastFrame.min.z, sceneCamera.far);
            var clippedNear = Math.max(-scene.viewBoundingBoxLastFrame.max.z, sceneCamera.near);

            var lightCamera = this._getDirectionalLightCamera(light, scene, sceneCamera);

            var lvpMat4Arr = lightViewProjMatrix.array;
            lightProjMatrix.copy(lightCamera.projectionMatrix);
            __WEBPACK_IMPORTED_MODULE_17__glmatrix_mat4__["a" /* default */].invert(lightViewMatrix.array, lightCamera.worldTransform.array);
            __WEBPACK_IMPORTED_MODULE_17__glmatrix_mat4__["a" /* default */].multiply(lightViewMatrix.array, lightViewMatrix.array, sceneCamera.worldTransform.array);
            __WEBPACK_IMPORTED_MODULE_17__glmatrix_mat4__["a" /* default */].multiply(lvpMat4Arr, lightProjMatrix.array, lightViewMatrix.array);

            var clipPlanes = [];
            var isPerspective = sceneCamera instanceof __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */];

            var scaleZ = (sceneCamera.near + sceneCamera.far) / (sceneCamera.near - sceneCamera.far);
            var offsetZ = 2 * sceneCamera.near * sceneCamera.far / (sceneCamera.near - sceneCamera.far);
            for (var i = 0; i <= light.shadowCascade; i++) {
                var clog = clippedNear * Math.pow(clippedFar / clippedNear, i / light.shadowCascade);
                var cuni = clippedNear + (clippedFar - clippedNear) * i / light.shadowCascade;
                var c = clog * light.cascadeSplitLogFactor + cuni * (1 - light.cascadeSplitLogFactor);
                clipPlanes.push(c);
                shadowCascadeClips.push(-(-c * scaleZ + offsetZ) / -c);
            }
            var texture = this._getTexture(light, light.shadowCascade);
            directionalLightShadowMaps.push(texture);

            var viewport = renderer.viewport;

            var _gl = renderer.gl;
            this._frameBuffer.attach(texture);
            this._frameBuffer.bind(renderer);
            _gl.clear(_gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT);

            for (var i = 0; i < light.shadowCascade; i++) {
                // Get the splitted frustum
                var nearPlane = clipPlanes[i];
                var farPlane = clipPlanes[i + 1];
                if (isPerspective) {
                    __WEBPACK_IMPORTED_MODULE_17__glmatrix_mat4__["a" /* default */].perspective(splitProjMatrix.array, sceneCamera.fov / 180 * Math.PI, sceneCamera.aspect, nearPlane, farPlane);
                }
                else {
                    __WEBPACK_IMPORTED_MODULE_17__glmatrix_mat4__["a" /* default */].ortho(
                        splitProjMatrix.array,
                        sceneCamera.left, sceneCamera.right, sceneCamera.bottom, sceneCamera.top,
                        nearPlane, farPlane
                    );
                }
                splitFrustum.setFromProjection(splitProjMatrix);
                splitFrustum.getTransformedBoundingBox(cropBBox, lightViewMatrix);
                cropBBox.applyProjection(lightProjMatrix);
                var _min = cropBBox.min.array;
                var _max = cropBBox.max.array;
                _min[0] = Math.max(_min[0], -1);
                _min[1] = Math.max(_min[1], -1);
                _max[0] = Math.min(_max[0], 1);
                _max[1] = Math.min(_max[1], 1);
                cropMatrix.ortho(_min[0], _max[0], _min[1], _max[1], 1, -1);
                lightCamera.projectionMatrix.multiplyLeft(cropMatrix);

                var shadowSize = light.shadowResolution || 512;

                // Reversed, left to right => far to near
                renderer.setViewport((light.shadowCascade - i - 1) * shadowSize, 0, shadowSize, shadowSize, 1);

                var renderList = scene.updateRenderList(lightCamera);
                renderer.renderPass(renderList.opaque, lightCamera, passConfig);

                // Filter for VSM
                if (this.softShadow === ShadowMapPass.VSM) {
                    this._gaussianFilter(renderer, texture, texture.width);
                }

                var matrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
                matrix.copy(lightCamera.viewMatrix)
                    .multiplyLeft(lightCamera.projectionMatrix);

                directionalLightMatrices.push(matrix.array);

                lightCamera.projectionMatrix.copy(lightProjMatrix);
            }

            this._frameBuffer.unbind(renderer);

            renderer.setViewport(viewport);
        };
    })(),

    renderSpotLightShadow: function (renderer, scene, light, spotLightMatrices, spotLightShadowMaps) {

        var texture = this._getTexture(light);
        var lightCamera = this._getSpotLightCamera(light);
        var _gl = renderer.gl;

        this._frameBuffer.attach(texture);
        this._frameBuffer.bind(renderer);

        _gl.clear(_gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT);

        var defaultShadowMaterial = this._getDepthMaterial(light);
        var passConfig = {
            getMaterial: function (renderable) {
                return renderable.shadowDepthMaterial || defaultShadowMaterial;
            },
            isMaterialChanged: isDepthMaterialChanged,
            getUniform: getDepthMaterialUniform,
            ifRender: function (renderable) {
                return renderable.castShadow;
            },
            sortCompare: __WEBPACK_IMPORTED_MODULE_6__Renderer__["a" /* default */].opaqueSortCompare
        };

        var renderList = scene.updateRenderList(lightCamera);
        renderer.renderPass(renderList.opaque, lightCamera, passConfig);

        this._frameBuffer.unbind(renderer);

        // Filter for VSM
        if (this.softShadow === ShadowMapPass.VSM) {
            this._gaussianFilter(renderer, texture, texture.width);
        }

        var matrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
        matrix.copy(lightCamera.worldTransform)
            .invert()
            .multiplyLeft(lightCamera.projectionMatrix);

        spotLightShadowMaps.push(texture);
        spotLightMatrices.push(matrix.array);
    },

    renderPointLightShadow: function (renderer, scene, light, pointLightShadowMaps) {
        var texture = this._getTexture(light);
        var _gl = renderer.gl;
        pointLightShadowMaps.push(texture);

        var defaultShadowMaterial = this._getDepthMaterial(light);
        var passConfig = {
            getMaterial: function (renderable) {
                return renderable.shadowDepthMaterial || defaultShadowMaterial;
            },
            getUniform: getDepthMaterialUniform,
            sortCompare: __WEBPACK_IMPORTED_MODULE_6__Renderer__["a" /* default */].opaqueSortCompare
        };

        var renderListEachSide = {
            px: [], py: [], pz: [], nx: [], ny: [], nz: []
        };
        var bbox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
        var lightWorldPosition = light.getWorldPosition().array;
        var lightBBox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
        var range = light.range;
        lightBBox.min.setArray(lightWorldPosition);
        lightBBox.max.setArray(lightWorldPosition);
        var extent = new __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */](range, range, range);
        lightBBox.max.add(extent);
        lightBBox.min.sub(extent);

        var targetsNeedRender = { px: false, py: false, pz: false, nx: false, ny: false, nz: false };
        scene.traverse(function (renderable) {
            if (renderable.isRenderable() && renderable.castShadow) {
                var geometry = renderable.geometry;
                if (!geometry.boundingBox) {
                    for (var i = 0; i < targets.length; i++) {
                        renderListEachSide[targets[i]].push(renderable);
                    }
                    return;
                }
                bbox.transformFrom(geometry.boundingBox, renderable.worldTransform);
                if (!bbox.intersectBoundingBox(lightBBox)) {
                    return;
                }

                bbox.updateVertices();
                for (var i = 0; i < targets.length; i++) {
                    targetsNeedRender[targets[i]] = false;
                }
                for (var i = 0; i < 8; i++) {
                    var vtx = bbox.vertices[i];
                    var x = vtx[0] - lightWorldPosition[0];
                    var y = vtx[1] - lightWorldPosition[1];
                    var z = vtx[2] - lightWorldPosition[2];
                    var absx = Math.abs(x);
                    var absy = Math.abs(y);
                    var absz = Math.abs(z);
                    if (absx > absy) {
                        if (absx > absz) {
                            targetsNeedRender[x > 0 ? 'px' : 'nx'] = true;
                        }
                        else {
                            targetsNeedRender[z > 0 ? 'pz' : 'nz'] = true;
                        }
                    }
                    else {
                        if (absy > absz) {
                            targetsNeedRender[y > 0 ? 'py' : 'ny'] = true;
                        }
                        else {
                            targetsNeedRender[z > 0 ? 'pz' : 'nz'] = true;
                        }
                    }
                }
                for (var i = 0; i < targets.length; i++) {
                    if (targetsNeedRender[targets[i]]) {
                        renderListEachSide[targets[i]].push(renderable);
                    }
                }
            }
        });

        for (var i = 0; i < 6; i++) {
            var target = targets[i];
            var camera = this._getPointLightCamera(light, target);

            this._frameBuffer.attach(texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i);
            this._frameBuffer.bind(renderer);
            _gl.clear(_gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT);

            renderer.renderPass(renderListEachSide[target], camera, passConfig);
        }

        this._frameBuffer.unbind(renderer);
    },

    _getDepthMaterial: function (light) {
        var shadowMaterial = this._lightMaterials[light.__uid__];
        var isPointLight = light.type === 'POINT_LIGHT';
        if (!shadowMaterial) {
            var shaderPrefix = isPointLight ? 'clay.sm.distance.' : 'clay.sm.depth.';
            shadowMaterial = new __WEBPACK_IMPORTED_MODULE_8__Material__["a" /* default */]({
                precision: this.precision,
                shader: new __WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */](__WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */].source(shaderPrefix + 'vertex'), __WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */].source(shaderPrefix + 'fragment'))
            });

            this._lightMaterials[light.__uid__] = shadowMaterial;
        }
        if (light.shadowSlopeScale != null) {
            shadowMaterial.setUniform('slopeScale', light.shadowSlopeScale);
        }
        if (light.shadowBias != null) {
            shadowMaterial.setUniform('bias', light.shadowBias);
        }
        if (this.softShadow === ShadowMapPass.VSM) {
            shadowMaterial.define('fragment', 'USE_VSM');
        }
        else {
            shadowMaterial.undefine('fragment', 'USE_VSM');
        }

        if (isPointLight) {
            shadowMaterial.set('lightPosition', light.getWorldPosition().array);
            shadowMaterial.set('range', light.range);
        }

        return shadowMaterial;
    },

    _gaussianFilter: function (renderer, texture, size) {
        var parameter = {
            width: size,
            height: size,
            type: __WEBPACK_IMPORTED_MODULE_10__Texture__["a" /* default */].FLOAT
        };
        var tmpTexture = this._texturePool.get(parameter);

        this._frameBuffer.attach(tmpTexture);
        this._frameBuffer.bind(renderer);
        this._gaussianPassH.setUniform('texture', texture);
        this._gaussianPassH.setUniform('textureWidth', size);
        this._gaussianPassH.render(renderer);

        this._frameBuffer.attach(texture);
        this._gaussianPassV.setUniform('texture', tmpTexture);
        this._gaussianPassV.setUniform('textureHeight', size);
        this._gaussianPassV.render(renderer);
        this._frameBuffer.unbind(renderer);

        this._texturePool.put(tmpTexture);
    },

    _getTexture: function (light, cascade) {
        var key = light.__uid__;
        var texture = this._textures[key];
        var resolution = light.shadowResolution || 512;
        cascade = cascade || 1;
        if (!texture) {
            if (light.type === 'POINT_LIGHT') {
                texture = new __WEBPACK_IMPORTED_MODULE_12__TextureCube__["a" /* default */]();
            }
            else {
                texture = new __WEBPACK_IMPORTED_MODULE_11__Texture2D__["a" /* default */]();
            }
            // At most 4 cascade
            // TODO share with height ?
            texture.width = resolution * cascade;
            texture.height = resolution;
            if (this.softShadow === ShadowMapPass.VSM) {
                texture.type = __WEBPACK_IMPORTED_MODULE_10__Texture__["a" /* default */].FLOAT;
                texture.anisotropic = 4;
            }
            else {
                texture.minFilter = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST;
                texture.magFilter = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST;
                texture.useMipmap = false;
            }
            this._textures[key] = texture;
        }

        return texture;
    },

    _getPointLightCamera: function (light, target) {
        if (!this._lightCameras.point) {
            this._lightCameras.point = {
                px: new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */](),
                nx: new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */](),
                py: new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */](),
                ny: new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */](),
                pz: new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */](),
                nz: new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */]()
            };
        }
        var camera = this._lightCameras.point[target];

        camera.far = light.range;
        camera.fov = 90;
        camera.position.set(0, 0, 0);
        switch (target) {
            case 'px':
                camera.lookAt(__WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].POSITIVE_X, __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Y);
                break;
            case 'nx':
                camera.lookAt(__WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_X, __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Y);
                break;
            case 'py':
                camera.lookAt(__WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].POSITIVE_Y, __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].POSITIVE_Z);
                break;
            case 'ny':
                camera.lookAt(__WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Y, __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Z);
                break;
            case 'pz':
                camera.lookAt(__WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].POSITIVE_Z, __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Y);
                break;
            case 'nz':
                camera.lookAt(__WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Z, __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Y);
                break;
        }
        light.getWorldPosition(camera.position);
        camera.update();

        return camera;
    },

    _getDirectionalLightCamera: (function () {
        var lightViewMatrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
        var sceneViewBoundingBox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
        var lightViewBBox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
        // Camera of directional light will be adjusted
        // to contain the view frustum and scene bounding box as tightly as possible
        return function (light, scene, sceneCamera) {
            if (!this._lightCameras.directional) {
                this._lightCameras.directional = new __WEBPACK_IMPORTED_MODULE_14__camera_Orthographic__["a" /* default */]();
            }
            var camera = this._lightCameras.directional;

            sceneViewBoundingBox.copy(scene.viewBoundingBoxLastFrame);
            sceneViewBoundingBox.intersection(sceneCamera.frustum.boundingBox);
            // Move to the center of frustum(in world space)
            camera.position
                .copy(sceneViewBoundingBox.min)
                .add(sceneViewBoundingBox.max)
                .scale(0.5)
                .transformMat4(sceneCamera.worldTransform);
            camera.rotation.copy(light.rotation);
            camera.scale.copy(light.scale);
            camera.updateWorldTransform();

            // Transform to light view space
            __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */].invert(lightViewMatrix, camera.worldTransform);
            __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */].multiply(lightViewMatrix, lightViewMatrix, sceneCamera.worldTransform);

            lightViewBBox.copy(sceneViewBoundingBox).applyTransform(lightViewMatrix);

            var min = lightViewBBox.min.array;
            var max = lightViewBBox.max.array;

            // Move camera to adjust the near to 0
            camera.position.set((min[0] + max[0]) / 2, (min[1] + max[1]) / 2, max[2])
                .transformMat4(camera.worldTransform);
            camera.near = 0;
            camera.far = -min[2] + max[2];
            // Make sure receivers not in the frustum will stil receive the shadow.
            if (isNaN(this.lightFrustumBias)) {
                camera.far *= 4;
            }
            else {
                camera.far += this.lightFrustumBias;
            }
            camera.left = min[0];
            camera.right = max[0];
            camera.top = max[1];
            camera.bottom = min[1];
            camera.update(true);

            return camera;
        };
    })(),

    _getSpotLightCamera: function (light) {
        if (!this._lightCameras.spot) {
            this._lightCameras.spot = new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */]();
        }
        var camera = this._lightCameras.spot;
        // Update properties
        camera.fov = light.penumbraAngle * 2;
        camera.far = light.range;
        camera.worldTransform.copy(light.worldTransform);
        camera.updateProjectionMatrix();
        __WEBPACK_IMPORTED_MODULE_17__glmatrix_mat4__["a" /* default */].invert(camera.viewMatrix.array, camera.worldTransform.array);

        return camera;
    },

    /**
     * @param  {clay.Renderer|WebGLRenderingContext} [renderer]
     * @memberOf clay.prePass.ShadowMap.prototype
     */
    // PENDING Renderer or WebGLRenderingContext
    dispose: function (renderer) {
        var _gl = renderer.gl || renderer;

        if (this._frameBuffer) {
            this._frameBuffer.dispose(_gl);
        }

        for (var name in this._textures) {
            this._textures[name].dispose(_gl);
        }

        this._texturePool.clear(renderer.gl);

        this._depthMaterials = {};
        this._distanceMaterials = {};
        this._textures = {};
        this._lightCameras = {};
        this._shadowMapNumber = {
            'POINT_LIGHT': 0,
            'DIRECTIONAL_LIGHT': 0,
            'SPOT_LIGHT': 0
        };
        this._meshMaterials = {};

        for (var i = 0; i < this._receivers.length; i++) {
            var mesh = this._receivers[i];
            // Mesh may be disposed
            if (mesh.material) {
                var material = mesh.material;
                material.undefine('fragment', 'POINT_LIGHT_SHADOW_COUNT');
                material.undefine('fragment', 'DIRECTIONAL_LIGHT_SHADOW_COUNT');
                material.undefine('fragment', 'AMBIENT_LIGHT_SHADOW_COUNT');
                material.set('shadowEnabled', 0);
            }
        }

        this._receivers = [];
        this._lightsCastShadow = [];
    }
});

/**
 * @name clay.prePass.ShadowMap.VSM
 * @type {number}
 */
ShadowMapPass.VSM = 1;

/**
 * @name clay.prePass.ShadowMap.PCF
 * @type {number}
 */
ShadowMapPass.PCF = 2;

/* harmony default export */ __webpack_exports__["a"] = (ShadowMapPass);


/***/ }),
/* 175 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.sm.depth.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\n@import clay.chunk.skinning_header\nvarying vec4 v_ViewPosition;\nvarying vec2 v_Texcoord;\nvoid main(){\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n v_ViewPosition = worldViewProjection * vec4(skinnedPosition, 1.0);\n gl_Position = v_ViewPosition;\n v_Texcoord = texcoord;\n}\n@end\n@export clay.sm.depth.fragment\nvarying vec4 v_ViewPosition;\nvarying vec2 v_Texcoord;\nuniform float bias : 0.001;\nuniform float slopeScale : 1.0;\nuniform sampler2D alphaMap;\nuniform float alphaCutoff: 0.0;\n@import clay.util.encode_float\nvoid main(){\n float depth = v_ViewPosition.z / v_ViewPosition.w;\n if (alphaCutoff > 0.0) {\n if (texture2D(alphaMap, v_Texcoord).a <= alphaCutoff) {\n discard;\n }\n }\n#ifdef USE_VSM\n depth = depth * 0.5 + 0.5;\n float moment1 = depth;\n float moment2 = depth * depth;\n float dx = dFdx(depth);\n float dy = dFdy(depth);\n moment2 += 0.25*(dx*dx+dy*dy);\n gl_FragColor = vec4(moment1, moment2, 0.0, 1.0);\n#else\n float dx = dFdx(depth);\n float dy = dFdy(depth);\n depth += sqrt(dx*dx + dy*dy) * slopeScale + bias;\n gl_FragColor = encodeFloat(depth * 0.5 + 0.5);\n#endif\n}\n@end\n@export clay.sm.debug_depth\nuniform sampler2D depthMap;\nvarying vec2 v_Texcoord;\n@import clay.util.decode_float\nvoid main() {\n vec4 tex = texture2D(depthMap, v_Texcoord);\n#ifdef USE_VSM\n gl_FragColor = vec4(tex.rgb, 1.0);\n#else\n float depth = decodeFloat(tex);\n gl_FragColor = vec4(depth, depth, depth, 1.0);\n#endif\n}\n@end\n@export clay.sm.distance.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 world : WORLD;\nattribute vec3 position : POSITION;\n@import clay.chunk.skinning_header\nvarying vec3 v_WorldPosition;\nvoid main (){\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition , 1.0);\n v_WorldPosition = (world * vec4(skinnedPosition, 1.0)).xyz;\n}\n@end\n@export clay.sm.distance.fragment\nuniform vec3 lightPosition;\nuniform float range : 100;\nvarying vec3 v_WorldPosition;\n@import clay.util.encode_float\nvoid main(){\n float dist = distance(lightPosition, v_WorldPosition);\n#ifdef USE_VSM\n gl_FragColor = vec4(dist, dist * dist, 0.0, 0.0);\n#else\n dist = dist / range;\n gl_FragColor = encodeFloat(dist);\n#endif\n}\n@end\n@export clay.plugin.shadow_map_common\n@import clay.util.decode_float\nfloat tapShadowMap(sampler2D map, vec2 uv, float z){\n vec4 tex = texture2D(map, uv);\n return step(z, decodeFloat(tex) * 2.0 - 1.0);\n}\nfloat pcf(sampler2D map, vec2 uv, float z, float textureSize, vec2 scale) {\n float shadowContrib = tapShadowMap(map, uv, z);\n vec2 offset = vec2(1.0 / textureSize) * scale;\n#ifdef PCF_KERNEL_SIZE\n for (int _idx_ = 0; _idx_ < PCF_KERNEL_SIZE; _idx_++) {{\n shadowContrib += tapShadowMap(map, uv + offset * pcfKernel[_idx_], z);\n }}\n return shadowContrib / float(PCF_KERNEL_SIZE + 1);\n#else\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, 0.0), z);\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(0.0, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, 0.0), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, -offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, -offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(0.0, -offset.y), z);\n return shadowContrib / 9.0;\n#endif\n}\nfloat pcf(sampler2D map, vec2 uv, float z, float textureSize) {\n return pcf(map, uv, z, textureSize, vec2(1.0));\n}\nfloat chebyshevUpperBound(vec2 moments, float z){\n float p = 0.0;\n z = z * 0.5 + 0.5;\n if (z <= moments.x) {\n p = 1.0;\n }\n float variance = moments.y - moments.x * moments.x;\n variance = max(variance, 0.0000001);\n float mD = moments.x - z;\n float pMax = variance / (variance + mD * mD);\n pMax = clamp((pMax-0.4)/(1.0-0.4), 0.0, 1.0);\n return max(p, pMax);\n}\nfloat computeShadowContrib(\n sampler2D map, mat4 lightVPM, vec3 position, float textureSize, vec2 scale, vec2 offset\n) {\n vec4 posInLightSpace = lightVPM * vec4(position, 1.0);\n posInLightSpace.xyz /= posInLightSpace.w;\n float z = posInLightSpace.z;\n if(all(greaterThan(posInLightSpace.xyz, vec3(-0.99, -0.99, -1.0))) &&\n all(lessThan(posInLightSpace.xyz, vec3(0.99, 0.99, 1.0)))){\n vec2 uv = (posInLightSpace.xy+1.0) / 2.0;\n #ifdef USE_VSM\n vec2 moments = texture2D(map, uv * scale + offset).xy;\n return chebyshevUpperBound(moments, z);\n #else\n return pcf(map, uv * scale + offset, z, textureSize, scale);\n #endif\n }\n return 1.0;\n}\nfloat computeShadowContrib(sampler2D map, mat4 lightVPM, vec3 position, float textureSize) {\n return computeShadowContrib(map, lightVPM, position, textureSize, vec2(1.0), vec2(0.0));\n}\nfloat computeShadowContribOmni(samplerCube map, vec3 direction, float range)\n{\n float dist = length(direction);\n vec4 shadowTex = textureCube(map, direction);\n#ifdef USE_VSM\n vec2 moments = shadowTex.xy;\n float variance = moments.y - moments.x * moments.x;\n float mD = moments.x - dist;\n float p = variance / (variance + mD * mD);\n if(moments.x + 0.001 < dist){\n return clamp(p, 0.0, 1.0);\n }else{\n return 1.0;\n }\n#else\n return step(dist, (decodeFloat(shadowTex) + 0.0002) * range);\n#endif\n}\n@end\n@export clay.plugin.compute_shadow_map\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT) || defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT) || defined(POINT_LIGHT_SHADOWMAP_COUNT)\n#ifdef SPOT_LIGHT_SHADOWMAP_COUNT\nuniform sampler2D spotLightShadowMaps[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform mat4 spotLightMatrices[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform float spotLightShadowMapSizes[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\n#ifdef DIRECTIONAL_LIGHT_SHADOWMAP_COUNT\n#if defined(SHADOW_CASCADE)\nuniform sampler2D directionalLightShadowMaps[1]:unconfigurable;\nuniform mat4 directionalLightMatrices[SHADOW_CASCADE]:unconfigurable;\nuniform float directionalLightShadowMapSizes[1]:unconfigurable;\nuniform float shadowCascadeClipsNear[SHADOW_CASCADE]:unconfigurable;\nuniform float shadowCascadeClipsFar[SHADOW_CASCADE]:unconfigurable;\n#else\nuniform sampler2D directionalLightShadowMaps[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform mat4 directionalLightMatrices[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform float directionalLightShadowMapSizes[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\n#endif\n#ifdef POINT_LIGHT_SHADOWMAP_COUNT\nuniform samplerCube pointLightShadowMaps[POINT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\nuniform bool shadowEnabled : true;\n#ifdef PCF_KERNEL_SIZE\nuniform vec2 pcfKernel[PCF_KERNEL_SIZE];\n#endif\n@import clay.plugin.shadow_map_common\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\nvoid computeShadowOfSpotLights(vec3 position, inout float shadowContribs[SPOT_LIGHT_COUNT] ) {\n float shadowContrib;\n for(int _idx_ = 0; _idx_ < SPOT_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n shadowContrib = computeShadowContrib(\n spotLightShadowMaps[_idx_], spotLightMatrices[_idx_], position,\n spotLightShadowMapSizes[_idx_]\n );\n shadowContribs[_idx_] = shadowContrib;\n }}\n for(int _idx_ = SPOT_LIGHT_SHADOWMAP_COUNT; _idx_ < SPOT_LIGHT_COUNT; _idx_++){{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n#ifdef SHADOW_CASCADE\nvoid computeShadowOfDirectionalLights(vec3 position, inout float shadowContribs[DIRECTIONAL_LIGHT_COUNT]){\n float depth = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far)\n / (gl_DepthRange.far - gl_DepthRange.near);\n float shadowContrib;\n shadowContribs[0] = 1.0;\n for (int _idx_ = 0; _idx_ < SHADOW_CASCADE; _idx_++) {{\n if (\n depth >= shadowCascadeClipsNear[_idx_] &&\n depth <= shadowCascadeClipsFar[_idx_]\n ) {\n shadowContrib = computeShadowContrib(\n directionalLightShadowMaps[0], directionalLightMatrices[_idx_], position,\n directionalLightShadowMapSizes[0],\n vec2(1.0 / float(SHADOW_CASCADE), 1.0),\n vec2(float(_idx_) / float(SHADOW_CASCADE), 0.0)\n );\n shadowContribs[0] = shadowContrib;\n }\n }}\n for(int _idx_ = DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#else\nvoid computeShadowOfDirectionalLights(vec3 position, inout float shadowContribs[DIRECTIONAL_LIGHT_COUNT]){\n float shadowContrib;\n for(int _idx_ = 0; _idx_ < DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n shadowContrib = computeShadowContrib(\n directionalLightShadowMaps[_idx_], directionalLightMatrices[_idx_], position,\n directionalLightShadowMapSizes[_idx_]\n );\n shadowContribs[_idx_] = shadowContrib;\n }}\n for(int _idx_ = DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#endif\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\nvoid computeShadowOfPointLights(vec3 position, inout float shadowContribs[POINT_LIGHT_COUNT] ){\n vec3 lightPosition;\n vec3 direction;\n for(int _idx_ = 0; _idx_ < POINT_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n lightPosition = pointLightPosition[_idx_];\n direction = position - lightPosition;\n shadowContribs[_idx_] = computeShadowContribOmni(pointLightShadowMaps[_idx_], direction, pointLightRange[_idx_]);\n }}\n for(int _idx_ = POINT_LIGHT_SHADOWMAP_COUNT; _idx_ < POINT_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#endif\n@end");


/***/ }),
/* 176 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_createCompositor__ = __webpack_require__(177);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__SSAOPass__ = __webpack_require__(189);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__SSRPass__ = __webpack_require__(191);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__poissonKernel__ = __webpack_require__(193);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__NormalPass__ = __webpack_require__(194);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__EdgePass__ = __webpack_require__(196);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11_claygl_src_math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__composite_js__ = __webpack_require__(197);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13_claygl_src_shader_source_compositor_blur_glsl_js__ = __webpack_require__(87);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14_claygl_src_shader_source_compositor_lut_glsl_js__ = __webpack_require__(88);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15_claygl_src_shader_source_compositor_output_glsl_js__ = __webpack_require__(89);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16_claygl_src_shader_source_compositor_bright_glsl_js__ = __webpack_require__(90);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17_claygl_src_shader_source_compositor_downsample_glsl_js__ = __webpack_require__(91);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18_claygl_src_shader_source_compositor_upsample_glsl_js__ = __webpack_require__(92);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19_claygl_src_shader_source_compositor_hdr_glsl_js__ = __webpack_require__(93);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_20_claygl_src_shader_source_compositor_blend_glsl_js__ = __webpack_require__(94);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21_claygl_src_shader_source_compositor_fxaa_glsl_js__ = __webpack_require__(95);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22__DOF_glsl_js__ = __webpack_require__(198);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_23__edge_glsl_js__ = __webpack_require__(199);



























__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_13_claygl_src_shader_source_compositor_blur_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_14_claygl_src_shader_source_compositor_lut_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_15_claygl_src_shader_source_compositor_output_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_16_claygl_src_shader_source_compositor_bright_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_17_claygl_src_shader_source_compositor_downsample_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_18_claygl_src_shader_source_compositor_upsample_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_19_claygl_src_shader_source_compositor_hdr_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_20_claygl_src_shader_source_compositor_blend_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_21_claygl_src_shader_source_compositor_fxaa_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_22__DOF_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_23__edge_glsl_js__["a" /* default */]);


var commonOutputs = {
    color : {
        parameters : {
            width : function (renderer) {
                return renderer.getWidth();
            },
            height : function (renderer) {
                return renderer.getHeight();
            }
        }
    }
}

var FINAL_NODES_CHAIN = ['composite', 'FXAA'];

function EffectCompositor() {
    this._sourceTexture = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture2D__["a" /* default */]({
        type: __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture__["a" /* default */].HALF_FLOAT
    });
    this._depthTexture = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture2D__["a" /* default */]({
        format: __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture__["a" /* default */].DEPTH_COMPONENT,
        type: __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture__["a" /* default */].UNSIGNED_INT
    });

    this._framebuffer = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__["a" /* default */]();
    this._framebuffer.attach(this._sourceTexture);
    this._framebuffer.attach(this._depthTexture, __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__["a" /* default */].DEPTH_ATTACHMENT);

    this._normalPass = new __WEBPACK_IMPORTED_MODULE_9__NormalPass__["a" /* default */]();

    this._compositor = Object(__WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_createCompositor__["a" /* default */])(__WEBPACK_IMPORTED_MODULE_12__composite_js__["a" /* default */]);

    var sourceNode = this._compositor.getNodeByName('source');
    sourceNode.texture = this._sourceTexture;
    var cocNode = this._compositor.getNodeByName('coc');

    this._sourceNode = sourceNode;
    this._cocNode = cocNode;
    this._compositeNode = this._compositor.getNodeByName('composite');
    this._fxaaNode = this._compositor.getNodeByName('FXAA');

    this._dofBlurNodes = ['dof_far_blur', 'dof_near_blur', 'dof_coc_blur'].map(function (name) {
        return this._compositor.getNodeByName(name);
    }, this);

    this._dofBlurKernel = 0;
    this._dofBlurKernelSize = new Float32Array(0);

    this._finalNodesChain = FINAL_NODES_CHAIN.map(function (name) {
        return this._compositor.getNodeByName(name);
    }, this);

    var gBufferObj = {
        normalTexture: this._normalPass.getNormalTexture(),
        depthTexture: this._normalPass.getDepthTexture()
    };
    this._ssaoPass = new __WEBPACK_IMPORTED_MODULE_5__SSAOPass__["a" /* default */](gBufferObj);
    this._ssrPass = new __WEBPACK_IMPORTED_MODULE_6__SSRPass__["a" /* default */](gBufferObj);
    this._edgePass = new __WEBPACK_IMPORTED_MODULE_10__EdgePass__["a" /* default */](gBufferObj);
}

EffectCompositor.prototype.resize = function (width, height, dpr) {
    dpr = dpr || 1;
    var width = width * dpr;
    var height = height * dpr;
    var sourceTexture = this._sourceTexture;
    var depthTexture = this._depthTexture;

    sourceTexture.width = width;
    sourceTexture.height = height;
    depthTexture.width = width;
    depthTexture.height = height;
};

EffectCompositor.prototype._ifRenderNormalPass = function () {
    return this._enableSSAO || this._enableEdge || this._enableSSR;
};

EffectCompositor.prototype._getPrevNode = function (node) {
    var idx = FINAL_NODES_CHAIN.indexOf(node.name) - 1;
    var prevNode = this._finalNodesChain[idx];
    while (prevNode && !this._compositor.getNodeByName(prevNode.name)) {
        idx -= 1;
        prevNode = this._finalNodesChain[idx];
    }
    return prevNode;
};
EffectCompositor.prototype._getNextNode = function (node) {
    var idx = FINAL_NODES_CHAIN.indexOf(node.name) + 1;
    var nextNode = this._finalNodesChain[idx];
    while (nextNode && !this._compositor.getNodeByName(nextNode.name)) {
        idx += 1;
        nextNode = this._finalNodesChain[idx];
    }
    return nextNode;
};
EffectCompositor.prototype._addChainNode = function (node) {
    var prevNode = this._getPrevNode(node);
    var nextNode = this._getNextNode(node);
    if (!prevNode) {
        return;
    }

    prevNode.outputs = commonOutputs;
    node.inputs.texture = prevNode.name;
    if (nextNode) {
        node.outputs = commonOutputs;
        nextNode.inputs.texture = node.name;
    }
    else {
        node.outputs = null;
    }
    this._compositor.addNode(node);
};
EffectCompositor.prototype._removeChainNode = function (node) {
    var prevNode = this._getPrevNode(node);
    var nextNode = this._getNextNode(node);
    if (!prevNode) {
        return;
    }

    if (nextNode) {
        prevNode.outputs = commonOutputs;
        nextNode.inputs.texture = prevNode.name;
    }
    else {
        prevNode.outputs = null;
    }
    this._compositor.removeNode(node);
};
/**
 * Update normal
 */
EffectCompositor.prototype.updateNormal = function (renderer, scene, camera, frame) {
    if (this._ifRenderNormalPass()) {
        this._normalPass.update(renderer, scene, camera);
    }
};

/**
 * Render SSAO after render the scene, before compositing
 */
EffectCompositor.prototype.updateSSAO = function (renderer, scene, camera, frame) {
    this._ssaoPass.update(renderer, camera, frame);
};

/**
 * Enable SSAO effect
 */
EffectCompositor.prototype.enableSSAO = function () {
    this._enableSSAO = true;
};

/**
 * Disable SSAO effect
 */
EffectCompositor.prototype.disableSSAO = function () {
    this._enableSSAO = false;
};

/**
 * Enable SSR effect
 */
EffectCompositor.prototype.enableSSR = function () {
    this._enableSSR = true;
    // this._normalPass.enableTargetTexture3 = true;
};
/**
 * Disable SSR effect
 */
EffectCompositor.prototype.disableSSR = function () {
    this._enableSSR = false;
    // this._normalPass.enableTargetTexture3 = false;
};

/**
 * Render SSAO after render the scene, before compositing
 */
EffectCompositor.prototype.getSSAOTexture = function () {
    return this._ssaoPass.getTargetTexture();
};

/**
 * @return {clay.FrameBuffer}
 */
EffectCompositor.prototype.getSourceFrameBuffer = function () {
    return this._framebuffer;
};

/**
 * @return {clay.Texture2D}
 */
EffectCompositor.prototype.getSourceTexture = function () {
    return this._sourceTexture;
};

/**
 * Disable fxaa effect
 */
EffectCompositor.prototype.disableFXAA = function () {
    this._removeChainNode(this._fxaaNode);
};

/**
 * Enable fxaa effect
 */
EffectCompositor.prototype.enableFXAA = function () {
    this._addChainNode(this._fxaaNode);
};

/**
 * Enable bloom effect
 */
EffectCompositor.prototype.enableBloom = function () {
    this._compositeNode.inputs.bloom = 'bloom_composite';
    this._compositor.dirty();
};

/**
 * Disable bloom effect
 */
EffectCompositor.prototype.disableBloom = function () {
    this._compositeNode.inputs.bloom = null;
    this._compositor.dirty();
};

/**
 * Enable depth of field effect
 */
EffectCompositor.prototype.enableDOF = function () {
    this._compositeNode.inputs.texture = 'dof_composite';
    this._compositor.dirty();
};
/**
 * Disable depth of field effect
 */
EffectCompositor.prototype.disableDOF = function () {
    this._compositeNode.inputs.texture = 'source';
    this._compositor.dirty();
};

/**
 * Enable color correction
 */
EffectCompositor.prototype.enableColorCorrection = function () {
    this._compositeNode.define('COLOR_CORRECTION');
    this._enableColorCorrection = true;
};
/**
 * Disable color correction
 */
EffectCompositor.prototype.disableColorCorrection = function () {
    this._compositeNode.undefine('COLOR_CORRECTION');
    this._enableColorCorrection = false;
};

/**
 * Enable edge detection
 */
EffectCompositor.prototype.enableEdge = function () {
    this._enableEdge = true;
};

/**
 * Disable edge detection
 */
EffectCompositor.prototype.disableEdge = function () {
    this._enableEdge = false;
};

/**
 * Set bloom intensity
 * @param {number} value
 */
EffectCompositor.prototype.setBloomIntensity = function (value) {
    this._compositeNode.setParameter('bloomIntensity', value);
};

EffectCompositor.prototype.setSSAOParameter = function (name, value) {
    switch (name) {
        case 'quality':
            // PENDING
            var kernelSize = ({
                low: 6,
                medium: 12,
                high: 32,
                ultra: 62
            })[value] || 12;
            this._ssaoPass.setParameter('kernelSize', kernelSize);
            break;
        case 'radius':
            this._ssaoPass.setParameter(name, value);
            this._ssaoPass.setParameter('bias', value / 200);
            break;
        case 'intensity':
            this._ssaoPass.setParameter(name, value);
            break;
        default:
            if (true) {
                console.warn('Unkown SSAO parameter ' + name);
            }
    }
};

EffectCompositor.prototype.setDOFParameter = function (name, value) {
    switch (name) {
        case 'focalDistance':
        case 'focalRange':
        case 'fstop':
            this._cocNode.setParameter(name, value);
            break;
        case 'blurRadius':
            for (var i = 0; i < this._dofBlurNodes.length; i++) {
                this._dofBlurNodes[i].setParameter('blurRadius', value);
            }
            break;
        case 'quality':
            var kernelSize = ({
                low: 4, medium: 8, high: 16, ultra: 32
            })[value] || 8;
            this._dofBlurKernelSize = kernelSize;
            for (var i = 0; i < this._dofBlurNodes.length; i++) {
                this._dofBlurNodes[i].pass.material.define('POISSON_KERNEL_SIZE', kernelSize);
            }
            this._dofBlurKernel = new Float32Array(kernelSize * 2);
            break;
        default:
            if (true) {
                console.warn('Unkown DOF parameter ' + name);
            }
    }
};

EffectCompositor.prototype.setSSRParameter = function (name, value) {
    if (value == null) {
        return;
    }
    switch (name) {
        case 'quality':
            // PENDING
            var maxIteration = ({
                low: 10,
                medium: 15,
                high: 30,
                ultra: 80
            })[value] || 20;
            var pixelStride = ({
                low: 32,
                medium: 16,
                high: 8,
                ultra: 4
            })[value] || 16;
            this._ssrPass.setParameter('maxIteration', maxIteration);
            this._ssrPass.setParameter('pixelStride', pixelStride);
            break;
        case 'maxRoughness':
            this._ssrPass.setParameter('minGlossiness', Math.max(Math.min(1.0 - value, 1.0), 0.0));
            break;
        case 'physical':
            this.setPhysicallyCorrectSSR(value);
            break;
        default:
            console.warn('Unkown SSR parameter ' + name);
    }
};

EffectCompositor.prototype.setPhysicallyCorrectSSR = function (physical) {
    this._ssrPass.setPhysicallyCorrect(physical);
};

/**
 * Set color of edge
 */
EffectCompositor.prototype.setEdgeColor = function (value) {
    var color = __WEBPACK_IMPORTED_MODULE_8__util_graphicGL__["a" /* default */].parseColor(value);
    this._edgePass.setParameter('edgeColor', color);
};

EffectCompositor.prototype.setExposure = function (value) {
    this._compositeNode.setParameter('exposure', Math.pow(2, value));
};

EffectCompositor.prototype.setColorLookupTexture = function (image, api) {
    this._compositeNode.pass.material.setTextureImage('lut', this._enableColorCorrection ? image : 'none', api, {
        minFilter: __WEBPACK_IMPORTED_MODULE_8__util_graphicGL__["a" /* default */].Texture.NEAREST,
        magFilter: __WEBPACK_IMPORTED_MODULE_8__util_graphicGL__["a" /* default */].Texture.NEAREST,
        flipY: false
    });
};
EffectCompositor.prototype.setColorCorrection = function (type, value) {
    this._compositeNode.setParameter(type, value);
};

EffectCompositor.prototype.isSSREnabled = function () {
    return this._enableSSR;
};

EffectCompositor.prototype.composite = function (renderer, scene, camera, framebuffer, frame) {

    var sourceTexture = this._sourceTexture;
    var targetTexture = sourceTexture;
    if (this._enableEdge) {
        this._edgePass.update(renderer, camera, sourceTexture, frame);
        sourceTexture = targetTexture = this._edgePass.getTargetTexture();
    }
    if (this._enableSSR) {
        this._ssrPass.update(renderer, camera, sourceTexture, frame);
        targetTexture = this._ssrPass.getTargetTexture();

        this._ssrPass.setSSAOTexture(
            this._enableSSAO ? this._ssaoPass.getTargetTexture() : null
        );
        // var lights = scene.getLights();
        // for (var i = 0; i < lights.length; i++) {
        //     if (lights[i].cubemap) {
        //         this._ssrPass.setAmbientCubemap(lights[i].cubemap, lights[i].intensity);
        //     }
        // }
    }
    this._sourceNode.texture = targetTexture;

    this._cocNode.setParameter('depth', this._depthTexture);

    var blurKernel = this._dofBlurKernel;
    var blurKernelSize = this._dofBlurKernelSize;
    var frameAll = Math.floor(__WEBPACK_IMPORTED_MODULE_7__poissonKernel__["a" /* default */].length / 2 / blurKernelSize);
    var kernelOffset = frame % frameAll;

    for (var i = 0; i < blurKernelSize * 2; i++) {
        blurKernel[i] = __WEBPACK_IMPORTED_MODULE_7__poissonKernel__["a" /* default */][i + kernelOffset * blurKernelSize * 2];
    }

    for (var i = 0; i < this._dofBlurNodes.length; i++) {
        this._dofBlurNodes[i].setParameter('percent', frame / 30.0);
        this._dofBlurNodes[i].setParameter('poissonKernel', blurKernel);
    }

    this._cocNode.setParameter('zNear', camera.near);
    this._cocNode.setParameter('zFar', camera.far);

    this._compositor.render(renderer, framebuffer);
};

EffectCompositor.prototype.dispose = function (renderer) {
    this._sourceTexture.dispose(renderer);
    this._depthTexture.dispose(renderer);
    this._framebuffer.dispose(renderer);
    this._compositor.dispose(renderer);

    this._normalPass.dispose(renderer);
    this._ssaoPass.dispose(renderer);
};

/* harmony default export */ __webpack_exports__["a"] = (EffectCompositor);

/***/ }),
/* 177 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__createCompositor__ = __webpack_require__(178);
// DEPRECATED

/* harmony default export */ __webpack_exports__["a"] = (__WEBPACK_IMPORTED_MODULE_0__createCompositor__["a" /* default */]);

/***/ }),
/* 178 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_util__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__compositor_Compositor__ = __webpack_require__(179);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__compositor_SceneNode__ = __webpack_require__(181);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__compositor_TextureNode__ = __webpack_require__(182);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__compositor_FilterNode__ = __webpack_require__(183);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__TextureCube__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__shader_registerBuiltinCompositor__ = __webpack_require__(184);












Object(__WEBPACK_IMPORTED_MODULE_9__shader_registerBuiltinCompositor__["a" /* default */])(__WEBPACK_IMPORTED_MODULE_5__Shader__["a" /* default */]);

var shaderSourceReg = /^#source\((.*?)\)/;

/**
 * @name clay.createCompositor
 * @function
 * @param {Object} json
 * @param {Object} [opts]
 * @return {clay.compositor.Compositor}
 */
function createCompositor(json, opts) {
    var compositor = new __WEBPACK_IMPORTED_MODULE_1__compositor_Compositor__["a" /* default */]();
    opts = opts || {};

    var lib = {
        textures: {},
        parameters: {}
    };
    var afterLoad = function(shaderLib, textureLib) {
        for (var i = 0; i < json.nodes.length; i++) {
            var nodeInfo = json.nodes[i];
            var node = createNode(nodeInfo, lib, opts);
            if (node) {
                compositor.addNode(node);
            }
        }
    };

    for (var name in json.parameters) {
        var paramInfo = json.parameters[name];
        lib.parameters[name] = convertParameter(paramInfo);
    }
    // TODO load texture asynchronous
    loadTextures(json, lib, opts, function(textureLib) {
        lib.textures = textureLib;
        afterLoad();
    });

    return compositor;
}

function createNode(nodeInfo, lib, opts) {
    var type = nodeInfo.type || 'filter';
    var shaderSource;
    var inputs;
    var outputs;

    if (type === 'filter') {
        var shaderExp = nodeInfo.shader.trim();
        var res = shaderSourceReg.exec(shaderExp);
        if (res) {
            shaderSource = __WEBPACK_IMPORTED_MODULE_5__Shader__["a" /* default */].source(res[1].trim());
        }
        else if (shaderExp.charAt(0) === '#') {
            shaderSource = lib.shaders[shaderExp.substr(1)];
        }
        if (!shaderSource) {
            shaderSource = shaderExp;
        }
        if (!shaderSource) {
            return;
        }
    }

    if (nodeInfo.inputs) {
        inputs = {};
        for (var name in nodeInfo.inputs) {
            if (typeof nodeInfo.inputs[name] === 'string') {
                inputs[name] = nodeInfo.inputs[name];
            }
            else {
                inputs[name] = {
                    node: nodeInfo.inputs[name].node,
                    pin: nodeInfo.inputs[name].pin
                };
            }
        }
    }
    if (nodeInfo.outputs) {
        outputs = {};
        for (var name in nodeInfo.outputs) {
            var outputInfo = nodeInfo.outputs[name];
            outputs[name] = {};
            if (outputInfo.attachment != null) {
                outputs[name].attachment = outputInfo.attachment;
            }
            if (outputInfo.keepLastFrame != null) {
                outputs[name].keepLastFrame = outputInfo.keepLastFrame;
            }
            if (outputInfo.outputLastFrame != null) {
                outputs[name].outputLastFrame = outputInfo.outputLastFrame;
            }
            if (outputInfo.parameters) {
                outputs[name].parameters = convertParameter(outputInfo.parameters);
            }
        }
    }
    var node;
    if (type === 'scene') {
        node = new __WEBPACK_IMPORTED_MODULE_2__compositor_SceneNode__["a" /* default */]({
            name: nodeInfo.name,
            scene: opts.scene,
            camera: opts.camera,
            outputs: outputs
        });
    }
    else if (type === 'texture') {
        node = new __WEBPACK_IMPORTED_MODULE_3__compositor_TextureNode__["a" /* default */]({
            name: nodeInfo.name,
            outputs: outputs
        });
    }
    // Default is filter
    else {
        node = new __WEBPACK_IMPORTED_MODULE_4__compositor_FilterNode__["a" /* default */]({
            name: nodeInfo.name,
            shader: shaderSource,
            inputs: inputs,
            outputs: outputs
        });
    }
    if (node) {
        if (nodeInfo.parameters) {
            for (var name in nodeInfo.parameters) {
                var val = nodeInfo.parameters[name];
                if (typeof(val) === 'string') {
                    val = val.trim();
                    if (val.charAt(0) === '#') {
                        val = lib.textures[val.substr(1)];
                    }
                    else {
                        node.on(
                            'beforerender', createSizeSetHandler(
                                name, tryConvertExpr(val)
                            )
                        );
                    }
                }
                node.setParameter(name, val);
            }
        }
        if (nodeInfo.defines && node.pass) {
            for (var name in nodeInfo.defines) {
                var val = nodeInfo.defines[name];
                node.pass.material.define('fragment', name, val);
            }
        }
    }
    return node;
}

function defaultWidthFunc(width, height) {
    return width;
}
function defaultHeightFunc(width, height) {
    return height;
}

function convertParameter(paramInfo) {
    var param = {};
    if (!paramInfo) {
        return param;
    }
    ['type', 'minFilter', 'magFilter', 'wrapS', 'wrapT', 'flipY', 'useMipmap']
        .forEach(function(name) {
            var val = paramInfo[name];
            if (val != null) {
                // Convert string to enum
                if (typeof val === 'string') {
                    val = __WEBPACK_IMPORTED_MODULE_6__Texture__["a" /* default */][val];
                }
                param[name] = val;
            }
        });

    var sizeScale = paramInfo.scale || 1;
    ['width', 'height']
        .forEach(function(name) {
            if (paramInfo[name] != null) {
                var val = paramInfo[name];
                if (typeof val === 'string') {
                    val = val.trim();
                    param[name] = createSizeParser(
                        name, tryConvertExpr(val), sizeScale
                    );
                }
                else {
                    param[name] = val;
                }
            }
        });
    if (!param.width) {
        param.width = defaultWidthFunc;
    }
    if (!param.height) {
        param.height = defaultHeightFunc;
    }

    if (paramInfo.useMipmap != null) {
        param.useMipmap = paramInfo.useMipmap;
    }
    return param;
}

function loadTextures(json, lib, opts, callback) {
    if (!json.textures) {
        callback({});
        return;
    }
    var textures = {};
    var loading = 0;

    var cbd = false;
    var textureRootPath = opts.textureRootPath;
    __WEBPACK_IMPORTED_MODULE_0__core_util__["a" /* default */].each(json.textures, function(textureInfo, name) {
        var texture;
        var path = textureInfo.path;
        var parameters = convertParameter(textureInfo.parameters);
        if (Array.isArray(path) && path.length === 6) {
            if (textureRootPath) {
                path = path.map(function(item) {
                    return __WEBPACK_IMPORTED_MODULE_0__core_util__["a" /* default */].relative2absolute(item, textureRootPath);
                });
            }
            texture = new __WEBPACK_IMPORTED_MODULE_8__TextureCube__["a" /* default */](parameters);
        }
        else if(typeof path === 'string') {
            if (textureRootPath) {
                path = __WEBPACK_IMPORTED_MODULE_0__core_util__["a" /* default */].relative2absolute(path, textureRootPath);
            }
            texture = new __WEBPACK_IMPORTED_MODULE_7__Texture2D__["a" /* default */](parameters);
        }
        else {
            return;
        }

        texture.load(path);
        loading++;
        texture.once('success', function() {
            textures[name] = texture;
            loading--;
            if (loading === 0) {
                callback(textures);
                cbd = true;
            }
        });
    });

    if (loading === 0 && !cbd) {
        callback(textures);
    }
}

function createSizeSetHandler(name, exprFunc) {
    return function (renderer) {
        // PENDING viewport size or window size
        var dpr = renderer.getDevicePixelRatio();
        // PENDING If multiply dpr ?
        var width = renderer.getWidth();
        var height = renderer.getHeight();
        var result = exprFunc(width, height, dpr);
        this.setParameter(name, result);
    };
}

function createSizeParser(name, exprFunc, scale) {
    scale = scale || 1;
    return function (renderer) {
        var dpr = renderer.getDevicePixelRatio();
        var width = renderer.getWidth() * scale;
        var height = renderer.getHeight() * scale;
        return exprFunc(width, height, dpr);
    };
}

function tryConvertExpr(string) {
    // PENDING
    var exprRes = /^expr\((.*)\)$/.exec(string);
    if (exprRes) {
        try {
            var func = new Function('width', 'height', 'dpr', 'return ' + exprRes[1]);
            // Try run t
            func(1, 1);

            return func;
        }
        catch (e) {
            throw new Error('Invalid expression.');
        }
    }
}

/* harmony default export */ __webpack_exports__["a"] = (createCompositor);


/***/ }),
/* 179 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Graph__ = __webpack_require__(180);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__TexturePool__ = __webpack_require__(86);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__FrameBuffer__ = __webpack_require__(10);




/**
 * Compositor provide graph based post processing
 *
 * @constructor clay.compositor.Compositor
 * @extends clay.compositor.Graph
 *
 */
var Compositor = __WEBPACK_IMPORTED_MODULE_0__Graph__["a" /* default */].extend(function() {
    return {
        // Output node
        _outputs: [],

        _texturePool: new __WEBPACK_IMPORTED_MODULE_1__TexturePool__["a" /* default */](),

        _frameBuffer: new __WEBPACK_IMPORTED_MODULE_2__FrameBuffer__["a" /* default */]({
            depthBuffer: false
        })
    };
},
/** @lends clay.compositor.Compositor.prototype */
{
    addNode: function(node) {
        __WEBPACK_IMPORTED_MODULE_0__Graph__["a" /* default */].prototype.addNode.call(this, node);
        node._compositor = this;
    },
    /**
     * @param  {clay.Renderer} renderer
     */
    render: function(renderer, frameBuffer) {
        if (this._dirty) {
            this.update();
            this._dirty = false;

            this._outputs.length = 0;
            for (var i = 0; i < this.nodes.length; i++) {
                if (!this.nodes[i].outputs) {
                    this._outputs.push(this.nodes[i]);
                }
            }
        }

        for (var i = 0; i < this.nodes.length; i++) {
            // Update the reference number of each output texture
            this.nodes[i].beforeFrame();
        }

        for (var i = 0; i < this._outputs.length; i++) {
            this._outputs[i].updateReference();
        }

        for (var i = 0; i < this._outputs.length; i++) {
            this._outputs[i].render(renderer, frameBuffer);
        }

        for (var i = 0; i < this.nodes.length; i++) {
            // Clear up
            this.nodes[i].afterFrame();
        }
    },

    allocateTexture: function (parameters) {
        return this._texturePool.get(parameters);
    },

    releaseTexture: function (parameters) {
        this._texturePool.put(parameters);
    },

    getFrameBuffer: function () {
        return this._frameBuffer;
    },

    /**
     * Dispose compositor
     * @param {clay.Renderer} renderer
     */
    dispose: function (renderer) {
        this._texturePool.clear(renderer);
    }
});

/* harmony default export */ __webpack_exports__["a"] = (Compositor);


/***/ }),
/* 180 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__CompositorNode__ = __webpack_require__(48);



/**
 * @constructor clay.compositor.Graph
 * @extends clay.core.Base
 */
var Graph = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
    return /** @lends clay.compositor.Graph# */ {
        /**
         * @type {Array.<clay.compositor.CompositorNode>}
         */
        nodes: []
    };
},
/** @lends clay.compositor.Graph.prototype */
{

    /**
     * Mark to update
     */
    dirty: function () {
        this._dirty = true;
    },
    /**
     * @param {clay.compositor.CompositorNode} node
     */
    addNode: function (node) {

        if (this.nodes.indexOf(node) >= 0) {
            return;
        }

        this.nodes.push(node);

        this._dirty = true;
    },
    /**
     * @param  {clay.compositor.CompositorNode|string} node
     */
    removeNode: function (node) {
        if (typeof node === 'string') {
            node = this.getNodeByName(node);
        }
        var idx = this.nodes.indexOf(node);
        if (idx >= 0) {
            this.nodes.splice(idx, 1);
            this._dirty = true;
        }
    },
    /**
     * @param {string} name
     * @return {clay.compositor.CompositorNode}
     */
    getNodeByName: function (name) {
        for (var i = 0; i < this.nodes.length; i++) {
            if (this.nodes[i].name === name) {
                return this.nodes[i];
            }
        }
    },
    /**
     * Update links of graph
     */
    update: function () {
        for (var i = 0; i < this.nodes.length; i++) {
            this.nodes[i].clear();
        }
        // Traverse all the nodes and build the graph
        for (var i = 0; i < this.nodes.length; i++) {
            var node = this.nodes[i];

            if (!node.inputs) {
                continue;
            }
            for (var inputName in node.inputs) {
                if (!node.inputs[inputName]) {
                    continue;
                }
                if (node.pass && !node.pass.material.isUniformEnabled(inputName)) {
                    console.warn('Pin '  + node.name + '.' + inputName + ' not used.');
                    continue;
                }
                var fromPinInfo = node.inputs[inputName];

                var fromPin = this.findPin(fromPinInfo);
                if (fromPin) {
                    node.link(inputName, fromPin.node, fromPin.pin);
                }
                else {
                    if (typeof fromPinInfo === 'string') {
                        console.warn('Node ' + fromPinInfo + ' not exist');
                    }
                    else {
                        console.warn('Pin of ' + fromPinInfo.node + '.' + fromPinInfo.pin + ' not exist');
                    }
                }
            }
        }
    },

    findPin: function (input) {
        var node;
        // Try to take input as a directly a node
        if (typeof input === 'string' || input instanceof __WEBPACK_IMPORTED_MODULE_1__CompositorNode__["a" /* default */]) {
            input = {
                node: input
            };
        }

        if (typeof input.node === 'string') {
            for (var i = 0; i < this.nodes.length; i++) {
                var tmp = this.nodes[i];
                if (tmp.name === input.node) {
                    node = tmp;
                }
            }
        }
        else {
            node = input.node;
        }
        if (node) {
            var inputPin = input.pin;
            if (!inputPin) {
                // Use first pin defaultly
                if (node.outputs) {
                    inputPin = Object.keys(node.outputs)[0];
                }
            }
            if (node.outputs[inputPin]) {
                return {
                    node: node,
                    pin: inputPin
                };
            }
        }
    }
});

/* harmony default export */ __webpack_exports__["a"] = (Graph);


/***/ }),
/* 181 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__CompositorNode__ = __webpack_require__(48);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__FrameBuffer__ = __webpack_require__(10);




/**
 * @constructor clay.compositor.SceneNode
 * @extends clay.compositor.CompositorNode
 */
var SceneNode = __WEBPACK_IMPORTED_MODULE_0__CompositorNode__["a" /* default */].extend(
/** @lends clay.compositor.SceneNode# */
{
    name: 'scene',
    /**
     * @type {clay.Scene}
     */
    scene: null,
    /**
     * @type {clay.Camera}
     */
    camera: null,
    /**
     * @type {boolean}
     */
    autoUpdateScene: true,
    /**
     * @type {boolean}
     */
    preZ: false

}, function() {
    this.frameBuffer = new __WEBPACK_IMPORTED_MODULE_2__FrameBuffer__["a" /* default */]();
}, {
    render: function(renderer) {

        this._rendering = true;
        var _gl = renderer.gl;

        this.trigger('beforerender');

        var renderInfo;

        if (!this.outputs) {

            renderInfo = renderer.render(this.scene, this.camera, !this.autoUpdateScene, this.preZ);

        }
        else {

            var frameBuffer = this.frameBuffer;
            for (var name in this.outputs) {
                var parameters = this.updateParameter(name, renderer);
                var outputInfo = this.outputs[name];
                var texture = this._compositor.allocateTexture(parameters);
                this._outputTextures[name] = texture;

                var attachment = outputInfo.attachment || _gl.COLOR_ATTACHMENT0;
                if (typeof(attachment) == 'string') {
                    attachment = _gl[attachment];
                }
                frameBuffer.attach(texture, attachment);
            }
            frameBuffer.bind(renderer);

            // MRT Support in chrome
            // https://www.khronos.org/registry/webgl/sdk/tests/conformance/extensions/ext-draw-buffers.html
            var ext = renderer.getGLExtension('EXT_draw_buffers');
            if (ext) {
                var bufs = [];
                for (var attachment in this.outputs) {
                    attachment = parseInt(attachment);
                    if (attachment >= _gl.COLOR_ATTACHMENT0 && attachment <= _gl.COLOR_ATTACHMENT0 + 8) {
                        bufs.push(attachment);
                    }
                }
                ext.drawBuffersEXT(bufs);
            }

            // Always clear
            // PENDING
            renderer.saveClear();
            renderer.clearBit = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DEPTH_BUFFER_BIT | __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].COLOR_BUFFER_BIT;
            renderInfo = renderer.render(this.scene, this.camera, !this.autoUpdateScene, this.preZ);
            renderer.restoreClear();

            frameBuffer.unbind(renderer);
        }

        this.trigger('afterrender', renderInfo);

        this._rendering = false;
        this._rendered = true;
    }
});

/* harmony default export */ __webpack_exports__["a"] = (SceneNode);


/***/ }),
/* 182 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__CompositorNode__ = __webpack_require__(48);


/**
 * @constructor clay.compositor.TextureNode
 * @extends clay.compositor.CompositorNode
 */
var TextureNode = __WEBPACK_IMPORTED_MODULE_0__CompositorNode__["a" /* default */].extend(function() {
    return /** @lends clay.compositor.TextureNode# */ {
        /**
         * @type {clay.Texture2D}
         */
        texture: null,

        // Texture node must have output without parameters
        outputs: {
            color: {}
        }
    };
}, function () {
}, {

    getOutput: function (renderer, name) {
        return this.texture;
    },

    // Do nothing
    beforeFrame: function () {},
    afterFrame: function () {}
});

/* harmony default export */ __webpack_exports__["a"] = (TextureNode);


/***/ }),
/* 183 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Pass__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__CompositorNode__ = __webpack_require__(48);
// TODO Shader library



// TODO curlnoise demo wrong

// PENDING
// Use topological sort ?

/**
 * Filter node
 *
 * @constructor clay.compositor.FilterNode
 * @extends clay.compositor.CompositorNode
 *
 * @example
    var node = new clay.compositor.FilterNode({
        name: 'fxaa',
        shader: clay.Shader.source('clay.compositor.fxaa'),
        inputs: {
            texture: {
                    node: 'scene',
                    pin: 'color'
            }
        },
        // Multiple outputs is preserved for MRT support in WebGL2.0
        outputs: {
            color: {
                attachment: clay.FrameBuffer.COLOR_ATTACHMENT0
                parameters: {
                    format: clay.Texture.RGBA,
                    width: 512,
                    height: 512
                },
                // Node will keep the RTT rendered in last frame
                keepLastFrame: true,
                // Force the node output the RTT rendered in last frame
                outputLastFrame: true
            }
        }
    });
    *
    */
var FilterNode = __WEBPACK_IMPORTED_MODULE_1__CompositorNode__["a" /* default */].extend(function () {
    return /** @lends clay.compositor.FilterNode# */ {
        /**
         * @type {string}
         */
        name: '',

        /**
         * @type {Object}
         */
        inputs: {},

        /**
         * @type {Object}
         */
        outputs: null,

        /**
         * @type {string}
         */
        shader: '',

        /**
         * Input links, will be updated by the graph
         * @example:
         *     inputName: {
         *         node: someNode,
         *         pin: 'xxxx'
         *     }
         * @type {Object}
         */
        inputLinks: {},

        /**
         * Output links, will be updated by the graph
         * @example:
         *     outputName: {
         *         node: someNode,
         *         pin: 'xxxx'
         *     }
         * @type {Object}
         */
        outputLinks: {},

        /**
         * @type {clay.compositor.Pass}
         */
        pass: null,

        // Save the output texture of previous frame
        // Will be used when there exist a circular reference
        _prevOutputTextures: {},
        _outputTextures: {},

        // Example: { name: 2 }
        _outputReferences: {},

        _rendering: false,
        // If rendered in this frame
        _rendered: false,

        _compositor: null
    };
}, function () {

    var pass = new __WEBPACK_IMPORTED_MODULE_0__Pass__["a" /* default */]({
        fragment: this.shader
    });
    this.pass = pass;
},
/** @lends clay.compositor.FilterNode.prototype */
{
    /**
     * @param  {clay.Renderer} renderer
     */
    render: function (renderer, frameBuffer) {
        this.trigger('beforerender', renderer);

        this._rendering = true;

        var _gl = renderer.gl;

        for (var inputName in this.inputLinks) {
            var link = this.inputLinks[inputName];
            var inputTexture = link.node.getOutput(renderer, link.pin);
            this.pass.setUniform(inputName, inputTexture);
        }
        // Output
        if (!this.outputs) {
            this.pass.outputs = null;

            this._compositor.getFrameBuffer().unbind(renderer);

            this.pass.render(renderer, frameBuffer);
        }
        else {
            this.pass.outputs = {};

            var attachedTextures = {};
            for (var name in this.outputs) {
                var parameters = this.updateParameter(name, renderer);
                if (isNaN(parameters.width)) {
                    this.updateParameter(name, renderer);
                }
                var outputInfo = this.outputs[name];
                var texture = this._compositor.allocateTexture(parameters);
                this._outputTextures[name] = texture;
                var attachment = outputInfo.attachment || _gl.COLOR_ATTACHMENT0;
                if (typeof(attachment) === 'string') {
                    attachment = _gl[attachment];
                }
                attachedTextures[attachment] = texture;
            }
            this._compositor.getFrameBuffer().bind(renderer);

            for (var attachment in attachedTextures) {
                // FIXME attachment changes in different nodes
                this._compositor.getFrameBuffer().attach(
                    attachedTextures[attachment], attachment
                );
            }

            this.pass.render(renderer);

            // Because the data of texture is changed over time,
            // Here update the mipmaps of texture each time after rendered;
            this._compositor.getFrameBuffer().updateMipmap(renderer);
        }

        for (var inputName in this.inputLinks) {
            var link = this.inputLinks[inputName];
            link.node.removeReference(link.pin);
        }

        this._rendering = false;
        this._rendered = true;

        this.trigger('afterrender', renderer);
    },

    // TODO Remove parameter function callback
    updateParameter: function (outputName, renderer) {
        var outputInfo = this.outputs[outputName];
        var parameters = outputInfo.parameters;
        var parametersCopy = outputInfo._parametersCopy;
        if (!parametersCopy) {
            parametersCopy = outputInfo._parametersCopy = {};
        }
        if (parameters) {
            for (var key in parameters) {
                if (key !== 'width' && key !== 'height') {
                    parametersCopy[key] = parameters[key];
                }
            }
        }
        var width, height;
        if (parameters.width instanceof Function) {
            width = parameters.width.call(this, renderer);
        }
        else {
            width = parameters.width;
        }
        if (parameters.height instanceof Function) {
            height = parameters.height.call(this, renderer);
        }
        else {
            height = parameters.height;
        }
        width = Math.ceil(width);
        height = Math.ceil(height);
        if (
            parametersCopy.width !== width
            || parametersCopy.height !== height
        ) {
            if (this._outputTextures[outputName]) {
                this._outputTextures[outputName].dispose(renderer);
            }
        }
        parametersCopy.width = width;
        parametersCopy.height = height;

        return parametersCopy;
    },

    /**
     * Set parameter
     * @param {string} name
     * @param {} value
     */
    setParameter: function (name, value) {
        this.pass.setUniform(name, value);
    },
    /**
     * Get parameter value
     * @param  {string} name
     * @return {}
     */
    getParameter: function (name) {
        return this.pass.getUniform(name);
    },
    /**
     * Set parameters
     * @param {Object} obj
     */
    setParameters: function (obj) {
        for (var name in obj) {
            this.setParameter(name, obj[name]);
        }
    },
    // /**
    //  * Set shader code
    //  * @param {string} shaderStr
    //  */
    // setShader: function (shaderStr) {
    //     var material = this.pass.material;
    //     material.shader.setFragment(shaderStr);
    //     material.attachShader(material.shader, true);
    // },
    /**
     * Proxy of pass.material.define('fragment', xxx);
     * @param  {string} symbol
     * @param  {number} [val]
     */
    define: function (symbol, val) {
        this.pass.material.define('fragment', symbol, val);
    },

    /**
     * Proxy of pass.material.undefine('fragment', xxx)
     * @param  {string} symbol
     */
    undefine: function (symbol) {
        this.pass.material.undefine('fragment', symbol);
    },

    removeReference: function (outputName) {
        this._outputReferences[outputName]--;
        if (this._outputReferences[outputName] === 0) {
            var outputInfo = this.outputs[outputName];
            if (outputInfo.keepLastFrame) {
                if (this._prevOutputTextures[outputName]) {
                    this._compositor.releaseTexture(this._prevOutputTextures[outputName]);
                }
                this._prevOutputTextures[outputName] = this._outputTextures[outputName];
            }
            else {
                // Output of this node have alreay been used by all other nodes
                // Put the texture back to the pool.
                this._compositor.releaseTexture(this._outputTextures[outputName]);
            }
        }
    },

    clear: function () {
        __WEBPACK_IMPORTED_MODULE_1__CompositorNode__["a" /* default */].prototype.clear.call(this);

        // Default disable all texture
        this.pass.material.disableTexturesAll();
    }
});

/* harmony default export */ __webpack_exports__["a"] = (FilterNode);


/***/ }),
/* 184 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export (immutable) */ __webpack_exports__["a"] = register;
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__source_compositor_coloradjust_glsl_js__ = __webpack_require__(185);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__source_compositor_blur_glsl_js__ = __webpack_require__(87);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__source_compositor_lum_glsl_js__ = __webpack_require__(186);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__source_compositor_lut_glsl_js__ = __webpack_require__(88);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__source_compositor_vignette_glsl_js__ = __webpack_require__(187);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__source_compositor_output_glsl_js__ = __webpack_require__(89);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__source_compositor_bright_glsl_js__ = __webpack_require__(90);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__source_compositor_downsample_glsl_js__ = __webpack_require__(91);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__source_compositor_upsample_glsl_js__ = __webpack_require__(92);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__source_compositor_hdr_glsl_js__ = __webpack_require__(93);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__source_compositor_lensflare_glsl_js__ = __webpack_require__(188);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__source_compositor_blend_glsl_js__ = __webpack_require__(94);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__source_compositor_fxaa_glsl_js__ = __webpack_require__(95);













// import fxaa3Essl from './source/compositor/fxaa3.glsl.js';

// TODO Must export a module and be used in the other modules. Or it will be tree shaked
function register(Shader) {
    // Some build in shaders
    Shader['import'](__WEBPACK_IMPORTED_MODULE_0__source_compositor_coloradjust_glsl_js__["a" /* default */]);
    Shader['import'](__WEBPACK_IMPORTED_MODULE_1__source_compositor_blur_glsl_js__["a" /* default */]);
    Shader['import'](__WEBPACK_IMPORTED_MODULE_2__source_compositor_lum_glsl_js__["a" /* default */]);
    Shader['import'](__WEBPACK_IMPORTED_MODULE_3__source_compositor_lut_glsl_js__["a" /* default */]);
    Shader['import'](__WEBPACK_IMPORTED_MODULE_4__source_compositor_vignette_glsl_js__["a" /* default */]);
    Shader['import'](__WEBPACK_IMPORTED_MODULE_5__source_compositor_output_glsl_js__["a" /* default */]);
    Shader['import'](__WEBPACK_IMPORTED_MODULE_6__source_compositor_bright_glsl_js__["a" /* default */]);
    Shader['import'](__WEBPACK_IMPORTED_MODULE_7__source_compositor_downsample_glsl_js__["a" /* default */]);
    Shader['import'](__WEBPACK_IMPORTED_MODULE_8__source_compositor_upsample_glsl_js__["a" /* default */]);
    Shader['import'](__WEBPACK_IMPORTED_MODULE_9__source_compositor_hdr_glsl_js__["a" /* default */]);
    Shader['import'](__WEBPACK_IMPORTED_MODULE_10__source_compositor_lensflare_glsl_js__["a" /* default */]);
    Shader['import'](__WEBPACK_IMPORTED_MODULE_11__source_compositor_blend_glsl_js__["a" /* default */]);

    Shader['import'](__WEBPACK_IMPORTED_MODULE_12__source_compositor_fxaa_glsl_js__["a" /* default */]);

}

/***/ }),
/* 185 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.coloradjust\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float brightness : 0.0;\nuniform float contrast : 1.0;\nuniform float exposure : 0.0;\nuniform float gamma : 1.0;\nuniform float saturation : 1.0;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = clamp(tex.rgb + vec3(brightness), 0.0, 1.0);\n color = clamp( (color-vec3(0.5))*contrast+vec3(0.5), 0.0, 1.0);\n color = clamp( color * pow(2.0, exposure), 0.0, 1.0);\n color = clamp( pow(color, vec3(gamma)), 0.0, 1.0);\n float luminance = dot( color, w );\n color = mix(vec3(luminance), color, saturation);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.brightness\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float brightness : 0.0;\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = tex.rgb + vec3(brightness);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.contrast\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float contrast : 1.0;\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = (tex.rgb-vec3(0.5))*contrast+vec3(0.5);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.exposure\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float exposure : 0.0;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = tex.rgb * pow(2.0, exposure);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.gamma\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float gamma : 1.0;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = pow(tex.rgb, vec3(gamma));\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.saturation\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float saturation : 1.0;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = tex.rgb;\n float luminance = dot(color, w);\n color = mix(vec3(luminance), color, saturation);\n gl_FragColor = vec4(color, tex.a);\n}\n@end");


/***/ }),
/* 186 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.hdr.log_lum\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = decodeHDR(texture2D(texture, v_Texcoord));\n float luminance = dot(tex.rgb, w);\n luminance = log(luminance + 0.001);\n gl_FragColor = encodeHDR(vec4(vec3(luminance), 1.0));\n}\n@end\n@export clay.compositor.hdr.lum_adaption\nvarying vec2 v_Texcoord;\nuniform sampler2D adaptedLum;\nuniform sampler2D currentLum;\nuniform float frameTime : 0.02;\n@import clay.util.rgbm\nvoid main()\n{\n float fAdaptedLum = decodeHDR(texture2D(adaptedLum, vec2(0.5, 0.5))).r;\n float fCurrentLum = exp(encodeHDR(texture2D(currentLum, vec2(0.5, 0.5))).r);\n fAdaptedLum += (fCurrentLum - fAdaptedLum) * (1.0 - pow(0.98, 30.0 * frameTime));\n gl_FragColor = encodeHDR(vec4(vec3(fAdaptedLum), 1.0));\n}\n@end\n@export clay.compositor.lum\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord );\n float luminance = dot(tex.rgb, w);\n gl_FragColor = vec4(vec3(luminance), 1.0);\n}\n@end");


/***/ }),
/* 187 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.vignette\n#define OUTPUT_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float darkness: 1;\nuniform float offset: 1;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(texture, v_Texcoord));\n gl_FragColor.rgb = texel.rgb;\n vec2 uv = (v_Texcoord - vec2(0.5)) * vec2(offset);\n gl_FragColor = encodeHDR(vec4(mix(texel.rgb, vec3(1.0 - darkness), dot(uv, uv)), texel.a));\n}\n@end");


/***/ }),
/* 188 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.lensflare\n#define SAMPLE_NUMBER 8\nuniform sampler2D texture;\nuniform sampler2D lenscolor;\nuniform vec2 textureSize : [512, 512];\nuniform float dispersal : 0.3;\nuniform float haloWidth : 0.4;\nuniform float distortion : 1.0;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvec4 textureDistorted(\n in vec2 texcoord,\n in vec2 direction,\n in vec3 distortion\n) {\n return vec4(\n decodeHDR(texture2D(texture, texcoord + direction * distortion.r)).r,\n decodeHDR(texture2D(texture, texcoord + direction * distortion.g)).g,\n decodeHDR(texture2D(texture, texcoord + direction * distortion.b)).b,\n 1.0\n );\n}\nvoid main()\n{\n vec2 texcoord = -v_Texcoord + vec2(1.0); vec2 textureOffset = 1.0 / textureSize;\n vec2 ghostVec = (vec2(0.5) - texcoord) * dispersal;\n vec2 haloVec = normalize(ghostVec) * haloWidth;\n vec3 distortion = vec3(-textureOffset.x * distortion, 0.0, textureOffset.x * distortion);\n vec4 result = vec4(0.0);\n for (int i = 0; i < SAMPLE_NUMBER; i++)\n {\n vec2 offset = fract(texcoord + ghostVec * float(i));\n float weight = length(vec2(0.5) - offset) / length(vec2(0.5));\n weight = pow(1.0 - weight, 10.0);\n result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;\n }\n result *= texture2D(lenscolor, vec2(length(vec2(0.5) - texcoord)) / length(vec2(0.5)));\n float weight = length(vec2(0.5) - fract(texcoord + haloVec)) / length(vec2(0.5));\n weight = pow(1.0 - weight, 10.0);\n vec2 offset = fract(texcoord + haloVec);\n result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;\n gl_FragColor = result;\n}\n@end");


/***/ }),
/* 189 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__halton__ = __webpack_require__(49);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__SSAO_glsl_js__ = __webpack_require__(190);










__WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_8__SSAO_glsl_js__["a" /* default */]);

function generateNoiseData(size) {
    var data = new Uint8Array(size * size * 4);
    var n = 0;
    var v3 = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */]();

    for (var i = 0; i < size; i++) {
        for (var j = 0; j < size; j++) {
            v3.set(Math.random() * 2 - 1, Math.random() * 2 - 1, 0).normalize();
            data[n++] = (v3.x * 0.5 + 0.5) * 255;
            data[n++] = (v3.y * 0.5 + 0.5) * 255;
            data[n++] = 0;
            data[n++] = 255;
        }
    }
    return data;
}

function generateNoiseTexture(size) {
    return new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
        pixels: generateNoiseData(size),
        wrapS: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].REPEAT,
        wrapT: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].REPEAT,
        width: size,
        height: size
    });
}

function generateKernel(size, offset, hemisphere) {
    var kernel = new Float32Array(size * 3);
    offset = offset || 0;
    for (var i = 0; i < size; i++) {
        var phi = Object(__WEBPACK_IMPORTED_MODULE_7__halton__["a" /* default */])(i + offset, 2) * (hemisphere ? 1 : 2) * Math.PI;
        var theta = Object(__WEBPACK_IMPORTED_MODULE_7__halton__["a" /* default */])(i + offset, 3) * Math.PI;
        var r = Math.random();
        var x = Math.cos(phi) * Math.sin(theta) * r;
        var y = Math.cos(theta) * r;
        var z = Math.sin(phi) * Math.sin(theta) * r;

        kernel[i * 3] = x;
        kernel[i * 3 + 1] = y;
        kernel[i * 3 + 2] = z;
    }
    return kernel;

    // var kernel = new Float32Array(size * 3);
    // var v3 = new Vector3();
    // for (var i = 0; i < size; i++) {
    //     v3.set(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random())
    //         .normalize().scale(Math.random());
    //     kernel[i * 3] = v3.x;
    //     kernel[i * 3 + 1] = v3.y;
    //     kernel[i * 3 + 2] = v3.z;
    // }
    // return kernel;
}

function SSAOPass(opt) {
    opt = opt || {};

    this._ssaoPass = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('ecgl.ssao.estimate')
    });
    this._blurPass = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('ecgl.ssao.blur')
    });
    this._framebuffer = new __WEBPACK_IMPORTED_MODULE_6_claygl_src_FrameBuffer__["a" /* default */]({
        depthBuffer: false
    });

    this._ssaoTexture = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]();
    this._blurTexture = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]();
    this._blurTexture2 = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]();

    this._depthTex = opt.depthTexture;
    this._normalTex = opt.normalTexture;

    this.setNoiseSize(4);
    this.setKernelSize(opt.kernelSize || 12);
    if (opt.radius != null) {
        this.setParameter('radius', opt.radius);
    }
    if (opt.power != null) {
        this.setParameter('power', opt.power);
    }

    if (!this._normalTex) {
        this._ssaoPass.material.disableTexture('normalTex');
        this._blurPass.material.disableTexture('normalTex');
    }
    if (!this._depthTex) {
        this._blurPass.material.disableTexture('depthTex');
    }

    this._blurPass.material.setUniform('normalTex', this._normalTex);
    this._blurPass.material.setUniform('depthTex', this._depthTex);
}

SSAOPass.prototype.setDepthTexture = function (depthTex) {
    this._depthTex = depthTex;
};

SSAOPass.prototype.setNormalTexture = function (normalTex) {
    this._normalTex = normalTex;
    this._ssaoPass.material[normalTex ? 'enableTexture' : 'disableTexture']('normalTex');
    // Switch between hemisphere and shere kernel.
    this.setKernelSize(this._kernelSize);
};

SSAOPass.prototype.update = function (renderer, camera, frame) {
    var width = renderer.getWidth();
    var height = renderer.getHeight();

    var ssaoPass = this._ssaoPass;
    var blurPass = this._blurPass;

    ssaoPass.setUniform('kernel', this._kernels[frame % this._kernels.length]);
    ssaoPass.setUniform('depthTex', this._depthTex);
    if (this._normalTex != null) {
        ssaoPass.setUniform('normalTex', this._normalTex);
    }
    ssaoPass.setUniform('depthTexSize', [this._depthTex.width, this._depthTex.height]);

    var viewInverseTranspose = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__["a" /* default */]();
    __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__["a" /* default */].transpose(viewInverseTranspose, camera.worldTransform);

    ssaoPass.setUniform('projection', camera.projectionMatrix.array);
    ssaoPass.setUniform('projectionInv', camera.invProjectionMatrix.array);
    ssaoPass.setUniform('viewInverseTranspose', viewInverseTranspose.array);

    var ssaoTexture = this._ssaoTexture;
    var blurTexture = this._blurTexture;
    var blurTexture2 = this._blurTexture2;

    ssaoTexture.width = width / 2;
    ssaoTexture.height = height / 2;
    blurTexture.width = width;
    blurTexture.height = height;
    blurTexture2.width = width;
    blurTexture2.height = height;

    this._framebuffer.attach(ssaoTexture);
    this._framebuffer.bind(renderer);
    renderer.gl.clearColor(1, 1, 1, 1);
    renderer.gl.clear(renderer.gl.COLOR_BUFFER_BIT);
    ssaoPass.render(renderer);

    blurPass.setUniform('textureSize', [width / 2, height / 2]);
    blurPass.setUniform('projection', camera.projectionMatrix.array);
    this._framebuffer.attach(blurTexture);
    blurPass.setUniform('direction', 0);
    blurPass.setUniform('ssaoTexture', ssaoTexture);
    blurPass.render(renderer);

    this._framebuffer.attach(blurTexture2);
    blurPass.setUniform('textureSize', [width, height]);
    blurPass.setUniform('direction', 1);
    blurPass.setUniform('ssaoTexture', blurTexture);
    blurPass.render(renderer);

    this._framebuffer.unbind(renderer);

    // Restore clear
    var clearColor = renderer.clearColor;
    renderer.gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
};

SSAOPass.prototype.getTargetTexture = function () {
    return this._blurTexture2;
}

SSAOPass.prototype.setParameter = function (name, val) {
    if (name === 'noiseTexSize') {
        this.setNoiseSize(val);
    }
    else if (name === 'kernelSize') {
        this.setKernelSize(val);
    }
    else if (name === 'intensity') {
        this._ssaoPass.material.set('intensity', val);
    }
    else {
        this._ssaoPass.setUniform(name, val);
    }
};

SSAOPass.prototype.setKernelSize = function (size) {
    this._kernelSize = size;
    this._ssaoPass.material.define('fragment', 'KERNEL_SIZE', size);
    this._kernels = this._kernels || [];
    for (var i = 0; i < 30; i++) {
        this._kernels[i] = generateKernel(size, i * size, !!this._normalTex);
    }
};

SSAOPass.prototype.setNoiseSize = function (size) {
    var texture = this._ssaoPass.getUniform('noiseTex');
    if (!texture) {
        texture = generateNoiseTexture(size);
        this._ssaoPass.setUniform('noiseTex', generateNoiseTexture(size));
    }
    else {
        texture.data = generateNoiseData(size);
        texture.width = texture.height = size;
        texture.dirty();
    }

    this._ssaoPass.setUniform('noiseTexSize', [size, size]);
};

SSAOPass.prototype.dispose = function (renderer) {
    this._blurTexture.dispose(renderer);
    this._ssaoTexture.dispose(renderer);
    this._blurTexture2.dispose(renderer);
};

/* harmony default export */ __webpack_exports__["a"] = (SSAOPass);

/***/ }),
/* 190 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.ssao.estimate\n\nuniform sampler2D depthTex;\n\nuniform sampler2D normalTex;\n\nuniform sampler2D noiseTex;\n\nuniform vec2 depthTexSize;\n\nuniform vec2 noiseTexSize;\n\nuniform mat4 projection;\n\nuniform mat4 projectionInv;\n\nuniform mat4 viewInverseTranspose;\n\nuniform vec3 kernel[KERNEL_SIZE];\n\nuniform float radius : 1;\n\nuniform float power : 1;\n\nuniform float bias: 1e-2;\n\nuniform float intensity: 1.0;\n\nvarying vec2 v_Texcoord;\n\nfloat ssaoEstimator(in vec3 originPos, in mat3 kernelBasis) {\n float occlusion = 0.0;\n\n for (int i = 0; i < KERNEL_SIZE; i++) {\n vec3 samplePos = kernel[i];\n#ifdef NORMALTEX_ENABLED\n samplePos = kernelBasis * samplePos;\n#endif\n samplePos = samplePos * radius + originPos;\n\n vec4 texCoord = projection * vec4(samplePos, 1.0);\n texCoord.xy /= texCoord.w;\n\n vec4 depthTexel = texture2D(depthTex, texCoord.xy * 0.5 + 0.5);\n\n float sampleDepth = depthTexel.r * 2.0 - 1.0;\n if (projection[3][3] == 0.0) {\n sampleDepth = projection[3][2] / (sampleDepth * projection[2][3] - projection[2][2]);\n }\n else {\n sampleDepth = (sampleDepth - projection[3][2]) / projection[2][2];\n }\n \n float rangeCheck = smoothstep(0.0, 1.0, radius / abs(originPos.z - sampleDepth));\n occlusion += rangeCheck * step(samplePos.z, sampleDepth - bias);\n }\n#ifdef NORMALTEX_ENABLED\n occlusion = 1.0 - occlusion / float(KERNEL_SIZE);\n#else\n occlusion = 1.0 - clamp((occlusion / float(KERNEL_SIZE) - 0.6) * 2.5, 0.0, 1.0);\n#endif\n return pow(occlusion, power);\n}\n\nvoid main()\n{\n\n vec4 depthTexel = texture2D(depthTex, v_Texcoord);\n\n#ifdef NORMALTEX_ENABLED\n vec4 tex = texture2D(normalTex, v_Texcoord);\n if (dot(tex.rgb, tex.rgb) == 0.0) {\n gl_FragColor = vec4(1.0);\n return;\n }\n vec3 N = tex.rgb * 2.0 - 1.0;\n N = (viewInverseTranspose * vec4(N, 0.0)).xyz;\n\n vec2 noiseTexCoord = depthTexSize / vec2(noiseTexSize) * v_Texcoord;\n vec3 rvec = texture2D(noiseTex, noiseTexCoord).rgb * 2.0 - 1.0;\n vec3 T = normalize(rvec - N * dot(rvec, N));\n vec3 BT = normalize(cross(N, T));\n mat3 kernelBasis = mat3(T, BT, N);\n#else\n if (depthTexel.r > 0.99999) {\n gl_FragColor = vec4(1.0);\n return;\n }\n mat3 kernelBasis;\n#endif\n\n float z = depthTexel.r * 2.0 - 1.0;\n\n vec4 projectedPos = vec4(v_Texcoord * 2.0 - 1.0, z, 1.0);\n vec4 p4 = projectionInv * projectedPos;\n\n vec3 position = p4.xyz / p4.w;\n\n float ao = ssaoEstimator(position, kernelBasis);\n ao = clamp(1.0 - (1.0 - ao) * intensity, 0.0, 1.0);\n gl_FragColor = vec4(vec3(ao), 1.0);\n}\n\n@end\n\n\n@export ecgl.ssao.blur\n#define SHADER_NAME SSAO_BLUR\n\nuniform sampler2D ssaoTexture;\n\n#ifdef NORMALTEX_ENABLED\nuniform sampler2D normalTex;\n#endif\n\nvarying vec2 v_Texcoord;\n\nuniform vec2 textureSize;\nuniform float blurSize : 1.0;\n\nuniform int direction: 0.0;\n\n#ifdef DEPTHTEX_ENABLED\nuniform sampler2D depthTex;\nuniform mat4 projection;\nuniform float depthRange : 0.5;\n\nfloat getLinearDepth(vec2 coord)\n{\n float depth = texture2D(depthTex, coord).r * 2.0 - 1.0;\n return projection[3][2] / (depth * projection[2][3] - projection[2][2]);\n}\n#endif\n\nvoid main()\n{\n float kernel[5];\n kernel[0] = 0.122581;\n kernel[1] = 0.233062;\n kernel[2] = 0.288713;\n kernel[3] = 0.233062;\n kernel[4] = 0.122581;\n\n vec2 off = vec2(0.0);\n if (direction == 0) {\n off[0] = blurSize / textureSize.x;\n }\n else {\n off[1] = blurSize / textureSize.y;\n }\n\n vec2 coord = v_Texcoord;\n\n float sum = 0.0;\n float weightAll = 0.0;\n\n#ifdef NORMALTEX_ENABLED\n vec3 centerNormal = texture2D(normalTex, v_Texcoord).rgb * 2.0 - 1.0;\n#endif\n#if defined(DEPTHTEX_ENABLED)\n float centerDepth = getLinearDepth(v_Texcoord);\n#endif\n\n for (int i = 0; i < 5; i++) {\n vec2 coord = clamp(v_Texcoord + vec2(float(i) - 2.0) * off, vec2(0.0), vec2(1.0));\n\n float w = kernel[i];\n#ifdef NORMALTEX_ENABLED\n vec3 normal = texture2D(normalTex, coord).rgb * 2.0 - 1.0;\n w *= clamp(dot(normal, centerNormal), 0.0, 1.0);\n#endif\n#ifdef DEPTHTEX_ENABLED\n float d = getLinearDepth(coord);\n w *= (1.0 - smoothstep(abs(centerDepth - d) / depthRange, 0.0, 1.0));\n#endif\n\n weightAll += w;\n sum += texture2D(ssaoTexture, coord).r * w;\n }\n\n gl_FragColor = vec4(vec3(sum / weightAll), 1.0);\n}\n\n@end\n");


/***/ }),
/* 191 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__halton__ = __webpack_require__(49);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_claygl_src_util_cubemap__ = __webpack_require__(77);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__SSR_glsl_js__ = __webpack_require__(192);












__WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_9__SSR_glsl_js__["a" /* default */]);

function SSRPass(opt) {
    opt = opt || {};

    this._ssrPass = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('ecgl.ssr.main'),
        clearColor: [0, 0, 0, 0]
    });
    this._blurPass1 = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('ecgl.ssr.blur'),
        clearColor: [0, 0, 0, 0]
    });
    this._blurPass2 = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('ecgl.ssr.blur'),
        clearColor: [0, 0, 0, 0]
    });
    this._blendPass = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('clay.compositor.blend')
    });
    this._blendPass.material.disableTexturesAll();
    this._blendPass.material.enableTexture(['texture1', 'texture2']);

    this._ssrPass.setUniform('gBufferTexture1', opt.normalTexture);
    this._ssrPass.setUniform('gBufferTexture2', opt.depthTexture);
    // this._ssrPass.setUniform('gBufferTexture3', opt.albedoTexture);

    this._blurPass1.setUniform('gBufferTexture1', opt.normalTexture);
    this._blurPass1.setUniform('gBufferTexture2', opt.depthTexture);

    this._blurPass2.setUniform('gBufferTexture1', opt.normalTexture);
    this._blurPass2.setUniform('gBufferTexture2', opt.depthTexture);

    this._blurPass2.material.define('fragment', 'VERTICAL');
    this._blurPass2.material.define('fragment', 'BLEND');

    this._ssrTexture = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
        type: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].HALF_FLOAT
    });
    this._texture2 = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
        type: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].HALF_FLOAT
    });
    this._texture3 = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
        type: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].HALF_FLOAT
    });
    this._prevTexture = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
        type: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].HALF_FLOAT
    });
    this._currentTexture = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
        type: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].HALF_FLOAT
    });

    this._frameBuffer = new __WEBPACK_IMPORTED_MODULE_6_claygl_src_FrameBuffer__["a" /* default */]({
        depthBuffer: false
    });

    this._normalDistribution = null;

    this._totalSamples = 256;
    this._samplePerFrame = 4;

    this._ssrPass.material.define('fragment', 'SAMPLE_PER_FRAME', this._samplePerFrame);
    this._ssrPass.material.define('fragment', 'TOTAL_SAMPLES', this._totalSamples);

    this._downScale = 1;
}

SSRPass.prototype.setAmbientCubemap = function (specularCubemap, specularIntensity) {
    this._ssrPass.material.set('specularCubemap', specularCubemap);
    this._ssrPass.material.set('specularIntensity', specularIntensity);

    var enableSpecularMap = specularCubemap && specularIntensity;
    this._ssrPass.material[enableSpecularMap ? 'enableTexture' : 'disableTexture']('specularCubemap');
};

SSRPass.prototype.update = function (renderer, camera, sourceTexture, frame) {
    var width = renderer.getWidth();
    var height = renderer.getHeight();
    var ssrTexture = this._ssrTexture;
    var texture2 = this._texture2;
    var texture3 = this._texture3;
    ssrTexture.width = this._prevTexture.width = this._currentTexture.width = width / this._downScale;
    ssrTexture.height = this._prevTexture.height = this._currentTexture.height = height / this._downScale;

    texture2.width = texture3.width = width;
    texture2.height = texture3.height = height;

    var frameBuffer = this._frameBuffer;

    var ssrPass = this._ssrPass;
    var blurPass1 = this._blurPass1;
    var blurPass2 = this._blurPass2;
    var blendPass = this._blendPass;

    var toViewSpace = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__["a" /* default */]();
    var toWorldSpace = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__["a" /* default */]();
    __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__["a" /* default */].transpose(toViewSpace, camera.worldTransform);
    __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__["a" /* default */].transpose(toWorldSpace, camera.viewMatrix);

    ssrPass.setUniform('sourceTexture', sourceTexture);
    ssrPass.setUniform('projection', camera.projectionMatrix.array);
    ssrPass.setUniform('projectionInv', camera.invProjectionMatrix.array);
    ssrPass.setUniform('toViewSpace', toViewSpace.array);
    ssrPass.setUniform('toWorldSpace', toWorldSpace.array);
    ssrPass.setUniform('nearZ', camera.near);

    var percent = frame / this._totalSamples * this._samplePerFrame;
    ssrPass.setUniform('jitterOffset', percent);
    ssrPass.setUniform('sampleOffset', frame * this._samplePerFrame);

    blurPass1.setUniform('textureSize', [ssrTexture.width, ssrTexture.height]);
    blurPass2.setUniform('textureSize', [width, height]);
    blurPass2.setUniform('sourceTexture', sourceTexture);

    blurPass1.setUniform('projection', camera.projectionMatrix.array);
    blurPass2.setUniform('projection', camera.projectionMatrix.array);

    frameBuffer.attach(ssrTexture);
    frameBuffer.bind(renderer);
    ssrPass.render(renderer);

    if (this._physicallyCorrect) {
        frameBuffer.attach(this._currentTexture);
        blendPass.setUniform('texture1', this._prevTexture);
        blendPass.setUniform('texture2', ssrTexture);
        blendPass.material.set({
            'weight1': frame >= 1 ? 0.95 : 0,
            'weight2': frame >= 1 ? 0.05 : 1
            // weight1: frame >= 1 ? 1 : 0,
            // weight2: 1
        });
        blendPass.render(renderer);
    }

    frameBuffer.attach(texture2);
    blurPass1.setUniform('texture', this._physicallyCorrect ? this._currentTexture : ssrTexture);
    blurPass1.render(renderer);

    frameBuffer.attach(texture3);
    blurPass2.setUniform('texture', texture2);
    blurPass2.render(renderer);
    frameBuffer.unbind(renderer);

    if (this._physicallyCorrect) {
        var tmp = this._prevTexture;
        this._prevTexture = this._currentTexture;
        this._currentTexture = tmp;
    }
};

SSRPass.prototype.getTargetTexture = function () {
    return this._texture3;
};

SSRPass.prototype.setParameter = function (name, val) {
    if (name === 'maxIteration') {
        this._ssrPass.material.define('fragment', 'MAX_ITERATION', val);
    }
    else {
        this._ssrPass.setUniform(name, val);
    }
};

SSRPass.prototype.setPhysicallyCorrect = function (isPhysicallyCorrect) {
    if (isPhysicallyCorrect) {
        if (!this._normalDistribution) {
            this._normalDistribution = __WEBPACK_IMPORTED_MODULE_8_claygl_src_util_cubemap__["a" /* default */].generateNormalDistribution(64, this._totalSamples);
        }
        this._ssrPass.material.define('fragment', 'PHYSICALLY_CORRECT');
        this._ssrPass.material.set('normalDistribution', this._normalDistribution);
        this._ssrPass.material.set('normalDistributionSize', [64, this._totalSamples]);
    }
    else {
        this._ssrPass.material.undefine('fragment', 'PHYSICALLY_CORRECT');
    }

    this._physicallyCorrect = isPhysicallyCorrect;
};

SSRPass.prototype.setSSAOTexture = function (texture) {
    var blendPass = this._blurPass2;
    if (texture) {
        blendPass.material.enableTexture('ssaoTex');
        blendPass.material.set('ssaoTex', texture);
    }
    else {
        blendPass.material.disableTexture('ssaoTex');
    }
};

SSRPass.prototype.isFinished = function (frame) {
    if (this._physicallyCorrect) {
        return frame > (this._totalSamples / this._samplePerFrame);
    }
    else {
        return true;
    }
};

SSRPass.prototype.dispose = function (renderer) {
    this._ssrTexture.dispose(renderer);
    this._texture2.dispose(renderer);
    this._texture3.dispose(renderer);
    this._prevTexture.dispose(renderer);
    this._currentTexture.dispose(renderer);
    this._frameBuffer.dispose(renderer);
};

/* harmony default export */ __webpack_exports__["a"] = (SSRPass);

/***/ }),
/* 192 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.ssr.main\n\n#define SHADER_NAME SSR\n#define MAX_ITERATION 20;\n#define SAMPLE_PER_FRAME 5;\n#define TOTAL_SAMPLES 128;\n\nuniform sampler2D sourceTexture;\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture2;\nuniform sampler2D gBufferTexture3;\nuniform samplerCube specularCubemap;\nuniform float specularIntensity: 1;\n\nuniform mat4 projection;\nuniform mat4 projectionInv;\nuniform mat4 toViewSpace;\nuniform mat4 toWorldSpace;\n\nuniform float maxRayDistance: 200;\n\nuniform float pixelStride: 16;\nuniform float pixelStrideZCutoff: 50; \nuniform float screenEdgeFadeStart: 0.9; \nuniform float eyeFadeStart : 0.2; uniform float eyeFadeEnd: 0.8; \nuniform float minGlossiness: 0.2; uniform float zThicknessThreshold: 1;\n\nuniform float nearZ;\nuniform vec2 viewportSize : VIEWPORT_SIZE;\n\nuniform float jitterOffset: 0;\n\nvarying vec2 v_Texcoord;\n\n#ifdef DEPTH_DECODE\n@import clay.util.decode_float\n#endif\n\n#ifdef PHYSICALLY_CORRECT\nuniform sampler2D normalDistribution;\nuniform float sampleOffset: 0;\nuniform vec2 normalDistributionSize;\n\nvec3 transformNormal(vec3 H, vec3 N) {\n vec3 upVector = N.y > 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nvec3 importanceSampleNormalGGX(float i, float roughness, vec3 N) {\n float p = fract((i + sampleOffset) / float(TOTAL_SAMPLES));\n vec3 H = texture2D(normalDistribution,vec2(roughness, p)).rgb;\n return transformNormal(H, N);\n}\nfloat G_Smith(float g, float ndv, float ndl) {\n float roughness = 1.0 - g;\n float k = roughness * roughness / 2.0;\n float G1V = ndv / (ndv * (1.0 - k) + k);\n float G1L = ndl / (ndl * (1.0 - k) + k);\n return G1L * G1V;\n}\nvec3 F_Schlick(float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\n#endif\n\nfloat fetchDepth(sampler2D depthTexture, vec2 uv)\n{\n vec4 depthTexel = texture2D(depthTexture, uv);\n return depthTexel.r * 2.0 - 1.0;\n}\n\nfloat linearDepth(float depth)\n{\n if (projection[3][3] == 0.0) {\n return projection[3][2] / (depth * projection[2][3] - projection[2][2]);\n }\n else {\n return (depth - projection[3][2]) / projection[2][2];\n }\n}\n\nbool rayIntersectDepth(float rayZNear, float rayZFar, vec2 hitPixel)\n{\n if (rayZFar > rayZNear)\n {\n float t = rayZFar; rayZFar = rayZNear; rayZNear = t;\n }\n float cameraZ = linearDepth(fetchDepth(gBufferTexture2, hitPixel));\n return rayZFar <= cameraZ && rayZNear >= cameraZ - zThicknessThreshold;\n}\n\n\nbool traceScreenSpaceRay(\n vec3 rayOrigin, vec3 rayDir, float jitter,\n out vec2 hitPixel, out vec3 hitPoint, out float iterationCount\n)\n{\n float rayLength = ((rayOrigin.z + rayDir.z * maxRayDistance) > -nearZ)\n ? (-nearZ - rayOrigin.z) / rayDir.z : maxRayDistance;\n\n vec3 rayEnd = rayOrigin + rayDir * rayLength;\n\n vec4 H0 = projection * vec4(rayOrigin, 1.0);\n vec4 H1 = projection * vec4(rayEnd, 1.0);\n\n float k0 = 1.0 / H0.w, k1 = 1.0 / H1.w;\n\n vec3 Q0 = rayOrigin * k0, Q1 = rayEnd * k1;\n\n vec2 P0 = (H0.xy * k0 * 0.5 + 0.5) * viewportSize;\n vec2 P1 = (H1.xy * k1 * 0.5 + 0.5) * viewportSize;\n\n P1 += dot(P1 - P0, P1 - P0) < 0.0001 ? 0.01 : 0.0;\n vec2 delta = P1 - P0;\n\n bool permute = false;\n if (abs(delta.x) < abs(delta.y)) {\n permute = true;\n delta = delta.yx;\n P0 = P0.yx;\n P1 = P1.yx;\n }\n float stepDir = sign(delta.x);\n float invdx = stepDir / delta.x;\n\n vec3 dQ = (Q1 - Q0) * invdx;\n float dk = (k1 - k0) * invdx;\n\n vec2 dP = vec2(stepDir, delta.y * invdx);\n\n float strideScaler = 1.0 - min(1.0, -rayOrigin.z / pixelStrideZCutoff);\n float pixStride = 1.0 + strideScaler * pixelStride;\n\n dP *= pixStride; dQ *= pixStride; dk *= pixStride;\n\n vec4 pqk = vec4(P0, Q0.z, k0);\n vec4 dPQK = vec4(dP, dQ.z, dk);\n\n pqk += dPQK * jitter;\n float rayZFar = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);\n float rayZNear;\n\n bool intersect = false;\n\n vec2 texelSize = 1.0 / viewportSize;\n\n iterationCount = 0.0;\n\n for (int i = 0; i < MAX_ITERATION; i++)\n {\n pqk += dPQK;\n\n rayZNear = rayZFar;\n rayZFar = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);\n\n hitPixel = permute ? pqk.yx : pqk.xy;\n hitPixel *= texelSize;\n\n intersect = rayIntersectDepth(rayZNear, rayZFar, hitPixel);\n\n iterationCount += 1.0;\n\n dPQK *= 1.2;\n\n if (intersect) {\n break;\n }\n }\n\n Q0.xy += dQ.xy * iterationCount;\n Q0.z = pqk.z;\n hitPoint = Q0 / pqk.w;\n\n return intersect;\n}\n\nfloat calculateAlpha(\n float iterationCount, float reflectivity,\n vec2 hitPixel, vec3 hitPoint, float dist, vec3 rayDir\n)\n{\n float alpha = clamp(reflectivity, 0.0, 1.0);\n alpha *= 1.0 - (iterationCount / float(MAX_ITERATION));\n vec2 hitPixelNDC = hitPixel * 2.0 - 1.0;\n float maxDimension = min(1.0, max(abs(hitPixelNDC.x), abs(hitPixelNDC.y)));\n alpha *= 1.0 - max(0.0, maxDimension - screenEdgeFadeStart) / (1.0 - screenEdgeFadeStart);\n\n float _eyeFadeStart = eyeFadeStart;\n float _eyeFadeEnd = eyeFadeEnd;\n if (_eyeFadeStart > _eyeFadeEnd) {\n float tmp = _eyeFadeEnd;\n _eyeFadeEnd = _eyeFadeStart;\n _eyeFadeStart = tmp;\n }\n\n float eyeDir = clamp(rayDir.z, _eyeFadeStart, _eyeFadeEnd);\n alpha *= 1.0 - (eyeDir - _eyeFadeStart) / (_eyeFadeEnd - _eyeFadeStart);\n\n alpha *= 1.0 - clamp(dist / maxRayDistance, 0.0, 1.0);\n\n return alpha;\n}\n\n@import clay.util.rand\n\n@import clay.util.rgbm\n\nvoid main()\n{\n vec4 normalAndGloss = texture2D(gBufferTexture1, v_Texcoord);\n\n if (dot(normalAndGloss.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n\n float g = normalAndGloss.a;\n#if !defined(PHYSICALLY_CORRECT)\n if (g <= minGlossiness) {\n discard;\n }\n#endif\n\n float reflectivity = (g - minGlossiness) / (1.0 - minGlossiness);\n\n vec3 N = normalize(normalAndGloss.rgb * 2.0 - 1.0);\n N = normalize((toViewSpace * vec4(N, 0.0)).xyz);\n\n vec4 projectedPos = vec4(v_Texcoord * 2.0 - 1.0, fetchDepth(gBufferTexture2, v_Texcoord), 1.0);\n vec4 pos = projectionInv * projectedPos;\n vec3 rayOrigin = pos.xyz / pos.w;\n vec3 V = -normalize(rayOrigin);\n\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float iterationCount;\n float jitter = rand(fract(v_Texcoord + jitterOffset));\n\n#ifdef PHYSICALLY_CORRECT\n vec4 color = vec4(vec3(0.0), 1.0);\n vec4 albedoMetalness = texture2D(gBufferTexture3, v_Texcoord);\n vec3 albedo = albedoMetalness.rgb;\n float m = albedoMetalness.a;\n vec3 diffuseColor = albedo * (1.0 - m);\n vec3 spec = mix(vec3(0.04), albedo, m);\n\n float jitter2 = rand(fract(v_Texcoord)) * float(TOTAL_SAMPLES);\n\n for (int i = 0; i < SAMPLE_PER_FRAME; i++) {\n vec3 H = importanceSampleNormalGGX(float(i) + jitter2, 1.0 - g, N);\n vec3 rayDir = normalize(reflect(-V, H));\n#else\n vec3 rayDir = normalize(reflect(-V, N));\n#endif\n vec2 hitPixel;\n vec3 hitPoint;\n\n bool intersect = traceScreenSpaceRay(rayOrigin, rayDir, jitter, hitPixel, hitPoint, iterationCount);\n\n float dist = distance(rayOrigin, hitPoint);\n\n vec3 hitNormal = texture2D(gBufferTexture1, hitPixel).rgb * 2.0 - 1.0;\n hitNormal = normalize((toViewSpace * vec4(hitNormal, 0.0)).xyz);\n#ifdef PHYSICALLY_CORRECT\n float ndl = clamp(dot(N, rayDir), 0.0, 1.0);\n float vdh = clamp(dot(V, H), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n vec3 litTexel = vec3(0.0);\n if (dot(hitNormal, rayDir) < 0.0 && intersect) {\n litTexel = texture2D(sourceTexture, hitPixel).rgb;\n litTexel *= pow(clamp(1.0 - dist / 200.0, 0.0, 1.0), 3.0);\n\n }\n else {\n #ifdef SPECULARCUBEMAP_ENABLED\n vec3 rayDirW = normalize(toWorldSpace * vec4(rayDir, 0.0)).rgb;\n litTexel = RGBMDecode(textureCubeLodEXT(specularCubemap, rayDirW, 0.0), 8.12).rgb * specularIntensity;\n#endif\n }\n color.rgb += ndl * litTexel * (\n F_Schlick(ndl, spec) * G_Smith(g, ndv, ndl) * vdh / (ndh * ndv + 0.001)\n );\n }\n color.rgb /= float(SAMPLE_PER_FRAME);\n#else\n #if !defined(SPECULARCUBEMAP_ENABLED)\n if (dot(hitNormal, rayDir) >= 0.0) {\n discard;\n }\n if (!intersect) {\n discard;\n }\n#endif\n float alpha = clamp(calculateAlpha(iterationCount, reflectivity, hitPixel, hitPoint, dist, rayDir), 0.0, 1.0);\n vec4 color = texture2D(sourceTexture, hitPixel);\n color.rgb *= alpha;\n\n#ifdef SPECULARCUBEMAP_ENABLED\n vec3 rayDirW = normalize(toWorldSpace * vec4(rayDir, 0.0)).rgb;\n alpha = alpha * (intersect ? 1.0 : 0.0);\n float bias = (1.0 -g) * 5.0;\n color.rgb += (1.0 - alpha)\n * RGBMDecode(textureCubeLodEXT(specularCubemap, rayDirW, bias), 8.12).rgb\n * specularIntensity;\n#endif\n\n#endif\n\n gl_FragColor = encodeHDR(color);\n}\n@end\n\n@export ecgl.ssr.blur\n\nuniform sampler2D texture;\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture2;\nuniform mat4 projection;\nuniform float depthRange : 0.05;\n\nvarying vec2 v_Texcoord;\n\nuniform vec2 textureSize;\nuniform float blurSize : 1.0;\n\n#ifdef BLEND\n #ifdef SSAOTEX_ENABLED\nuniform sampler2D ssaoTex;\n #endif\nuniform sampler2D sourceTexture;\n#endif\n\nfloat getLinearDepth(vec2 coord)\n{\n float depth = texture2D(gBufferTexture2, coord).r * 2.0 - 1.0;\n return projection[3][2] / (depth * projection[2][3] - projection[2][2]);\n}\n\n@import clay.util.rgbm\n\n\nvoid main()\n{\n @import clay.compositor.kernel.gaussian_9\n\n vec4 centerNTexel = texture2D(gBufferTexture1, v_Texcoord);\n float g = centerNTexel.a;\n float maxBlurSize = clamp(1.0 - g, 0.0, 1.0) * blurSize;\n#ifdef VERTICAL\n vec2 off = vec2(0.0, maxBlurSize / textureSize.y);\n#else\n vec2 off = vec2(maxBlurSize / textureSize.x, 0.0);\n#endif\n\n vec2 coord = v_Texcoord;\n\n vec4 sum = vec4(0.0);\n float weightAll = 0.0;\n\n vec3 cN = centerNTexel.rgb * 2.0 - 1.0;\n float cD = getLinearDepth(v_Texcoord);\n for (int i = 0; i < 9; i++) {\n vec2 coord = clamp((float(i) - 4.0) * off + v_Texcoord, vec2(0.0), vec2(1.0));\n float w = gaussianKernel[i]\n * clamp(dot(cN, texture2D(gBufferTexture1, coord).rgb * 2.0 - 1.0), 0.0, 1.0);\n float d = getLinearDepth(coord);\n w *= (1.0 - smoothstep(abs(cD - d) / depthRange, 0.0, 1.0));\n\n weightAll += w;\n sum += decodeHDR(texture2D(texture, coord)) * w;\n }\n\n#ifdef BLEND\n float aoFactor = 1.0;\n #ifdef SSAOTEX_ENABLED\n aoFactor = texture2D(ssaoTex, v_Texcoord).r;\n #endif\n gl_FragColor = encodeHDR(\n sum / weightAll * aoFactor + decodeHDR(texture2D(sourceTexture, v_Texcoord))\n );\n#else\n gl_FragColor = encodeHDR(sum / weightAll);\n#endif\n}\n\n@end");


/***/ }),
/* 193 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
// Based on https://bl.ocks.org/mbostock/19168c663618b707158

/* harmony default export */ __webpack_exports__["a"] = ([
0.0, 0.0,
-0.321585265978, -0.154972575841,
0.458126042375, 0.188473391593,
0.842080129861, 0.527766490688,
0.147304551086, -0.659453822776,
-0.331943915203, -0.940619700594,
0.0479226680259, 0.54812163202,
0.701581552186, -0.709825561388,
-0.295436780218, 0.940589268233,
-0.901489676764, 0.237713156085,
0.973570876096, -0.109899459384,
-0.866792314779, -0.451805525005,
0.330975007087, 0.800048655954,
-0.344275183665, 0.381779221166,
-0.386139432542, -0.437418421534,
-0.576478634965, -0.0148463392551,
0.385798197415, -0.262426961053,
-0.666302061145, 0.682427250835,
-0.628010632582, -0.732836215494,
0.10163141741, -0.987658134403,
0.711995289051, -0.320024291314,
0.0296005138058, 0.950296523438,
0.0130612307608, -0.351024443122,
-0.879596633704, -0.10478487883,
0.435712737232, 0.504254490347,
0.779203817497, 0.206477676721,
0.388264289969, -0.896736162545,
-0.153106280781, -0.629203242522,
-0.245517550697, 0.657969239148,
0.126830499058, 0.26862328493,
-0.634888119007, -0.302301223431,
0.617074219636, 0.779817204925
]);

/***/ }),
/* 194 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_Material__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_compositor_Pass__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_util_texture__ = __webpack_require__(61);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__util_shader_normal_glsl_js__ = __webpack_require__(195);
// NormalPass will generate normal and depth data.

// TODO Animation









__WEBPACK_IMPORTED_MODULE_2_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_7__util_shader_normal_glsl_js__["a" /* default */]);

function attachTextureToSlot(renderer, program, symbol, texture, slot) {
    var gl = renderer.gl;
    program.setUniform(gl, '1i', symbol, slot);

    gl.activeTexture(gl.TEXTURE0 + slot);
    // Maybe texture is not loaded yet;
    if (texture.isRenderable()) {
        texture.bind(renderer);
    }
    else {
        // Bind texture to null
        texture.unbind(renderer);
    }
}

// TODO Use globalShader insteadof globalMaterial?
function getBeforeRenderHook (renderer, defaultNormalMap, defaultBumpMap, defaultRoughnessMap, normalMaterial) {

    var previousNormalMap;
    var previousBumpMap;
    var previousRoughnessMap;
    var previousRenderable;
    var gl = renderer.gl;

    return function (renderable, normalMaterial, prevNormalMaterial) {
        // Material not change
        if (previousRenderable && previousRenderable.material === renderable.material) {
            return;
        }

        var material = renderable.material;
        var program = renderable.__program;

        var roughness = material.get('roughness');
        if (roughness == null) {
            roughness = 1;
        }

        var normalMap = material.get('normalMap') || defaultNormalMap;
        var roughnessMap = material.get('roughnessMap');
        var bumpMap = material.get('bumpMap');
        var uvRepeat = material.get('uvRepeat');
        var uvOffset = material.get('uvOffset');
        var detailUvRepeat = material.get('detailUvRepeat');
        var detailUvOffset = material.get('detailUvOffset');

        var useBumpMap = !!bumpMap && material.isTextureEnabled('bumpMap');
        var useRoughnessMap = !!roughnessMap && material.isTextureEnabled('roughnessMap');
        var doubleSide = material.isDefined('fragment', 'DOUBLE_SIDED');

        bumpMap = bumpMap || defaultBumpMap;
        roughnessMap = roughnessMap || defaultRoughnessMap;

        if (prevNormalMaterial !== normalMaterial) {
            normalMaterial.set('normalMap', normalMap);
            normalMaterial.set('bumpMap', bumpMap);
            normalMaterial.set('roughnessMap', roughnessMap);
            normalMaterial.set('useBumpMap', useBumpMap);
            normalMaterial.set('useRoughnessMap', useRoughnessMap);
            normalMaterial.set('doubleSide', doubleSide);
            uvRepeat != null && normalMaterial.set('uvRepeat', uvRepeat);
            uvOffset != null && normalMaterial.set('uvOffset', uvOffset);
            detailUvRepeat != null && normalMaterial.set('detailUvRepeat', detailUvRepeat);
            detailUvOffset != null && normalMaterial.set('detailUvOffset', detailUvOffset);

            normalMaterial.set('roughness', roughness);
        }
        else {
            program.setUniform(gl, '1f', 'roughness', roughness);

            if (previousNormalMap !== normalMap) {
                attachTextureToSlot(renderer, program, 'normalMap', normalMap, 0);
            }
            if (previousBumpMap !== bumpMap && bumpMap) {
                attachTextureToSlot(renderer, program, 'bumpMap', bumpMap, 1);
            }
            if (previousRoughnessMap !== roughnessMap && roughnessMap) {
                attachTextureToSlot(renderer, program, 'roughnessMap', roughnessMap, 2);
            }
            if (uvRepeat != null) {
                program.setUniform(gl, '2f', 'uvRepeat', uvRepeat);
            }
            if (uvOffset != null) {
                program.setUniform(gl, '2f', 'uvOffset', uvOffset);
            }
            if (detailUvRepeat != null) {
                program.setUniform(gl, '2f', 'detailUvRepeat', detailUvRepeat);
            }
            if (detailUvOffset != null) {
                program.setUniform(gl, '2f', 'detailUvOffset', detailUvOffset);
            }
            program.setUniform(gl, '1i', 'useBumpMap', +useBumpMap);
            program.setUniform(gl, '1i', 'useRoughnessMap', +useRoughnessMap);
            program.setUniform(gl, '1i', 'doubleSide', +doubleSide);
        }

        previousNormalMap = normalMap;
        previousBumpMap = bumpMap;
        previousRoughnessMap = roughnessMap;

        previousRenderable = renderable;
    };
}

function NormalPass(opt) {
    opt = opt || {};

    this._depthTex = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__["a" /* default */]({
        format: __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__["a" /* default */].DEPTH_COMPONENT,
        type: __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__["a" /* default */].UNSIGNED_INT
    });
    this._normalTex = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__["a" /* default */]({
        type: __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__["a" /* default */].HALF_FLOAT
    });

    this._framebuffer = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__["a" /* default */]();
    this._framebuffer.attach(this._normalTex);
    this._framebuffer.attach(this._depthTex, __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__["a" /* default */].DEPTH_ATTACHMENT);

    this._normalMaterial = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_Material__["a" /* default */]({
        shader: new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Shader__["a" /* default */](
            __WEBPACK_IMPORTED_MODULE_2_claygl_src_Shader__["a" /* default */].source('ecgl.normal.vertex'),
            __WEBPACK_IMPORTED_MODULE_2_claygl_src_Shader__["a" /* default */].source('ecgl.normal.fragment')
        )
    });
    this._normalMaterial.enableTexture(['normalMap', 'bumpMap', 'roughnessMap']);

    this._defaultNormalMap = __WEBPACK_IMPORTED_MODULE_6_claygl_src_util_texture__["a" /* default */].createBlank('#000');
    this._defaultBumpMap = __WEBPACK_IMPORTED_MODULE_6_claygl_src_util_texture__["a" /* default */].createBlank('#000');
    this._defaultRoughessMap = __WEBPACK_IMPORTED_MODULE_6_claygl_src_util_texture__["a" /* default */].createBlank('#000');


    this._debugPass = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_2_claygl_src_Shader__["a" /* default */].source('clay.compositor.output')
    });
    this._debugPass.setUniform('texture', this._normalTex);
    this._debugPass.material.undefine('fragment', 'OUTPUT_ALPHA');
}

NormalPass.prototype.getDepthTexture = function () {
    return this._depthTex;
};

NormalPass.prototype.getNormalTexture = function () {
    return this._normalTex;
};

NormalPass.prototype.update = function (renderer, scene, camera) {

    var width = renderer.getWidth();
    var height = renderer.getHeight();

    var depthTexture = this._depthTex;
    var normalTexture = this._normalTex;
    var normalMaterial = this._normalMaterial;

    depthTexture.width = width;
    depthTexture.height = height;
    normalTexture.width = width;
    normalTexture.height = height;

    var opaqueList = scene.getRenderList(camera).opaque;

    this._framebuffer.bind(renderer);
    renderer.gl.clearColor(0, 0, 0, 0);
    renderer.gl.clear(renderer.gl.COLOR_BUFFER_BIT | renderer.gl.DEPTH_BUFFER_BIT);
    renderer.gl.disable(renderer.gl.BLEND);

    renderer.renderPass(opaqueList, camera, {
        getMaterial: function () {
            return normalMaterial;
        },
        ifRender: function (object) {
            return object.renderNormal;
        },
        beforeRender: getBeforeRenderHook(
            renderer, this._defaultNormalMap, this._defaultBumpMap, this._defaultRoughessMap, this._normalMaterial
        ),
        sort: renderer.opaqueSortCompare
    });
    this._framebuffer.unbind(renderer);
};

NormalPass.prototype.renderDebug = function (renderer) {
    this._debugPass.render(renderer);
};

NormalPass.prototype.dispose = function (renderer) {
    this._depthTex.dispose(renderer);
    this._normalTex.dispose(renderer);
}

/* harmony default export */ __webpack_exports__["a"] = (NormalPass);

/***/ }),
/* 195 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.normal.vertex\n\n@import ecgl.common.transformUniforms\n\n@import ecgl.common.uv.header\n\n@import ecgl.common.attributes\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\n@import ecgl.common.normalMap.vertexHeader\n\n@import ecgl.common.vertexAnimation.header\n\nvoid main()\n{\n\n @import ecgl.common.vertexAnimation.main\n\n @import ecgl.common.uv.main\n\n v_Normal = normalize((worldInverseTranspose * vec4(normal, 0.0)).xyz);\n v_WorldPosition = (world * vec4(pos, 1.0)).xyz;\n\n @import ecgl.common.normalMap.vertexMain\n\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n\n}\n\n\n@end\n\n\n@export ecgl.normal.fragment\n\n#define ROUGHNESS_CHANEL 0\n\nuniform bool useBumpMap;\nuniform bool useRoughnessMap;\nuniform bool doubleSide;\nuniform float roughness;\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform mat4 viewInverse : VIEWINVERSE;\n\n@import ecgl.common.normalMap.fragmentHeader\n@import ecgl.common.bumpMap.header\n\nuniform sampler2D roughnessMap;\n\nvoid main()\n{\n vec3 N = v_Normal;\n \n bool flipNormal = false;\n if (doubleSide) {\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n\n if (dot(N, V) < 0.0) {\n flipNormal = true;\n }\n }\n\n @import ecgl.common.normalMap.fragmentMain\n\n if (useBumpMap) {\n N = bumpNormal(v_WorldPosition, v_Normal, N);\n }\n\n float g = 1.0 - roughness;\n\n if (useRoughnessMap) {\n float g2 = 1.0 - texture2D(roughnessMap, v_DetailTexcoord)[ROUGHNESS_CHANEL];\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n }\n\n if (flipNormal) {\n N = -N;\n }\n\n gl_FragColor.rgb = (N.xyz + 1.0) * 0.5;\n gl_FragColor.a = g;\n}\n@end");


/***/ }),
/* 196 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_FrameBuffer__ = __webpack_require__(10);








function EdgePass(opt) {
    opt = opt || {};

    this._edgePass = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('ecgl.edge')
    });

    this._edgePass.setUniform('normalTexture', opt.normalTexture);
    this._edgePass.setUniform('depthTexture', opt.depthTexture);

    this._targetTexture = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
        type: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].HALF_FLOAT
    });

    this._frameBuffer = new __WEBPACK_IMPORTED_MODULE_6_claygl_src_FrameBuffer__["a" /* default */]();
    this._frameBuffer.attach(this._targetTexture);
}

EdgePass.prototype.update = function (renderer, camera, sourceTexture, frame) {
    var width = renderer.getWidth();
    var height = renderer.getHeight();
    var texture = this._targetTexture;
    texture.width = width;
    texture.height = height;
    var frameBuffer = this._frameBuffer;

    frameBuffer.bind(renderer);
    this._edgePass.setUniform('projectionInv', camera.invProjectionMatrix.array);
    this._edgePass.setUniform('textureSize', [width, height]);
    this._edgePass.setUniform('texture', sourceTexture);
    this._edgePass.render(renderer);

    frameBuffer.unbind(renderer);
};

EdgePass.prototype.getTargetTexture = function () {
    return this._targetTexture;
};

EdgePass.prototype.setParameter = function (name, val) {
    this._edgePass.setUniform(name, val);
};

EdgePass.prototype.dispose = function (renderer) {
    this._targetTexture.dispose(renderer);
    this._frameBuffer.dispose(renderer);
};

/* harmony default export */ __webpack_exports__["a"] = (EdgePass);

/***/ }),
/* 197 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ({
    'type' : 'compositor',
    'nodes' : [
        {
            'name': 'source',
            'type': 'texture',
            'outputs': {
                'color': {}
            }
        },
        {
            'name': 'source_half',
            'shader': '#source(clay.compositor.downsample)',
            'inputs': {
                'texture': 'source'
            },
            'outputs': {
                'color': {
                    'parameters': {
                        'width': 'expr(width * 1.0 / 2)',
                        'height': 'expr(height * 1.0 / 2)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'textureSize': 'expr( [width * 1.0, height * 1.0] )'
            }
        },


        {
            'name' : 'bright',
            'shader' : '#source(clay.compositor.bright)',
            'inputs' : {
                'texture' : 'source_half'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 2)',
                        'height' : 'expr(height * 1.0 / 2)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'threshold' : 2,
                'scale': 4,
                'textureSize': 'expr([width * 1.0 / 2, height / 2])'
            }
        },

        {
            'name': 'bright_downsample_4',
            'shader' : '#source(clay.compositor.downsample)',
            'inputs' : {
                'texture' : 'bright'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 4)',
                        'height' : 'expr(height * 1.0 / 4)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'textureSize': 'expr( [width * 1.0 / 2, height / 2] )'
            }
        },
        {
            'name': 'bright_downsample_8',
            'shader' : '#source(clay.compositor.downsample)',
            'inputs' : {
                'texture' : 'bright_downsample_4'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 8)',
                        'height' : 'expr(height * 1.0 / 8)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'textureSize': 'expr( [width * 1.0 / 4, height / 4] )'
            }
        },
        {
            'name': 'bright_downsample_16',
            'shader' : '#source(clay.compositor.downsample)',
            'inputs' : {
                'texture' : 'bright_downsample_8'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 16)',
                        'height' : 'expr(height * 1.0 / 16)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'textureSize': 'expr( [width * 1.0 / 8, height / 8] )'
            }
        },
        {
            'name': 'bright_downsample_32',
            'shader' : '#source(clay.compositor.downsample)',
            'inputs' : {
                'texture' : 'bright_downsample_16'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 32)',
                        'height' : 'expr(height * 1.0 / 32)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'textureSize': 'expr( [width * 1.0 / 16, height / 16] )'
            }
        },


        {
            'name' : 'bright_upsample_16_blur_h',
            'shader' : '#source(clay.compositor.gaussian_blur)',
            'inputs' : {
                'texture' : 'bright_downsample_32'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 16)',
                        'height' : 'expr(height * 1.0 / 16)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'blurSize' : 1,
                'blurDir': 0.0,
                'textureSize': 'expr( [width * 1.0 / 32, height / 32] )'
            }
        },
        {
            'name' : 'bright_upsample_16_blur_v',
            'shader' : '#source(clay.compositor.gaussian_blur)',
            'inputs' : {
                'texture' : 'bright_upsample_16_blur_h'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 16)',
                        'height' : 'expr(height * 1.0 / 16)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'blurSize' : 1,
                'blurDir': 1.0,
                'textureSize': 'expr( [width * 1.0 / 16, height * 1.0 / 16] )'
            }
        },



        {
            'name' : 'bright_upsample_8_blur_h',
            'shader' : '#source(clay.compositor.gaussian_blur)',
            'inputs' : {
                'texture' : 'bright_downsample_16'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 8)',
                        'height' : 'expr(height * 1.0 / 8)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'blurSize' : 1,
                'blurDir': 0.0,
                'textureSize': 'expr( [width * 1.0 / 16, height * 1.0 / 16] )'
            }
        },
        {
            'name' : 'bright_upsample_8_blur_v',
            'shader' : '#source(clay.compositor.gaussian_blur)',
            'inputs' : {
                'texture' : 'bright_upsample_8_blur_h'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 8)',
                        'height' : 'expr(height * 1.0 / 8)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'blurSize' : 1,
                'blurDir': 1.0,
                'textureSize': 'expr( [width * 1.0 / 8, height * 1.0 / 8] )'
            }
        },
        {
            'name' : 'bright_upsample_8_blend',
            'shader' : '#source(clay.compositor.blend)',
            'inputs' : {
                'texture1' : 'bright_upsample_8_blur_v',
                'texture2' : 'bright_upsample_16_blur_v'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 8)',
                        'height' : 'expr(height * 1.0 / 8)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'weight1' : 0.3,
                'weight2' : 0.7
            }
        },


        {
            'name' : 'bright_upsample_4_blur_h',
            'shader' : '#source(clay.compositor.gaussian_blur)',
            'inputs' : {
                'texture' : 'bright_downsample_8'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 4)',
                        'height' : 'expr(height * 1.0 / 4)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'blurSize' : 1,
                'blurDir': 0.0,
                'textureSize': 'expr( [width * 1.0 / 8, height * 1.0 / 8] )'
            }
        },
        {
            'name' : 'bright_upsample_4_blur_v',
            'shader' : '#source(clay.compositor.gaussian_blur)',
            'inputs' : {
                'texture' : 'bright_upsample_4_blur_h'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 4)',
                        'height' : 'expr(height * 1.0 / 4)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'blurSize' : 1,
                'blurDir': 1.0,
                'textureSize': 'expr( [width * 1.0 / 4, height * 1.0 / 4] )'
            }
        },
        {
            'name' : 'bright_upsample_4_blend',
            'shader' : '#source(clay.compositor.blend)',
            'inputs' : {
                'texture1' : 'bright_upsample_4_blur_v',
                'texture2' : 'bright_upsample_8_blend'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 4)',
                        'height' : 'expr(height * 1.0 / 4)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'weight1' : 0.3,
                'weight2' : 0.7
            }
        },





        {
            'name' : 'bright_upsample_2_blur_h',
            'shader' : '#source(clay.compositor.gaussian_blur)',
            'inputs' : {
                'texture' : 'bright_downsample_4'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 2)',
                        'height' : 'expr(height * 1.0 / 2)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'blurSize' : 1,
                'blurDir': 0.0,
                'textureSize': 'expr( [width * 1.0 / 4, height * 1.0 / 4] )'
            }
        },
        {
            'name' : 'bright_upsample_2_blur_v',
            'shader' : '#source(clay.compositor.gaussian_blur)',
            'inputs' : {
                'texture' : 'bright_upsample_2_blur_h'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 2)',
                        'height' : 'expr(height * 1.0 / 2)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'blurSize' : 1,
                'blurDir': 1.0,
                'textureSize': 'expr( [width * 1.0 / 2, height * 1.0 / 2] )'
            }
        },
        {
            'name' : 'bright_upsample_2_blend',
            'shader' : '#source(clay.compositor.blend)',
            'inputs' : {
                'texture1' : 'bright_upsample_2_blur_v',
                'texture2' : 'bright_upsample_4_blend'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0 / 2)',
                        'height' : 'expr(height * 1.0 / 2)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'weight1' : 0.3,
                'weight2' : 0.7
            }
        },



        {
            'name' : 'bright_upsample_full_blur_h',
            'shader' : '#source(clay.compositor.gaussian_blur)',
            'inputs' : {
                'texture' : 'bright'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0)',
                        'height' : 'expr(height * 1.0)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'blurSize' : 1,
                'blurDir': 0.0,
                'textureSize': 'expr( [width * 1.0 / 2, height * 1.0 / 2] )'
            }
        },
        {
            'name' : 'bright_upsample_full_blur_v',
            'shader' : '#source(clay.compositor.gaussian_blur)',
            'inputs' : {
                'texture' : 'bright_upsample_full_blur_h'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0)',
                        'height' : 'expr(height * 1.0)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'blurSize' : 1,
                'blurDir': 1.0,
                'textureSize': 'expr( [width * 1.0, height * 1.0] )'
            }
        },
        {
            'name' : 'bloom_composite',
            'shader' : '#source(clay.compositor.blend)',
            'inputs' : {
                'texture1' : 'bright_upsample_full_blur_v',
                'texture2' : 'bright_upsample_2_blend'
            },
            'outputs' : {
                'color' : {
                    'parameters' : {
                        'width' : 'expr(width * 1.0)',
                        'height' : 'expr(height * 1.0)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters' : {
                'weight1' : 0.3,
                'weight2' : 0.7
            }
        },


        {
            'name': 'coc',
            'shader': '#source(ecgl.dof.coc)',
            'outputs': {
                'color': {
                    'parameters': {
                        'minFilter': 'NEAREST',
                        'magFilter': 'NEAREST',
                        'width': 'expr(width * 1.0)',
                        'height': 'expr(height * 1.0)'
                    }
                }
            },
            'parameters': {
                'focalDist': 50,
                'focalRange': 30
            }
        },

        {
            'name': 'dof_far_blur',
            'shader': '#source(ecgl.dof.diskBlur)',
            'inputs': {
                'texture': 'source',
                'coc': 'coc'
            },
            'outputs': {
                'color': {
                    'parameters': {
                        'width': 'expr(width * 1.0)',
                        'height': 'expr(height * 1.0)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters': {
                'textureSize': 'expr( [width * 1.0, height * 1.0] )'
            }
        },
        {
            'name': 'dof_near_blur',
            'shader': '#source(ecgl.dof.diskBlur)',
            'inputs': {
                'texture': 'source',
                'coc': 'coc'
            },
            'outputs': {
                'color': {
                    'parameters': {
                        'width': 'expr(width * 1.0)',
                        'height': 'expr(height * 1.0)',
                        'type': 'HALF_FLOAT'
                    }
                }
            },
            'parameters': {
                'textureSize': 'expr( [width * 1.0, height * 1.0] )'
            },
            'defines': {
                'BLUR_NEARFIELD': null
            }
        },


        {
            'name': 'dof_coc_blur',
            'shader': '#source(ecgl.dof.diskBlur)',
            'inputs': {
                'texture': 'coc'
            },
            'outputs': {
                'color': {
                    'parameters': {
                        'minFilter': 'NEAREST',
                        'magFilter': 'NEAREST',
                        'width': 'expr(width * 1.0)',
                        'height': 'expr(height * 1.0)'
                    }
                }
            },
            'parameters': {
                'textureSize': 'expr( [width * 1.0, height * 1.0] )'
            },
            'defines': {
                'BLUR_COC': null
            }
        },

        {
            'name': 'dof_composite',
            'shader': '#source(ecgl.dof.composite)',
            'inputs': {
                'original': 'source',
                'blurred': 'dof_far_blur',
                'nearfield': 'dof_near_blur',
                'coc': 'coc',
                'nearcoc': 'dof_coc_blur'
            },
            'outputs': {
                'color': {
                    'parameters': {
                        'width': 'expr(width * 1.0)',
                        'height': 'expr(height * 1.0)',
                        'type': 'HALF_FLOAT'
                    }
                }
            }
        },
        {
            'name' : 'composite',
            'shader' : '#source(clay.compositor.hdr.composite)',
            'inputs' : {
                'texture': 'source',
                'bloom' : 'bloom_composite'
            },
            'defines': {
                // Images are all premultiplied alpha before composite because of blending.
                // 'PREMULTIPLY_ALPHA': null,
                // 'DEBUG': 2
            }
        },
        {
            'name' : 'FXAA',
            'shader' : '#source(clay.compositor.fxaa)',
            'inputs' : {
                'texture' : 'composite'
            }
        }
    ]
});

/***/ }),
/* 198 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.dof.coc\n\nuniform sampler2D depth;\n\nuniform float zNear: 0.1;\nuniform float zFar: 2000;\n\nuniform float focalDistance: 3;\nuniform float focalRange: 1;\nuniform float focalLength: 30;\nuniform float fstop: 2.8;\n\nvarying vec2 v_Texcoord;\n\n@import clay.util.encode_float\n\nvoid main()\n{\n float z = texture2D(depth, v_Texcoord).r * 2.0 - 1.0;\n\n float dist = 2.0 * zNear * zFar / (zFar + zNear - z * (zFar - zNear));\n\n float aperture = focalLength / fstop;\n\n float coc;\n\n float uppper = focalDistance + focalRange;\n float lower = focalDistance - focalRange;\n if (dist <= uppper && dist >= lower) {\n coc = 0.5;\n }\n else {\n float focalAdjusted = dist > uppper ? uppper : lower;\n\n coc = abs(aperture * (focalLength * (dist - focalAdjusted)) / (dist * (focalAdjusted - focalLength)));\n coc = clamp(coc, 0.0, 2.0) / 2.00001;\n\n if (dist < lower) {\n coc = -coc;\n }\n coc = coc * 0.5 + 0.5;\n }\n\n gl_FragColor = encodeFloat(coc);\n}\n@end\n\n\n@export ecgl.dof.composite\n\n#define DEBUG 0\n\nuniform sampler2D original;\nuniform sampler2D blurred;\nuniform sampler2D nearfield;\nuniform sampler2D coc;\nuniform sampler2D nearcoc;\nvarying vec2 v_Texcoord;\n\n@import clay.util.rgbm\n@import clay.util.float\n\nvoid main()\n{\n vec4 blurredColor = texture2D(blurred, v_Texcoord);\n vec4 originalColor = texture2D(original, v_Texcoord);\n\n float fCoc = decodeFloat(texture2D(coc, v_Texcoord));\n\n fCoc = abs(fCoc * 2.0 - 1.0);\n\n float weight = smoothstep(0.0, 1.0, fCoc);\n \n#ifdef NEARFIELD_ENABLED\n vec4 nearfieldColor = texture2D(nearfield, v_Texcoord);\n float fNearCoc = decodeFloat(texture2D(nearcoc, v_Texcoord));\n fNearCoc = abs(fNearCoc * 2.0 - 1.0);\n\n gl_FragColor = encodeHDR(\n mix(\n nearfieldColor, mix(originalColor, blurredColor, weight),\n pow(1.0 - fNearCoc, 4.0)\n )\n );\n#else\n gl_FragColor = encodeHDR(mix(originalColor, blurredColor, weight));\n#endif\n\n}\n\n@end\n\n\n\n@export ecgl.dof.diskBlur\n\n#define POISSON_KERNEL_SIZE 16;\n\nuniform sampler2D texture;\nuniform sampler2D coc;\nvarying vec2 v_Texcoord;\n\nuniform float blurRadius : 10.0;\nuniform vec2 textureSize : [512.0, 512.0];\n\nuniform vec2 poissonKernel[POISSON_KERNEL_SIZE];\n\nuniform float percent;\n\nfloat nrand(const in vec2 n) {\n return fract(sin(dot(n.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\n@import clay.util.rgbm\n@import clay.util.float\n\n\nvoid main()\n{\n vec2 offset = blurRadius / textureSize;\n\n float rnd = 6.28318 * nrand(v_Texcoord + 0.07 * percent );\n float cosa = cos(rnd);\n float sina = sin(rnd);\n vec4 basis = vec4(cosa, -sina, sina, cosa);\n\n#if !defined(BLUR_NEARFIELD) && !defined(BLUR_COC)\n offset *= abs(decodeFloat(texture2D(coc, v_Texcoord)) * 2.0 - 1.0);\n#endif\n\n#ifdef BLUR_COC\n float cocSum = 0.0;\n#else\n vec4 color = vec4(0.0);\n#endif\n\n\n float weightSum = 0.0;\n\n for (int i = 0; i < POISSON_KERNEL_SIZE; i++) {\n vec2 ofs = poissonKernel[i];\n\n ofs = vec2(dot(ofs, basis.xy), dot(ofs, basis.zw));\n\n vec2 uv = v_Texcoord + ofs * offset;\n vec4 texel = texture2D(texture, uv);\n\n float w = 1.0;\n#ifdef BLUR_COC\n float fCoc = decodeFloat(texel) * 2.0 - 1.0;\n cocSum += clamp(fCoc, -1.0, 0.0) * w;\n#else\n texel = texel;\n #if !defined(BLUR_NEARFIELD)\n float fCoc = decodeFloat(texture2D(coc, uv)) * 2.0 - 1.0;\n w *= abs(fCoc);\n #endif\n texel.rgb *= texel.a;\n color += texel * w;\n#endif\n\n weightSum += w;\n }\n\n#ifdef BLUR_COC\n gl_FragColor = encodeFloat(clamp(cocSum / weightSum, -1.0, 0.0) * 0.5 + 0.5);\n#else\n color /= weightSum;\n color.rgb /= (color.a + 0.0001);\n gl_FragColor = color;\n#endif\n}\n\n@end");


/***/ }),
/* 199 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.edge\n\nuniform sampler2D texture;\n\nuniform sampler2D normalTexture;\nuniform sampler2D depthTexture;\n\nuniform mat4 projectionInv;\n\nuniform vec2 textureSize;\n\nuniform vec4 edgeColor: [0,0,0,0.8];\n\nvarying vec2 v_Texcoord;\n\nvec3 packColor(vec2 coord) {\n float z = texture2D(depthTexture, coord).r * 2.0 - 1.0;\n vec4 p = vec4(v_Texcoord * 2.0 - 1.0, z, 1.0);\n vec4 p4 = projectionInv * p;\n\n return vec3(\n texture2D(normalTexture, coord).rg,\n -p4.z / p4.w / 5.0\n );\n}\n\nvoid main() {\n vec2 cc = v_Texcoord;\n vec3 center = packColor(cc);\n\n float size = clamp(1.0 - (center.z - 10.0) / 100.0, 0.0, 1.0) * 0.5;\n float dx = size / textureSize.x;\n float dy = size / textureSize.y;\n\n vec2 coord;\n vec3 topLeft = packColor(cc+vec2(-dx, -dy));\n vec3 top = packColor(cc+vec2(0.0, -dy));\n vec3 topRight = packColor(cc+vec2(dx, -dy));\n vec3 left = packColor(cc+vec2(-dx, 0.0));\n vec3 right = packColor(cc+vec2(dx, 0.0));\n vec3 bottomLeft = packColor(cc+vec2(-dx, dy));\n vec3 bottom = packColor(cc+vec2(0.0, dy));\n vec3 bottomRight = packColor(cc+vec2(dx, dy));\n\n vec3 v = -topLeft-2.0*top-topRight+bottomLeft+2.0*bottom+bottomRight;\n vec3 h = -bottomLeft-2.0*left-topLeft+bottomRight+2.0*right+topRight;\n\n float edge = sqrt(dot(h, h) + dot(v, v));\n\n edge = smoothstep(0.8, 1.0, edge);\n\n gl_FragColor = mix(texture2D(texture, v_Texcoord), vec4(edgeColor.rgb, 1.0), edgeColor.a * edge);\n}\n@end");


/***/ }),
/* 200 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__halton__ = __webpack_require__(49);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_compositor_Pass__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__ = __webpack_require__(9);
// Temporal Super Sample for static Scene







function TemporalSuperSampling (frames) {
    var haltonSequence = [];

    for (var i = 0; i < 30; i++) {
        haltonSequence.push([Object(__WEBPACK_IMPORTED_MODULE_0__halton__["a" /* default */])(i, 2), Object(__WEBPACK_IMPORTED_MODULE_0__halton__["a" /* default */])(i, 3)]);
    }

    this._haltonSequence = haltonSequence;

    this._frame = 0;

    this._sourceTex = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture2D__["a" /* default */]();
    this._sourceFb = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_FrameBuffer__["a" /* default */]();
    this._sourceFb.attach(this._sourceTex);

    // Frame texture before temporal supersampling
    this._prevFrameTex = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture2D__["a" /* default */]();
    this._outputTex = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture2D__["a" /* default */]();

    var blendPass = this._blendPass = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('clay.compositor.blend')
    });
    blendPass.material.disableTexturesAll();
    blendPass.material.enableTexture(['texture1', 'texture2']);

    this._blendFb = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_FrameBuffer__["a" /* default */]({
        depthBuffer: false
    });

    this._outputPass = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('clay.compositor.output'),
        // TODO, alpha is premultiplied?
        blendWithPrevious: true
    });
    this._outputPass.material.define('fragment', 'OUTPUT_ALPHA');
    this._outputPass.material.blend = function (_gl) {
        // FIXME.
        // Output is premultiplied alpha when BLEND is enabled ?
        // http://stackoverflow.com/questions/2171085/opengl-blending-with-previous-contents-of-framebuffer
        _gl.blendEquationSeparate(_gl.FUNC_ADD, _gl.FUNC_ADD);
        _gl.blendFuncSeparate(_gl.ONE, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA);
    };
}

TemporalSuperSampling.prototype = {

    constructor: TemporalSuperSampling,

    /**
     * Jitter camera projectionMatrix
     * @parma {clay.Renderer} renderer
     * @param {clay.Camera} camera
     */
    jitterProjection: function (renderer, camera) {
        var viewport = renderer.viewport;
        var dpr = viewport.devicePixelRatio || renderer.getDevicePixelRatio();
        var width = viewport.width * dpr;
        var height = viewport.height * dpr;

        var offset = this._haltonSequence[this._frame % this._haltonSequence.length];

        var translationMat = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */]();
        translationMat.array[12] = (offset[0] * 2.0 - 1.0) / width;
        translationMat.array[13] = (offset[1] * 2.0 - 1.0) / height;

        __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */].mul(camera.projectionMatrix, translationMat, camera.projectionMatrix);

        __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */].invert(camera.invProjectionMatrix, camera.projectionMatrix);
    },

    /**
     * Reset accumulating frame
     */
    resetFrame: function () {
        this._frame = 0;
    },

    /**
     * Return current frame
     */
    getFrame: function () {
        return this._frame;
    },

    /**
     * Get source framebuffer for usage
     */
    getSourceFrameBuffer: function () {
        return this._sourceFb;
    },

    getOutputTexture: function () {
        return this._outputTex;
    },

    resize: function (width, height) {
        this._prevFrameTex.width = width;
        this._prevFrameTex.height = height;

        this._outputTex.width = width;
        this._outputTex.height = height;

        this._sourceTex.width = width;
        this._sourceTex.height = height;

        this._prevFrameTex.dirty();
        this._outputTex.dirty();
        this._sourceTex.dirty();
    },

    isFinished: function () {
        return this._frame >= this._haltonSequence.length;
    },

    render: function (renderer, sourceTex, notOutput) {
        var blendPass = this._blendPass;
        if (this._frame === 0) {
            // Direct output
            blendPass.setUniform('weight1', 0);
            blendPass.setUniform('weight2', 1);
        }
        else {
            blendPass.setUniform('weight1', 0.9);
            blendPass.setUniform('weight2', 0.1);
        }
        blendPass.setUniform('texture1', this._prevFrameTex);
        blendPass.setUniform('texture2', sourceTex || this._sourceTex);

        this._blendFb.attach(this._outputTex);
        this._blendFb.bind(renderer);
        blendPass.render(renderer);
        this._blendFb.unbind(renderer);

        if (!notOutput) {
            this._outputPass.setUniform('texture', this._outputTex);
            this._outputPass.render(renderer);
        }

        // Swap texture
        var tmp = this._prevFrameTex;
        this._prevFrameTex = this._outputTex;
        this._outputTex = tmp;

        this._frame++;
    },

    dispose: function (renderer) {
        this._sourceFb.dispose(renderer);
        this._blendFb.dispose(renderer);
        this._prevFrameTex.dispose(renderer);
        this._outputTex.dispose(renderer);
        this._sourceTex.dispose(renderer);
        this._outputPass.dispose(renderer);
        this._blendPass.dispose(renderer);
    }
};

/* harmony default export */ __webpack_exports__["a"] = (TemporalSuperSampling);

/***/ }),
/* 201 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__geo3D_Geo3DModel__ = __webpack_require__(202);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__geo3D_Geo3DView__ = __webpack_require__(203);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__coord_geo3DCreator__ = __webpack_require__(98);







__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'geo3DChangeCamera',
    event: 'geo3dcamerachanged',
    update: 'series:updateCamera'
}, function (payload, ecModel) {
    ecModel.eachComponent({
        mainType: 'geo3D', query: payload
    }, function (componentModel) {
        componentModel.setView(payload);
    });
});

/***/ }),
/* 202 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_componentViewControlMixin__ = __webpack_require__(44);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_componentPostEffectMixin__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_componentLightMixin__ = __webpack_require__(29);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_componentShadingMixin__ = __webpack_require__(31);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__coord_geo3D_geo3DModelMixin__ = __webpack_require__(96);







var Geo3DModel = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentModel({

    type: 'geo3D',

    layoutMode: 'box',

    coordinateSystem: null,

    optionUpdated: function () {
        var option = this.option;

        option.regions = this.getFilledRegions(option.regions, option.map);

        var dimensions = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.completeDimensions(['value'], option.data, {
            encodeDef: this.get('encode'),
            dimsDef: this.get('dimensions')
        });
        var list = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(dimensions, this);
        list.initData(option.regions);

        var regionModelMap = {};
        list.each(function (idx) {
            var name = list.getName(idx);
            var itemModel = list.getItemModel(idx);
            regionModelMap[name] = itemModel;
        });

        this._regionModelMap = regionModelMap;

        this._data = list;
    },

    getData: function () {
        return this._data;
    },

    getRegionModel: function (idx) {
        var name = this.getData().getName(idx);
        return this._regionModelMap[name] || new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Model(null, this);
    },

    getRegionPolygonCoords: function (idx) {
        var name = this.getData().getName(idx);
        var region = this.coordinateSystem.getRegion(name);

        return region ? region.geometries : [];
    },

    /**
     * Format label
     * @param {string} name Region name
     * @param {string} [status='normal'] 'normal' or 'emphasis'
     * @return {string}
     */
    getFormattedLabel: function (dataIndex, status) {
        var name = this._data.getName(dataIndex);
        var regionModel = this.getRegionModel(name);
        var formatter = regionModel.get(status === 'normal' ? ['label', 'formatter'] : ['emphasis', 'label', 'formatter']);
        if (formatter == null) {
            formatter = regionModel.get(['label', 'formatter']);
        }
        var params = {
            name: name
        };
        if (typeof formatter === 'function') {
            params.status = status;
            return formatter(params);
        }
        else if (typeof formatter === 'string') {
            var serName = params.seriesName;
            return formatter.replace('{a}', serName != null ? serName : '');
        }
        else {
            return name;
        }
    },

    defaultOption: {

        // itemStyle: {},
        // height,
        // label: {}
        // realisticMaterial
        regions: []
    }
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Geo3DModel.prototype, __WEBPACK_IMPORTED_MODULE_5__coord_geo3D_geo3DModelMixin__["a" /* default */]);

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Geo3DModel.prototype, __WEBPACK_IMPORTED_MODULE_1__common_componentViewControlMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Geo3DModel.prototype, __WEBPACK_IMPORTED_MODULE_2__common_componentPostEffectMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Geo3DModel.prototype, __WEBPACK_IMPORTED_MODULE_3__common_componentLightMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Geo3DModel.prototype, __WEBPACK_IMPORTED_MODULE_4__common_componentShadingMixin__["a" /* default */]);

/* unused harmony default export */ var _unused_webpack_default_export = (Geo3DModel);

/***/ }),
/* 203 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common_Geo3DBuilder__ = __webpack_require__(64);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_OrbitControl__ = __webpack_require__(45);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_SceneHelper__ = __webpack_require__(30);







/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.extendComponentView({

    type: 'geo3D',

    __ecgl__: true,

    init: function (ecModel, api) {

        this._geo3DBuilder = new __WEBPACK_IMPORTED_MODULE_0__common_Geo3DBuilder__["a" /* default */](api);
        this.groupGL = new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Node();

        this._lightRoot = new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Node();
        this._sceneHelper = new __WEBPACK_IMPORTED_MODULE_4__common_SceneHelper__["a" /* default */](this._lightRoot);
        this._sceneHelper.initLight(this._lightRoot);

        this._control = new __WEBPACK_IMPORTED_MODULE_3__util_OrbitControl__["a" /* default */]({
            zr: api.getZr()
        });
        this._control.init();
    },

    render: function (geo3DModel, ecModel, api) {
        this.groupGL.add(this._geo3DBuilder.rootNode);

        var geo3D = geo3DModel.coordinateSystem;

        if (!geo3D || !geo3D.viewGL) {
            return;
        }

        // Always have light.
        geo3D.viewGL.add(this._lightRoot);

        if (geo3DModel.get('show')) {
            geo3D.viewGL.add(this.groupGL);
        }
        else {
            geo3D.viewGL.remove(this.groupGL);
        }

        var control = this._control;
        control.setViewGL(geo3D.viewGL);

        var viewControlModel = geo3DModel.getModel('viewControl');
        control.setFromViewControlModel(viewControlModel, 0);

        this._sceneHelper.setScene(geo3D.viewGL.scene);
        this._sceneHelper.updateLight(geo3DModel);

        // Set post effect
        geo3D.viewGL.setPostEffect(geo3DModel.getModel('postEffect'), api);
        geo3D.viewGL.setTemporalSuperSampling(geo3DModel.getModel('temporalSuperSampling'));

        // Must update after geo3D.viewGL.setPostEffect
        this._geo3DBuilder.update(geo3DModel, ecModel, api, 0, geo3DModel.getData().count());
        var srgbDefineMethod = geo3D.viewGL.isLinearSpace() ? 'define' : 'undefine';
        this._geo3DBuilder.rootNode.traverse(function (mesh) {
            if (mesh.material) {
                mesh.material[srgbDefineMethod]('fragment', 'SRGB_DECODE');
            }
        });

        control.off('update');
        control.on('update', function () {
            api.dispatchAction({
                type: 'geo3DChangeCamera',
                alpha: control.getAlpha(),
                beta: control.getBeta(),
                distance: control.getDistance(),
                center: control.getCenter(),
                from: this.uid,
                geo3DId: geo3DModel.id
            });
        });
        control.update();
    },

    afterRender: function (geo3DModel, ecModel, api, layerGL) {
        var renderer = layerGL.renderer;
        this._sceneHelper.updateAmbientCubemap(renderer, geo3DModel, api);

        this._sceneHelper.updateSkybox(renderer, geo3DModel, api);
    },

    dispose: function () {
        this._control.dispose();
    }
}));

/***/ }),
/* 204 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
// https://github.com/mapbox/earcut/blob/master/src/earcut.js

/* harmony default export */ __webpack_exports__["a"] = (earcut);

function earcut(data, holeIndices, dim) {

    dim = dim || 2;

    var hasHoles = holeIndices && holeIndices.length,
        outerLen = hasHoles ? holeIndices[0] * dim : data.length,
        outerNode = linkedList(data, 0, outerLen, dim, true),
        triangles = [];

    if (!outerNode) return triangles;

    var minX, minY, maxX, maxY, x, y, size;

    if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);

    // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
    if (data.length > 80 * dim) {
        minX = maxX = data[0];
        minY = maxY = data[1];

        for (var i = dim; i < outerLen; i += dim) {
            x = data[i];
            y = data[i + 1];
            if (x < minX) minX = x;
            if (y < minY) minY = y;
            if (x > maxX) maxX = x;
            if (y > maxY) maxY = y;
        }

        // minX, minY and size are later used to transform coords into integers for z-order calculation
        size = Math.max(maxX - minX, maxY - minY);
    }

    earcutLinked(outerNode, triangles, dim, minX, minY, size);

    return triangles;
}

// create a circular doubly linked list from polygon points in the specified winding order
function linkedList(data, start, end, dim, clockwise) {
    var i, last;

    if (clockwise === (signedArea(data, start, end, dim) > 0)) {
        for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
    } else {
        for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
    }

    if (last && equals(last, last.next)) {
        removeNode(last);
        last = last.next;
    }

    return last;
}

// eliminate colinear or duplicate points
function filterPoints(start, end) {
    if (!start) return start;
    if (!end) end = start;

    var p = start,
        again;
    do {
        again = false;

        if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
            removeNode(p);
            p = end = p.prev;
            if (p === p.next) return null;
            again = true;

        } else {
            p = p.next;
        }
    } while (again || p !== end);

    return end;
}

// main ear slicing loop which triangulates a polygon (given as a linked list)
function earcutLinked(ear, triangles, dim, minX, minY, size, pass) {
    if (!ear) return;

    // interlink polygon nodes in z-order
    if (!pass && size) indexCurve(ear, minX, minY, size);

    var stop = ear,
        prev, next;

    // iterate through ears, slicing them one by one
    while (ear.prev !== ear.next) {
        prev = ear.prev;
        next = ear.next;

        if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {
            // cut off the triangle
            triangles.push(prev.i / dim);
            triangles.push(ear.i / dim);
            triangles.push(next.i / dim);

            removeNode(ear);

            // skipping the next vertice leads to less sliver triangles
            ear = next.next;
            stop = next.next;

            continue;
        }

        ear = next;

        // if we looped through the whole remaining polygon and can't find any more ears
        if (ear === stop) {
            // try filtering points and slicing again
            if (!pass) {
                earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);

            // if this didn't work, try curing all small self-intersections locally
            } else if (pass === 1) {
                ear = cureLocalIntersections(ear, triangles, dim);
                earcutLinked(ear, triangles, dim, minX, minY, size, 2);

            // as a last resort, try splitting the remaining polygon into two
            } else if (pass === 2) {
                splitEarcut(ear, triangles, dim, minX, minY, size);
            }

            break;
        }
    }
}

// check whether a polygon node forms a valid ear with adjacent nodes
function isEar(ear) {
    var a = ear.prev,
        b = ear,
        c = ear.next;

    if (area(a, b, c) >= 0) return false; // reflex, can't be an ear

    // now make sure we don't have other points inside the potential ear
    var p = ear.next.next;

    while (p !== ear.prev) {
        if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
            area(p.prev, p, p.next) >= 0) return false;
        p = p.next;
    }

    return true;
}

function isEarHashed(ear, minX, minY, size) {
    var a = ear.prev,
        b = ear,
        c = ear.next;

    if (area(a, b, c) >= 0) return false; // reflex, can't be an ear

    // triangle bbox; min & max are calculated like this for speed
    var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),
        minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),
        maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),
        maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);

    // z-order range for the current triangle bbox;
    var minZ = zOrder(minTX, minTY, minX, minY, size),
        maxZ = zOrder(maxTX, maxTY, minX, minY, size);

    // first look for points inside the triangle in increasing z-order
    var p = ear.nextZ;

    while (p && p.z <= maxZ) {
        if (p !== ear.prev && p !== ear.next &&
            pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
            area(p.prev, p, p.next) >= 0) return false;
        p = p.nextZ;
    }

    // then look for points in decreasing z-order
    p = ear.prevZ;

    while (p && p.z >= minZ) {
        if (p !== ear.prev && p !== ear.next &&
            pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
            area(p.prev, p, p.next) >= 0) return false;
        p = p.prevZ;
    }

    return true;
}

// go through all polygon nodes and cure small local self-intersections
function cureLocalIntersections(start, triangles, dim) {
    var p = start;
    do {
        var a = p.prev,
            b = p.next.next;

        if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {

            triangles.push(a.i / dim);
            triangles.push(p.i / dim);
            triangles.push(b.i / dim);

            // remove two nodes involved
            removeNode(p);
            removeNode(p.next);

            p = start = b;
        }
        p = p.next;
    } while (p !== start);

    return p;
}

// try splitting polygon into two and triangulate them independently
function splitEarcut(start, triangles, dim, minX, minY, size) {
    // look for a valid diagonal that divides the polygon into two
    var a = start;
    do {
        var b = a.next.next;
        while (b !== a.prev) {
            if (a.i !== b.i && isValidDiagonal(a, b)) {
                // split the polygon in two by the diagonal
                var c = splitPolygon(a, b);

                // filter colinear points around the cuts
                a = filterPoints(a, a.next);
                c = filterPoints(c, c.next);

                // run earcut on each half
                earcutLinked(a, triangles, dim, minX, minY, size);
                earcutLinked(c, triangles, dim, minX, minY, size);
                return;
            }
            b = b.next;
        }
        a = a.next;
    } while (a !== start);
}

// link every hole into the outer loop, producing a single-ring polygon without holes
function eliminateHoles(data, holeIndices, outerNode, dim) {
    var queue = [],
        i, len, start, end, list;

    for (i = 0, len = holeIndices.length; i < len; i++) {
        start = holeIndices[i] * dim;
        end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
        list = linkedList(data, start, end, dim, false);
        if (list === list.next) list.steiner = true;
        queue.push(getLeftmost(list));
    }

    queue.sort(compareX);

    // process holes from left to right
    for (i = 0; i < queue.length; i++) {
        eliminateHole(queue[i], outerNode);
        outerNode = filterPoints(outerNode, outerNode.next);
    }

    return outerNode;
}

function compareX(a, b) {
    return a.x - b.x;
}

// find a bridge between vertices that connects hole with an outer ring and and link it
function eliminateHole(hole, outerNode) {
    outerNode = findHoleBridge(hole, outerNode);
    if (outerNode) {
        var b = splitPolygon(outerNode, hole);
        filterPoints(b, b.next);
    }
}

// David Eberly's algorithm for finding a bridge between hole and outer polygon
function findHoleBridge(hole, outerNode) {
    var p = outerNode,
        hx = hole.x,
        hy = hole.y,
        qx = -Infinity,
        m;

    // find a segment intersected by a ray from the hole's leftmost point to the left;
    // segment's endpoint with lesser x will be potential connection point
    do {
        if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
            var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
            if (x <= hx && x > qx) {
                qx = x;
                if (x === hx) {
                    if (hy === p.y) return p;
                    if (hy === p.next.y) return p.next;
                }
                m = p.x < p.next.x ? p : p.next;
            }
        }
        p = p.next;
    } while (p !== outerNode);

    if (!m) return null;

    if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint

    // look for points inside the triangle of hole point, segment intersection and endpoint;
    // if there are no points found, we have a valid connection;
    // otherwise choose the point of the minimum angle with the ray as connection point

    var stop = m,
        mx = m.x,
        my = m.y,
        tanMin = Infinity,
        tan;

    p = m.next;

    while (p !== stop) {
        if (hx >= p.x && p.x >= mx && hx !== p.x &&
                pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {

            tan = Math.abs(hy - p.y) / (hx - p.x); // tangential

            if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) {
                m = p;
                tanMin = tan;
            }
        }

        p = p.next;
    }

    return m;
}

// interlink polygon nodes in z-order
function indexCurve(start, minX, minY, size) {
    var p = start;
    do {
        if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);
        p.prevZ = p.prev;
        p.nextZ = p.next;
        p = p.next;
    } while (p !== start);

    p.prevZ.nextZ = null;
    p.prevZ = null;

    sortLinked(p);
}

// Simon Tatham's linked list merge sort algorithm
// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
function sortLinked(list) {
    var i, p, q, e, tail, numMerges, pSize, qSize,
        inSize = 1;

    do {
        p = list;
        list = null;
        tail = null;
        numMerges = 0;

        while (p) {
            numMerges++;
            q = p;
            pSize = 0;
            for (i = 0; i < inSize; i++) {
                pSize++;
                q = q.nextZ;
                if (!q) break;
            }
            qSize = inSize;

            while (pSize > 0 || (qSize > 0 && q)) {

                if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
                    e = p;
                    p = p.nextZ;
                    pSize--;
                } else {
                    e = q;
                    q = q.nextZ;
                    qSize--;
                }

                if (tail) tail.nextZ = e;
                else list = e;

                e.prevZ = tail;
                tail = e;
            }

            p = q;
        }

        tail.nextZ = null;
        inSize *= 2;

    } while (numMerges > 1);

    return list;
}

// z-order of a point given coords and size of the data bounding box
function zOrder(x, y, minX, minY, size) {
    // coords are transformed into non-negative 15-bit integer range
    x = 32767 * (x - minX) / size;
    y = 32767 * (y - minY) / size;

    x = (x | (x << 8)) & 0x00FF00FF;
    x = (x | (x << 4)) & 0x0F0F0F0F;
    x = (x | (x << 2)) & 0x33333333;
    x = (x | (x << 1)) & 0x55555555;

    y = (y | (y << 8)) & 0x00FF00FF;
    y = (y | (y << 4)) & 0x0F0F0F0F;
    y = (y | (y << 2)) & 0x33333333;
    y = (y | (y << 1)) & 0x55555555;

    return x | (y << 1);
}

// find the leftmost node of a polygon ring
function getLeftmost(start) {
    var p = start,
        leftmost = start;
    do {
        if (p.x < leftmost.x) leftmost = p;
        p = p.next;
    } while (p !== start);

    return leftmost;
}

// check if a point lies within a convex triangle
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
    return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&
           (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&
           (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
}

// check if a diagonal between two polygon nodes is valid (lies in polygon interior)
function isValidDiagonal(a, b) {
    return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) &&
           locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);
}

// signed area of a triangle
function area(p, q, r) {
    return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
}

// check if two points are equal
function equals(p1, p2) {
    return p1.x === p2.x && p1.y === p2.y;
}

// check if two segments intersect
function intersects(p1, q1, p2, q2) {
    if ((equals(p1, q1) && equals(p2, q2)) ||
        (equals(p1, q2) && equals(p2, q1))) return true;
    return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 &&
           area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;
}

// check if a polygon diagonal intersects any polygon segments
function intersectsPolygon(a, b) {
    var p = a;
    do {
        if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
                intersects(p, p.next, a, b)) return true;
        p = p.next;
    } while (p !== a);

    return false;
}

// check if a polygon diagonal is locally inside the polygon
function locallyInside(a, b) {
    return area(a.prev, a, a.next) < 0 ?
        area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :
        area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
}

// check if the middle point of a polygon diagonal is inside the polygon
function middleInside(a, b) {
    var p = a,
        inside = false,
        px = (a.x + b.x) / 2,
        py = (a.y + b.y) / 2;
    do {
        if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&
                (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))
            inside = !inside;
        p = p.next;
    } while (p !== a);

    return inside;
}

// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
// if one belongs to the outer ring and another to a hole, it merges it into a single ring
function splitPolygon(a, b) {
    var a2 = new Node(a.i, a.x, a.y),
        b2 = new Node(b.i, b.x, b.y),
        an = a.next,
        bp = b.prev;

    a.next = b;
    b.prev = a;

    a2.next = an;
    an.prev = a2;

    b2.next = a2;
    a2.prev = b2;

    bp.next = b2;
    b2.prev = bp;

    return b2;
}

// create a node and optionally link it with previous one (in a circular doubly linked list)
function insertNode(i, x, y, last) {
    var p = new Node(i, x, y);

    if (!last) {
        p.prev = p;
        p.next = p;

    } else {
        p.next = last.next;
        p.prev = last;
        last.next.prev = p;
        last.next = p;
    }
    return p;
}

function removeNode(p) {
    p.next.prev = p.prev;
    p.prev.next = p.next;

    if (p.prevZ) p.prevZ.nextZ = p.nextZ;
    if (p.nextZ) p.nextZ.prevZ = p.prevZ;
}

function Node(i, x, y) {
    // vertice index in coordinates array
    this.i = i;

    // vertex coordinates
    this.x = x;
    this.y = y;

    // previous and next vertice nodes in a polygon ring
    this.prev = null;
    this.next = null;

    // z-order curve value
    this.z = null;

    // previous and next nodes in z-order
    this.prevZ = null;
    this.nextZ = null;

    // indicates whether this is a steiner point
    this.steiner = false;
}

// return a percentage difference between the polygon area and its triangulation area;
// used to verify correctness of triangulation
earcut.deviation = function (data, holeIndices, dim, triangles) {
    var hasHoles = holeIndices && holeIndices.length;
    var outerLen = hasHoles ? holeIndices[0] * dim : data.length;

    var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
    if (hasHoles) {
        for (var i = 0, len = holeIndices.length; i < len; i++) {
            var start = holeIndices[i] * dim;
            var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
            polygonArea -= Math.abs(signedArea(data, start, end, dim));
        }
    }

    var trianglesArea = 0;
    for (i = 0; i < triangles.length; i += 3) {
        var a = triangles[i] * dim;
        var b = triangles[i + 1] * dim;
        var c = triangles[i + 2] * dim;
        trianglesArea += Math.abs(
            (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -
            (data[a] - data[b]) * (data[c + 1] - data[a + 1]));
    }

    return polygonArea === 0 && trianglesArea === 0 ? 0 :
        Math.abs((trianglesArea - polygonArea) / polygonArea);
};

function signedArea(data, start, end, dim) {
    var sum = 0;
    for (var i = start, j = end - dim; i < end; i += dim) {
        sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
        j = i;
    }
    return sum;
}

/***/ }),
/* 205 */
/***/ (function(module, exports, __webpack_require__) {

var zrUtil = __webpack_require__(13);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var coordsOffsetMap = {
  '南海诸岛': [32, 80],
  // 全国
  '广东': [0, -10],
  '香港': [10, 5],
  '澳门': [-10, 10],
  //'北京': [-10, 0],
  '天津': [5, 5]
};

function _default(geo) {
  zrUtil.each(geo.regions, function (region) {
    var coordFix = coordsOffsetMap[region.name];

    if (coordFix) {
      var cp = region.center;
      cp[0] += coordFix[0] / 10.5;
      cp[1] += -coordFix[1] / (10.5 / 0.75);
    }
  });
}

module.exports = _default;

/***/ }),
/* 206 */
/***/ (function(module, exports, __webpack_require__) {

var zrUtil = __webpack_require__(13);

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

function _default(geo) {
  zrUtil.each(geo.regions, function (region) {
    var geoCoord = geoCoordMap[region.name];

    if (geoCoord) {
      var cp = region.center;
      cp[0] = geoCoord[0];
      cp[1] = geoCoord[1];
    }
  });
}

module.exports = _default;

/***/ }),
/* 207 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__globe_GlobeModel__ = __webpack_require__(208);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__globe_GlobeView__ = __webpack_require__(209);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__coord_globeCreator__ = __webpack_require__(211);







__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'globeChangeCamera',
    event: 'globecamerachanged',
    update: 'series:updateCamera'
}, function (payload, ecModel) {
    ecModel.eachComponent({
        mainType: 'globe', query: payload
    }, function (componentModel) {
        componentModel.setView(payload);
    });
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'globeUpdateDisplacment',
    event: 'globedisplacementupdated',
    update: 'update'
}, function (payload, ecModel) {
    // Noop
});

/***/ }),
/* 208 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_componentViewControlMixin__ = __webpack_require__(44);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_componentPostEffectMixin__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_componentLightMixin__ = __webpack_require__(29);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_componentShadingMixin__ = __webpack_require__(31);







function defaultId(option, idx) {
    option.id = option.id || option.name || (idx + '');
}
var GlobeModel = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentModel({

    type: 'globe',

    layoutMode: 'box',

    coordinateSystem: null,

    init: function () {
        GlobeModel.superApply(this, 'init', arguments);

        __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(this.option.layers, function (layerOption, idx) {
            __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(layerOption, this.defaultLayerOption);
            defaultId(layerOption, idx);
        }, this);
    },

    mergeOption: function (option) {
        // TODO test
        var oldLayers = this.option.layers;
        this.option.layers = null;
        GlobeModel.superApply(this, 'mergeOption', arguments);

        function createLayerMap(layers) {
            return __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.reduce(layers, function (obj, layerOption, idx) {
                defaultId(layerOption, idx);
                obj[layerOption.id] = layerOption;
                return obj;
            }, {});
        }
        if (oldLayers && oldLayers.length) {
            var newLayerMap = createLayerMap(option.layers);
            var oldLayerMap = createLayerMap(oldLayers);
            for (var id in newLayerMap) {
                if (oldLayerMap[id]) {
                    __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(oldLayerMap[id], newLayerMap[id], true);
                }
                else {
                    oldLayers.push(option.layers[id]);
                }
            }
            // Copy back
            this.option.layers = oldLayers;
        }
        // else overwrite

        // Set default
        __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(this.option.layers, function (layerOption) {
            __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(layerOption, this.defaultLayerOption);
        }, this);
    },

    optionUpdated: function () {
        this.updateDisplacementHash();
    },

    defaultLayerOption: {
        show: true,
        type: 'overlay'
    },

    defaultOption: {

        show: true,

        zlevel: -10,

        // Layout used for viewport
        left: 0,
        top: 0,
        width: '100%',
        height: '100%',

        environment: 'auto',

        baseColor: '#fff',

        // Base albedo texture
        baseTexture: '',

        // Height texture for bump mapping and vertex displacement
        heightTexture: '',

        // Texture for vertex displacement, default use heightTexture
        displacementTexture: '',
        // Scale of vertex displacement, available only if displacementTexture is set.
        displacementScale: 0,

        // Detail of displacement. 'low', 'medium', 'high', 'ultra'
        displacementQuality: 'medium',

        // Globe radius
        globeRadius: 100,

        // Globe outer radius. Which is max of altitude.
        globeOuterRadius: 150,

        // Shading of globe
        shading: 'lambert',

        // Extend light
        light: {
            // Main sun light
            main: {
                // Time, default it will use system time
                time: ''
            }
        },

        // light
        // postEffect
        // temporalSuperSampling

        viewControl: {
            autoRotate: true,

            panSensitivity: 0,

            targetCoord: null
        },


        // {
        //     show: true,
        //     name: 'cloud',
        //     type: 'overlay',
        //     shading: 'lambert',
        //     distance: 10,
        //     texture: ''
        // }
        // {
        //     type: 'blend',
        //     blendTo: 'albedo'
        //     blendType: 'source-over'
        // }

        layers: []
    },

    setDisplacementData: function (data, width, height) {
        this.displacementData = data;
        this.displacementWidth = width;
        this.displacementHeight = height;
    },

    getDisplacementTexture: function () {
        return this.get('displacementTexture') || this.get('heightTexture');
    },

    getDisplacemenScale: function () {
        var displacementTexture = this.getDisplacementTexture();
        var displacementScale = this.get('displacementScale');
        if (!displacementTexture || displacementTexture === 'none') {
            displacementScale = 0;
        }
        return displacementScale;
    },

    hasDisplacement: function () {
        return this.getDisplacemenScale() > 0;
    },

    _displacementChanged: true,

    _displacementScale: 0,

    updateDisplacementHash: function () {
        var displacementTexture = this.getDisplacementTexture();
        var displacementScale = this.getDisplacemenScale();

        this._displacementChanged =
            this._displacementTexture !== displacementTexture
            || this._displacementScale !== displacementScale;

        this._displacementTexture = displacementTexture;
        this._displacementScale = displacementScale;
    },

    isDisplacementChanged: function () {
        return this._displacementChanged;
    }
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(GlobeModel.prototype, __WEBPACK_IMPORTED_MODULE_1__common_componentViewControlMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(GlobeModel.prototype, __WEBPACK_IMPORTED_MODULE_2__common_componentPostEffectMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(GlobeModel.prototype, __WEBPACK_IMPORTED_MODULE_3__common_componentLightMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(GlobeModel.prototype, __WEBPACK_IMPORTED_MODULE_4__common_componentShadingMixin__["a" /* default */]);

/* unused harmony default export */ var _unused_webpack_default_export = (GlobeModel);

/***/ }),
/* 209 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_OrbitControl__ = __webpack_require__(45);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_SceneHelper__ = __webpack_require__(30);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_sunCalc__ = __webpack_require__(210);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_retrieve__ = __webpack_require__(2);









/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentView({

    type: 'globe',

    __ecgl__: true,

    _displacementScale: 0,

    init: function (ecModel, api) {
        this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();

        /**
         * @type {clay.geometry.Sphere}
         * @private
         */
        this._sphereGeometry = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].SphereGeometry({
            widthSegments: 200,
            heightSegments: 100,
            dynamic: true
        });
        this._overlayGeometry = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].SphereGeometry({
            widthSegments: 80,
            heightSegments: 40
        });

        /**
         * @type {clay.geometry.Plane}
         */
        this._planeGeometry = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].PlaneGeometry();

        /**
         * @type {clay.geometry.Mesh}
         */
        this._earthMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
            renderNormal: true
        });

        this._lightRoot = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
        this._sceneHelper = new __WEBPACK_IMPORTED_MODULE_3__common_SceneHelper__["a" /* default */]();
        this._sceneHelper.initLight(this._lightRoot);

        this.groupGL.add(this._earthMesh);

        this._control = new __WEBPACK_IMPORTED_MODULE_2__util_OrbitControl__["a" /* default */]({
            zr: api.getZr()
        });

        this._control.init();

        this._layerMeshes = {};
    },

    render: function (globeModel, ecModel, api) {
        var coordSys = globeModel.coordinateSystem;
        var shading = globeModel.get('shading');

        // Always have light.
        coordSys.viewGL.add(this._lightRoot);

        if (globeModel.get('show')) {
            // Add self to scene;
            coordSys.viewGL.add(this.groupGL);
        }
        else {
            coordSys.viewGL.remove(this.groupGL);
        }

        this._sceneHelper.setScene(coordSys.viewGL.scene);

        // Set post effect
        coordSys.viewGL.setPostEffect(globeModel.getModel('postEffect'), api);
        coordSys.viewGL.setTemporalSuperSampling(globeModel.getModel('temporalSuperSampling'));

        var earthMesh = this._earthMesh;

        earthMesh.geometry = this._sphereGeometry;

        var shadingPrefix = 'ecgl.' + shading;
        if (!earthMesh.material || earthMesh.material.shader.name !== shadingPrefix) {
            earthMesh.material = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createMaterial(shadingPrefix);
        }

        __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].setMaterialFromModel(
            shading, earthMesh.material, globeModel, api
        );
        ['roughnessMap', 'metalnessMap', 'detailMap', 'normalMap'].forEach(function (texName) {
            var texture = earthMesh.material.get(texName);
            if (texture) {
                texture.flipY = false;
            }
        })

        earthMesh.material.set('color', __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(
            globeModel.get('baseColor')
        ));

        // shrink a little
        var scale = coordSys.radius * 0.99;
        earthMesh.scale.set(scale, scale, scale);

        var diffuseTexture = earthMesh.material.setTextureImage('diffuseMap', globeModel.get('baseTexture'), api, {
            flipY: false,
            anisotropic: 8
        });
        if (diffuseTexture && diffuseTexture.surface) {
            diffuseTexture.surface.attachToMesh(earthMesh);
        }

        // Update bump map
        var bumpTexture = earthMesh.material.setTextureImage('bumpMap', globeModel.get('heightTexture'), api, {
            flipY: false,
            anisotropic: 8
        });
        if (bumpTexture && bumpTexture.surface) {
            bumpTexture.surface.attachToMesh(earthMesh);
        }

        earthMesh.material[globeModel.get('postEffect.enable') ? 'define' : 'undefine']('fragment', 'SRGB_DECODE');

        this._updateLight(globeModel, api);

        this._displaceVertices(globeModel, api);

        this._updateViewControl(globeModel, api);

        this._updateLayers(globeModel, api);
    },

    afterRender: function (globeModel, ecModel, api, layerGL) {
        // Create ambient cubemap after render because we need to know the renderer.
        // TODO
        var renderer = layerGL.renderer;

        this._sceneHelper.updateAmbientCubemap(renderer, globeModel, api);

        this._sceneHelper.updateSkybox(renderer, globeModel, api);
    },


    _updateLayers: function (globeModel, api) {
        var coordSys = globeModel.coordinateSystem;
        var layers = globeModel.get('layers');

        var lastDistance = coordSys.radius;
        var layerDiffuseTextures = [];
        var layerDiffuseIntensity = [];

        var layerEmissiveTextures = [];
        var layerEmissionIntensity = [];
        __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(layers, function (layerOption) {
            var layerModel = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Model(layerOption);
            var layerType = layerModel.get('type');

            var texture = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].loadTexture(layerModel.get('texture'), api, {
                flipY: false,
                anisotropic: 8
            });
            if (texture.surface) {
                texture.surface.attachToMesh(this._earthMesh);
            }

            if (layerType === 'blend') {
                var blendTo = layerModel.get('blendTo');
                var intensity = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(layerModel.get('intensity'), 1.0);
                if (blendTo === 'emission') {
                    layerEmissiveTextures.push(texture);
                    layerEmissionIntensity.push(intensity);
                }
                else { // Default is albedo
                    layerDiffuseTextures.push(texture);
                    layerDiffuseIntensity.push(intensity);
                }
            }
            else { // Default use overlay
                var id = layerModel.get('id');
                var overlayMesh = this._layerMeshes[id];
                if (!overlayMesh) {
                    overlayMesh = this._layerMeshes[id] = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
                        geometry: this._overlayGeometry,
                        castShadow: false,
                        ignorePicking: true
                    });
                }
                var shading = layerModel.get('shading');

                if (shading === 'lambert') {
                    overlayMesh.material = overlayMesh.__lambertMaterial || new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
                        autoUpdateTextureStatus: false,
                        shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.lambert'),
                        transparent: true,
                        depthMask: false
                    });
                    overlayMesh.__lambertMaterial = overlayMesh.material;
                }
                else { // color
                    overlayMesh.material = overlayMesh.__colorMaterial || new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
                        autoUpdateTextureStatus: false,
                        shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.color'),
                        transparent: true,
                        depthMask: false
                    });
                    overlayMesh.__colorMaterial = overlayMesh.material;
                }
                // overlay should be transparent if texture is not loaded yet.
                overlayMesh.material.enableTexture('diffuseMap');

                var distance = layerModel.get('distance');
                // Based on distance of last layer
                var radius = lastDistance + (distance == null ? coordSys.radius / 100 : distance);
                overlayMesh.scale.set(radius, radius, radius);

                lastDistance = radius;

                // FIXME Exists blink.
                var blankTexture = this._blankTexture || (this._blankTexture = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createBlankTexture('rgba(255, 255, 255, 0)'));
                overlayMesh.material.set('diffuseMap', blankTexture);

                __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].loadTexture(layerModel.get('texture'), api, {
                    flipY: false,
                    anisotropic: 8
                }, function (texture) {
                    if (texture.surface) {
                        texture.surface.attachToMesh(overlayMesh);
                    }
                    overlayMesh.material.set('diffuseMap', texture);
                    api.getZr().refresh();
                });

                layerModel.get('show') ? this.groupGL.add(overlayMesh) : this.groupGL.remove(overlayMesh);
            }
        }, this);

        var earthMaterial = this._earthMesh.material;
        earthMaterial.define('fragment', 'LAYER_DIFFUSEMAP_COUNT', layerDiffuseTextures.length);
        earthMaterial.define('fragment', 'LAYER_EMISSIVEMAP_COUNT', layerEmissiveTextures.length);

        earthMaterial.set('layerDiffuseMap', layerDiffuseTextures);
        earthMaterial.set('layerDiffuseIntensity', layerDiffuseIntensity);
        earthMaterial.set('layerEmissiveMap', layerEmissiveTextures);
        earthMaterial.set('layerEmissionIntensity', layerEmissionIntensity);

        var debugWireframeModel = globeModel.getModel('debug.wireframe');
        if (debugWireframeModel.get('show')) {
            earthMaterial.define('both', 'WIREFRAME_TRIANGLE');
            var color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(
                debugWireframeModel.get('lineStyle.color') || 'rgba(0,0,0,0.5)'
            );
            var width = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(
                debugWireframeModel.get('lineStyle.width'), 1
            );
            earthMaterial.set('wireframeLineWidth', width);
            earthMaterial.set('wireframeLineColor', color);
        }
        else {
            earthMaterial.undefine('both', 'WIREFRAME_TRIANGLE');
        }
    },

    _updateViewControl: function (globeModel, api) {
        var coordSys = globeModel.coordinateSystem;
        // Update camera
        var viewControlModel = globeModel.getModel('viewControl');

        var camera = coordSys.viewGL.camera;
        var self = this;

        function makeAction() {
            return {
                type: 'globeChangeCamera',
                alpha: control.getAlpha(),
                beta: control.getBeta(),
                distance: control.getDistance() - coordSys.radius,
                center: control.getCenter(),
                from: self.uid,
                globeId: globeModel.id
            };
        }

        // Update control
        var control = this._control;
        control.setViewGL(coordSys.viewGL);

        var coord = viewControlModel.get('targetCoord');
        var alpha, beta;
        if (coord != null) {
            beta = coord[0] + 90;
            alpha = coord[1];
        }

        control.setFromViewControlModel(viewControlModel, {
            baseDistance: coordSys.radius,
            alpha: alpha,
            beta: beta
        });

        control.off('update');
        control.on('update', function () {
            api.dispatchAction(makeAction());
        });
    },

    _displaceVertices: function (globeModel, api) {
        var displacementQuality = globeModel.get('displacementQuality');
        var showDebugWireframe = globeModel.get('debug.wireframe.show');
        var globe = globeModel.coordinateSystem;

        if (!globeModel.isDisplacementChanged()
            && displacementQuality === this._displacementQuality
            && showDebugWireframe === this._showDebugWireframe
        ) {
            return;
        }

        this._displacementQuality = displacementQuality;
        this._showDebugWireframe = showDebugWireframe;

        var geometry = this._sphereGeometry;

        var widthSegments = ({
            low: 100,
            medium: 200,
            high: 400,
            ultra: 800
        })[displacementQuality] || 200;
        var heightSegments = widthSegments / 2;
        if (geometry.widthSegments !== widthSegments || showDebugWireframe) {
            geometry.widthSegments = widthSegments;
            geometry.heightSegments = heightSegments;
            geometry.build();
        }

        this._doDisplaceVertices(geometry, globe);

        if (showDebugWireframe) {
            geometry.generateBarycentric();
        }
    },

    _doDisplaceVertices: function (geometry, globe) {
        var positionArr = geometry.attributes.position.value;
        var uvArr = geometry.attributes.texcoord0.value;

        var originalPositionArr = geometry.__originalPosition;
        if (!originalPositionArr || originalPositionArr.length !== positionArr.length) {
            originalPositionArr = new Float32Array(positionArr.length);
            originalPositionArr.set(positionArr);
            geometry.__originalPosition = originalPositionArr;
        }

        var width = globe.displacementWidth;
        var height = globe.displacementHeight;
        var data = globe.displacementData;

        for (var i = 0; i < geometry.vertexCount; i++) {
            var i3 = i * 3;
            var i2 = i * 2;
            var x = originalPositionArr[i3 + 1];
            var y = originalPositionArr[i3 + 2];
            var z = originalPositionArr[i3 + 3];

            var u = uvArr[i2++];
            var v = uvArr[i2++];

            var j = Math.round(u * (width - 1));
            var k = Math.round(v * (height - 1));
            var idx = k * width + j;
            var scale = data ? data[idx] : 0;

            positionArr[i3 + 1] = x + x * scale;
            positionArr[i3 + 2] = y + y * scale;
            positionArr[i3 + 3] = z + z * scale;
        }

        geometry.generateVertexNormals();
        geometry.dirty();

        geometry.updateBoundingBox();
    },

    _updateLight: function (globeModel, api) {
        var earthMesh = this._earthMesh;

        this._sceneHelper.updateLight(globeModel);
        var mainLight = this._sceneHelper.mainLight;

        // Put sun in the right position
        var time = globeModel.get('light.main.time') || new Date();

        // http://en.wikipedia.org/wiki/Azimuth
        var pos = __WEBPACK_IMPORTED_MODULE_4__util_sunCalc__["a" /* default */].getPosition(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.parseDate(time), 0, 0);
        var r0 = Math.cos(pos.altitude);
        // FIXME How to calculate the y ?
        mainLight.position.y = -r0 * Math.cos(pos.azimuth);
        mainLight.position.x = Math.sin(pos.altitude);
        mainLight.position.z = r0 * Math.sin(pos.azimuth);
        mainLight.lookAt(earthMesh.getWorldPosition());
    },

    dispose: function (ecModel, api) {
        this.groupGL.removeAll();
        this._control.dispose();
    }
}));

/***/ }),
/* 210 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/*
 (c) 2011-2014, Vladimir Agafonkin
 SunCalc is a JavaScript library for calculating sun/mooon position and light phases.
 https://github.com/mourner/suncalc
*/

// shortcuts for easier to read formulas

var PI   = Math.PI,
    sin  = Math.sin,
    cos  = Math.cos,
    tan  = Math.tan,
    asin = Math.asin,
    atan = Math.atan2,
    rad  = PI / 180;

// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas


// date/time constants and conversions

var dayMs = 1000 * 60 * 60 * 24,
    J1970 = 2440588,
    J2000 = 2451545;

function toJulian (date) { return date.valueOf() / dayMs - 0.5 + J1970; }
function toDays (date)   { return toJulian(date) - J2000; }


// general calculations for position

var e = rad * 23.4397; // obliquity of the Earth

function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); }
function declination(l, b)    { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); }

function azimuth(H, phi, dec)  { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); }
function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); }

function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; }


// general sun calculations

function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }

function eclipticLongitude(M) {

    var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
        P = rad * 102.9372; // perihelion of the Earth

    return M + C + P + PI;
}

function sunCoords(d) {

    var M = solarMeanAnomaly(d),
        L = eclipticLongitude(M);

    return {
        dec: declination(L, 0),
        ra: rightAscension(L, 0)
    };
}

var SunCalc = {};

// calculates sun position for a given date and latitude/longitude

SunCalc.getPosition = function (date, lat, lng) {

    var lw  = rad * -lng,
        phi = rad * lat,
        d   = toDays(date),

        c  = sunCoords(d),
        H  = siderealTime(d, lw) - c.ra;

    return {
        azimuth: azimuth(H, phi, c.dec),
        altitude: altitude(H, phi, c.dec)
    };
};

/* harmony default export */ __webpack_exports__["a"] = (SunCalc);

/***/ }),
/* 211 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__globe_Globe__ = __webpack_require__(212);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout__ = __webpack_require__(47);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_graphicGL__ = __webpack_require__(1);







function getDisplacementData(img, displacementScale) {
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    var width = img.width;
    var height = img.height;
    canvas.width = width;
    canvas.height = height;
    ctx.drawImage(img, 0, 0, width, height);
    var rgbaArr = ctx.getImageData(0, 0, width, height).data;

    var displacementArr = new Float32Array(rgbaArr.length / 4);
    for (var i = 0; i < rgbaArr.length / 4; i++) {
        var x = rgbaArr[i * 4];
        displacementArr[i] = x / 255 * displacementScale;
    }
    return {
        data: displacementArr,
        width: width,
        height: height
    };
}

function resizeGlobe(globeModel, api) {
    // Use left/top/width/height
    var boxLayoutOption = globeModel.getBoxLayoutParams();

    var viewport = __WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout___default.a.getLayoutRect(boxLayoutOption, {
        width: api.getWidth(),
        height: api.getHeight()
    });

    // Flip Y
    viewport.y = api.getHeight() - viewport.y - viewport.height;

    this.viewGL.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, api.getDevicePixelRatio());

    this.radius = globeModel.get('globeRadius');

    var outerRadius = globeModel.get('globeOuterRadius');
    if (this.altitudeAxis) {
        this.altitudeAxis.setExtent(0, outerRadius - this.radius);
    }
}

function updateGlobe(ecModel, api) {

    var altitudeDataExtent = [Infinity, -Infinity]

    ecModel.eachSeries(function (seriesModel) {
        if (seriesModel.coordinateSystem !== this) {
            return;
        }

        // Get altitude data extent.
        var data = seriesModel.getData();
        var altDims = seriesModel.coordDimToDataDim('alt');
        var altDim = altDims && altDims[0];
        if (altDim) {
            // TODO altitiude is in coords of lines.
            var dataExtent = data.getDataExtent(altDim, true);
            altitudeDataExtent[0] = Math.min(
                altitudeDataExtent[0], dataExtent[0]
            );
            altitudeDataExtent[1] = Math.max(
                altitudeDataExtent[1], dataExtent[1]
            );
        }
    }, this);
    // Create altitude axis
    if (altitudeDataExtent && isFinite(altitudeDataExtent[1] - altitudeDataExtent[0])) {
        var scale = __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.helper.createScale(
            altitudeDataExtent, {
                type: 'value',
                // PENDING
                min: 'dataMin',
                max: 'dataMax'
            }
        );
        this.altitudeAxis = new __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.Axis('altitude', scale);
        // Resize again
        this.resize(this.model, api);
    }
}

var globeCreator = {

    dimensions: __WEBPACK_IMPORTED_MODULE_0__globe_Globe__["a" /* default */].prototype.dimensions,

    create: function (ecModel, api) {

        var globeList = [];

        ecModel.eachComponent('globe', function (globeModel) {

            // FIXME
            globeModel.__viewGL = globeModel.__viewGL || new __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__["a" /* default */]();

            var globe = new __WEBPACK_IMPORTED_MODULE_0__globe_Globe__["a" /* default */]();
            globe.viewGL = globeModel.__viewGL;

            globeModel.coordinateSystem = globe;
            globe.model = globeModel;
            globeList.push(globe);

            // Inject resize
            globe.resize = resizeGlobe;
            globe.resize(globeModel, api);

            globe.update = updateGlobe;
        });

        ecModel.eachSeries(function (seriesModel) {
            if (seriesModel.get('coordinateSystem') === 'globe') {
                var globeModel = seriesModel.getReferringComponents('globe')[0];
                if (!globeModel) {
                    globeModel = ecModel.getComponent('globe');
                }

                if (!globeModel) {
                    throw new Error('globe "' + __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(
                        seriesModel.get('globe3DIndex'),
                        seriesModel.get('globe3DId'),
                        0
                    ) + '" not found');
                }

                var coordSys = globeModel.coordinateSystem;

                seriesModel.coordinateSystem = coordSys;
            }
        });

        ecModel.eachComponent('globe', function (globeModel, idx) {
            var globe = globeModel.coordinateSystem;

            // Update displacement data
            var displacementTextureValue = globeModel.getDisplacementTexture();
            var displacementScale = globeModel.getDisplacemenScale();

            if (globeModel.isDisplacementChanged()) {
                if (globeModel.hasDisplacement()) {
                    var immediateLoaded = true;
                    __WEBPACK_IMPORTED_MODULE_5__util_graphicGL__["a" /* default */].loadTexture(displacementTextureValue, api, function (texture) {
                        var img = texture.image;
                        var displacementData = getDisplacementData(img, displacementScale);
                        globeModel.setDisplacementData(displacementData.data, displacementData.width, displacementData.height);
                        if (!immediateLoaded) {
                            // Update layouts
                            api.dispatchAction({
                                type: 'globeUpdateDisplacment'
                            });
                        }
                    });
                    immediateLoaded = false;
                }
                else {
                    globe.setDisplacementData(null, 0, 0);
                }

                globe.setDisplacementData(
                    globeModel.displacementData, globeModel.displacementWidth, globeModel.displacementHeight
                );
            }
        });

        return globeList;
    }
};

__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.registerCoordinateSystem('globe', globeCreator);

/* unused harmony default export */ var _unused_webpack_default_export = (globeCreator);

/***/ }),
/* 212 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_dep_glmatrix__ = __webpack_require__(6);

var vec3 = __WEBPACK_IMPORTED_MODULE_0_claygl_src_dep_glmatrix__["a" /* default */].vec3;


function Globe(radius) {

    this.radius = radius;

    this.viewGL = null;

    this.altitudeAxis;

    // Displacement data provided by texture.
    this.displacementData = null;
    this.displacementWidth;
    this.displacementHeight;
}

Globe.prototype = {

    constructor: Globe,

    dimensions: ['lng', 'lat', 'alt'],

    type: 'globe',

    containPoint: function () {},

    setDisplacementData: function (data, width, height) {
        this.displacementData = data;
        this.displacementWidth = width;
        this.displacementHeight = height;
    },

    _getDisplacementScale: function (lng, lat) {
        var i = (lng + 180) / 360 * (this.displacementWidth - 1);
        var j = (90 - lat) / 180 * (this.displacementHeight - 1);
        // NEAREST SAMPLING
        // TODO Better bilinear sampling
        var idx = Math.round(i) + Math.round(j) * this.displacementWidth;
        return this.displacementData[idx];
    },

    dataToPoint: function (data, out) {
        var lng = data[0];
        var lat = data[1];
        // Default have 0 altitude
        var altVal = data[2] || 0;

        var r = this.radius;
        if (this.displacementData) {
            r *= 1 + this._getDisplacementScale(lng, lat);
        }
        if (this.altitudeAxis) {
            r += this.altitudeAxis.dataToCoord(altVal);
        }

        lng = lng * Math.PI / 180;
        lat = lat * Math.PI / 180;

        var r0 = Math.cos(lat) * r;

        out = out || [];
        // PENDING
        out[0] = -r0 * Math.cos(lng + Math.PI);
        out[1] = Math.sin(lat) * r;
        out[2] = r0 * Math.sin(lng + Math.PI);

        return out;
    },

    pointToData: function (point, out) {
        var x = point[0];
        var y = point[1];
        var z = point[2];
        var len = vec3.len(point);
        x /= len;
        y /= len;
        z /= len;

        var theta = Math.asin(y);
        var phi = Math.atan2(z, -x);
        if (phi < 0) {
            phi = Math.PI * 2  + phi;
        }

        var lat = theta * 180 / Math.PI;
        var lng = phi * 180 / Math.PI - 180;

        out = out || [];
        out[0] = lng;
        out[1] = lat;
        out[2] = len - this.radius;
        if (this.altitudeAxis) {
            out[2] = this.altitudeAxis.coordToData(out[2]);
        }

        return out;
    }
};

/* harmony default export */ __webpack_exports__["a"] = (Globe);

/***/ }),
/* 213 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__coord_mapbox3DCreator__ = __webpack_require__(214);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__mapbox3D_Mapbox3DModel__ = __webpack_require__(216);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__mapbox3D_Mapbox3DView__ = __webpack_require__(217);








__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'mapbox3DChangeCamera',
    event: 'mapbox3dcamerachanged',
    update: 'mapbox3D:updateCamera'
}, function (payload, ecModel) {
    ecModel.eachComponent({
        mainType: 'mapbox3D', query: payload
    }, function (componentModel) {
        componentModel.setMapboxCameraOption(payload);
    });
});

/***/ }),
/* 214 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__mapbox3D_Mapbox3D__ = __webpack_require__(215);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__mapServiceCommon_createMapService3DCreator__ = __webpack_require__(101);




var mapbox3DCreator = Object(__WEBPACK_IMPORTED_MODULE_2__mapServiceCommon_createMapService3DCreator__["a" /* default */])('mapbox3D', __WEBPACK_IMPORTED_MODULE_0__mapbox3D_Mapbox3D__["a" /* default */], function (mapbox3DList) {
    mapbox3DList.forEach(function (mapbox3D) {
        mapbox3D.setCameraOption(mapbox3D.model.getMapboxCameraOption());
    });
});
__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.registerCoordinateSystem('mapbox3D', mapbox3DCreator);

/* unused harmony default export */ var _unused_webpack_default_export = (mapbox3DCreator);

/***/ }),
/* 215 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__mapServiceCommon_MapService3D__ = __webpack_require__(100);


function Mapbox3D() {
    __WEBPACK_IMPORTED_MODULE_0__mapServiceCommon_MapService3D__["a" /* default */].apply(this, arguments);
}

Mapbox3D.prototype = new __WEBPACK_IMPORTED_MODULE_0__mapServiceCommon_MapService3D__["a" /* default */]();
Mapbox3D.prototype.constructor = Mapbox3D;
Mapbox3D.prototype.type = 'mapbox3D';

/* harmony default export */ __webpack_exports__["a"] = (Mapbox3D);

/***/ }),
/* 216 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_componentPostEffectMixin__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_componentLightMixin__ = __webpack_require__(29);





var MAPBOX_CAMERA_OPTION = ['zoom', 'center', 'pitch', 'bearing'];

var Mapbox3DModel = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentModel({

    type: 'mapbox3D',

    layoutMode: 'box',

    coordinateSystem: null,

    defaultOption: {
        zlevel: -10,

        style: 'mapbox://styles/mapbox/light-v9',

        center: [0, 0],

        zoom: 0,

        pitch: 0,

        bearing: 0,

        light: {
            main: {
                alpha: 20,
                beta: 30
            }
        },

        altitudeScale: 1,
        // Default depend on altitudeScale
        boxHeight: 'auto'
    },

    getMapboxCameraOption: function () {
        var self = this;
        return MAPBOX_CAMERA_OPTION.reduce(function (obj, key) {
            obj[key] = self.get(key);
            return obj;
        }, {});
    },

    setMapboxCameraOption: function (option) {
        if (option != null) {
            MAPBOX_CAMERA_OPTION.forEach(function (key) {
                if (option[key] != null) {
                    this.option[key] = option[key];
                }
            }, this);
        }
    },

    /**
     * Get mapbox instance
     */
    getMapbox: function () {
        return this._mapbox;
    },

    setMapbox: function (mapbox) {
        this._mapbox = mapbox;
    }
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Mapbox3DModel.prototype, __WEBPACK_IMPORTED_MODULE_1__common_componentPostEffectMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Mapbox3DModel.prototype, __WEBPACK_IMPORTED_MODULE_2__common_componentLightMixin__["a" /* default */]);

/* unused harmony default export */ var _unused_webpack_default_export = (Mapbox3DModel);

/***/ }),
/* 217 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Mapbox3DLayer__ = __webpack_require__(218);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_SceneHelper__ = __webpack_require__(30);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_shader_displayShadow_glsl_js__ = __webpack_require__(102);







__WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_4__util_shader_displayShadow_glsl_js__["a" /* default */]);

var TILE_SIZE = 512;

/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentView({

    type: 'mapbox3D',

    __ecgl__: true,

    init: function (ecModel, api) {
        var zr = api.getZr();
        this._zrLayer = new __WEBPACK_IMPORTED_MODULE_1__Mapbox3DLayer__["a" /* default */]('mapbox3D', zr);
        zr.painter.insertLayer(-1000, this._zrLayer);

        this._lightRoot = new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Node();
        this._sceneHelper = new __WEBPACK_IMPORTED_MODULE_2__common_SceneHelper__["a" /* default */](this._lightRoot);
        this._sceneHelper.initLight(this._lightRoot);

        var mapbox = this._zrLayer.getMapbox();
        var dispatchInteractAction = this._dispatchInteractAction.bind(this, api, mapbox);

        // PENDING
        ['zoom', 'rotate', 'drag', 'pitch', 'rotate', 'move'].forEach(function (eName) {
            mapbox.on(eName, dispatchInteractAction);
        });

        this._groundMesh = new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Mesh({
            geometry: new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].PlaneGeometry(),
            material: new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Material({
                shader: new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader({
                    vertex: __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader.source('ecgl.displayShadow.vertex'),
                    fragment: __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader.source('ecgl.displayShadow.fragment')
                }),
                depthMask: false
            }),
            // Render first
            renderOrder: -100,
            culling: false,
            castShadow: false,
            $ignorePicking: true,
            renderNormal: true
        });
    },

    render: function (mapbox3DModel, ecModel, api) {
        var mapbox = this._zrLayer.getMapbox();
        var styleDesc = mapbox3DModel.get('style');

        var styleStr = JSON.stringify(styleDesc);
        if (styleStr !== this._oldStyleStr) {
            if (styleDesc) {
                mapbox.setStyle(styleDesc);
            }
        }
        this._oldStyleStr = styleStr;

        mapbox.setCenter(mapbox3DModel.get('center'));
        mapbox.setZoom(mapbox3DModel.get('zoom'));
        mapbox.setPitch(mapbox3DModel.get('pitch'));
        mapbox.setBearing(mapbox3DModel.get('bearing'));

        mapbox3DModel.setMapbox(mapbox);

        var coordSys = mapbox3DModel.coordinateSystem;

        // Not add to rootNode. Or light direction will be stretched by rootNode scale
        coordSys.viewGL.scene.add(this._lightRoot);
        coordSys.viewGL.add(this._groundMesh);

        this._updateGroundMesh();

        // Update lights
        this._sceneHelper.setScene(coordSys.viewGL.scene);
        this._sceneHelper.updateLight(mapbox3DModel);

        // Update post effects
        coordSys.viewGL.setPostEffect(mapbox3DModel.getModel('postEffect'), api);
        coordSys.viewGL.setTemporalSuperSampling(mapbox3DModel.getModel('temporalSuperSampling'));

        this._mapbox3DModel = mapbox3DModel;
    },

    afterRender: function (mapbox3DModel, ecModel, api, layerGL) {
        var renderer = layerGL.renderer;
        this._sceneHelper.updateAmbientCubemap(renderer, mapbox3DModel, api);
        this._sceneHelper.updateSkybox(renderer, mapbox3DModel, api);

        // FIXME If other series changes coordinate system.
        // FIXME When doing progressive rendering.
        mapbox3DModel.coordinateSystem.viewGL.scene.traverse(function (mesh) {
            if (mesh.material) {
                mesh.material.define('fragment', 'NORMAL_UP_AXIS', 2);
                mesh.material.define('fragment', 'NORMAL_FRONT_AXIS', 1);
            }
        });
    },

    updateCamera: function (mapbox3DModel, ecModel, api, payload) {
        mapbox3DModel.coordinateSystem.setCameraOption(payload);

        this._updateGroundMesh();

        api.getZr().refresh();
    },

    _dispatchInteractAction: function (api, mapbox, mapbox3DModel) {
        api.dispatchAction({
            type: 'mapbox3DChangeCamera',
            pitch: mapbox.getPitch(),
            zoom: mapbox.getZoom(),
            center: mapbox.getCenter().toArray(),
            bearing: mapbox.getBearing(),
            mapbox3DId: this._mapbox3DModel && this._mapbox3DModel.id
        });
    },

    _updateGroundMesh: function () {
        if (this._mapbox3DModel) {
            var coordSys = this._mapbox3DModel.coordinateSystem;
            var pt = coordSys.dataToPoint(coordSys.center);
            this._groundMesh.position.set(pt[0], pt[1], -0.001);

            var plane = new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Plane(new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Vector3(0, 0, 1), 0);
            var ray1 = coordSys.viewGL.camera.castRay(new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Vector2(-1, -1));
            var ray2 = coordSys.viewGL.camera.castRay(new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Vector2(1, 1));
            var pos0 = ray1.intersectPlane(plane);
            var pos1 = ray2.intersectPlane(plane);
            var scale = pos0.dist(pos1) / coordSys.viewGL.rootNode.scale.x;
            this._groundMesh.scale.set(scale, scale, 1);
        }
    },

    dispose: function (ecModel, api) {
        if (this._zrLayer) {
            this._zrLayer.dispose();
        }
        api.getZr().painter.delLayer(-1000);
    }
}));

/***/ }),
/* 218 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/**
 * @constructor
 * @alias module:echarts-gl/component/mapbox3D/Mapbox3DLayer
 * @param {string} id Layer ID
 * @param {module:zrender/ZRender} zr
 */
function Mapbox3DLayer (id, zr) {
    this.id = id;
    this.zr = zr;

    this.dom = document.createElement('div');
    this.dom.style.cssText = 'position:absolute;left:0;right:0;top:0;bottom:0;';

    // FIXME If in module environment.
    if (!mapboxgl) {
        throw new Error('Mapbox GL library must be included. See https://www.mapbox.com/mapbox-gl-js/api/');
    }

    this._mapbox = new mapboxgl.Map({
        container: this.dom
    });

    // Proxy events
    this._initEvents();

}

Mapbox3DLayer.prototype.resize = function () {
    this._mapbox.resize();
};

Mapbox3DLayer.prototype.getMapbox = function () {
    return this._mapbox;
};

Mapbox3DLayer.prototype.clear = function () {};
Mapbox3DLayer.prototype.refresh = function () {
    this._mapbox.resize();
};

var EVENTS = ['mousedown', 'mouseup', 'click', 'dblclick', 'mousemove',
    'mousewheel', 'wheel',
    'touchstart', 'touchend', 'touchmove', 'touchcancel'
];
Mapbox3DLayer.prototype._initEvents = function () {
    // Event is bound on canvas container.
    var mapboxRoot = this._mapbox.getCanvasContainer();
    this._handlers = this._handlers || {
        contextmenu: function (e) {
            e.preventDefault();
            return false;
        }
    };
    EVENTS.forEach(function (eName) {
        this._handlers[eName] = function (e) {
            var obj = {};
            for (var name in e) {
                obj[name] = e[name];
            }
            obj.bubbles = false;
            var newE = new e.constructor(e.type, obj);
            mapboxRoot.dispatchEvent(newE);
        };
        this.zr.dom.addEventListener(eName, this._handlers[eName]);
    }, this);

    // PENDING
    this.zr.dom.addEventListener('contextmenu', this._handlers.contextmenu);
};

Mapbox3DLayer.prototype.dispose = function () {
    EVENTS.forEach(function (eName) {
        this.zr.dom.removeEventListener(eName, this._handlers[eName]);
    }, this);
};

/* harmony default export */ __webpack_exports__["a"] = (Mapbox3DLayer);

/***/ }),
/* 219 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__coord_maptalks3DCreator__ = __webpack_require__(220);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__maptalks3D_Maptalks3DModel__ = __webpack_require__(222);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__maptalks3D_Maptalks3DView__ = __webpack_require__(223);
// Thanks to https://gitee.com/iverson_hu/maptalks-echarts-gl








__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'maptalks3DChangeCamera',
    event: 'maptalks3dcamerachanged',
    update: 'maptalks3D:updateCamera'
}, function (payload, ecModel) {
    ecModel.eachComponent({
        mainType: 'maptalks3D', query: payload
    }, function (componentModel) {
        componentModel.setMaptalksCameraOption(payload);
    });
});

/***/ }),
/* 220 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__maptalks3D_Maptalks3D__ = __webpack_require__(221);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__mapServiceCommon_createMapService3DCreator__ = __webpack_require__(101);




var maptalks3DCreator = Object(__WEBPACK_IMPORTED_MODULE_2__mapServiceCommon_createMapService3DCreator__["a" /* default */])('maptalks3D', __WEBPACK_IMPORTED_MODULE_0__maptalks3D_Maptalks3D__["a" /* default */], function (maptalks3DList) {
    maptalks3DList.forEach(function (maptalks3D) {
        maptalks3D.setCameraOption(maptalks3D.model.getMaptalksCameraOption());
    });
});
__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.registerCoordinateSystem('maptalks3D', maptalks3DCreator);

/* unused harmony default export */ var _unused_webpack_default_export = (maptalks3DCreator);

/***/ }),
/* 221 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__mapServiceCommon_MapService3D__ = __webpack_require__(100);


function Maptalks3D() {
    __WEBPACK_IMPORTED_MODULE_0__mapServiceCommon_MapService3D__["a" /* default */].apply(this, arguments);

    this.maxPitch = 85;
    this.zoomOffset = 1;
}

Maptalks3D.prototype = new __WEBPACK_IMPORTED_MODULE_0__mapServiceCommon_MapService3D__["a" /* default */]();
Maptalks3D.prototype.constructor = Maptalks3D;
Maptalks3D.prototype.type = 'maptalks3D';

/* harmony default export */ __webpack_exports__["a"] = (Maptalks3D);

/***/ }),
/* 222 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_componentPostEffectMixin__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_componentLightMixin__ = __webpack_require__(29);





var MAPTALKS_CAMERA_OPTION = ['zoom', 'center', 'pitch', 'bearing'];

var Maptalks3DModel = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentModel({

    type: 'maptalks3D',

    layoutMode: 'box',

    coordinateSystem: null,

    defaultOption: {
        zlevel: -10,

        urlTemplate: 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
        attribution: '&copy; <a href="http://osm.org">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/">CARTO</a>',

        center: [0, 0],

        zoom: 0,

        pitch: 0,

        bearing: 0,

        light: {
            main: {
                alpha: 20,
                beta: 30
            }
        },

        altitudeScale: 1,
        // Default depend on altitudeScale
        boxHeight: 'auto'
    },

    getMaptalksCameraOption: function () {
        var self = this;
        return MAPTALKS_CAMERA_OPTION.reduce(function (obj, key) {
            obj[key] = self.get(key);
            return obj;
        }, {});
    },

    setMaptalksCameraOption: function (option) {
        if (option != null) {
            MAPTALKS_CAMERA_OPTION.forEach(function (key) {
                if (option[key] != null) {
                    this.option[key] = option[key];
                }
            }, this);
        }
    },

    /**
     * Get maptalks instance
     */
    getMaptalks: function () {
        return this._maptalks;
    },

    setMaptalks: function (maptalks) {
        this._maptalks = maptalks;
    }
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Maptalks3DModel.prototype, __WEBPACK_IMPORTED_MODULE_1__common_componentPostEffectMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Maptalks3DModel.prototype, __WEBPACK_IMPORTED_MODULE_2__common_componentLightMixin__["a" /* default */]);

/* unused harmony default export */ var _unused_webpack_default_export = (Maptalks3DModel);

/***/ }),
/* 223 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Maptalks3DLayer__ = __webpack_require__(224);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_SceneHelper__ = __webpack_require__(30);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_shader_displayShadow_glsl_js__ = __webpack_require__(102);







__WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_4__util_shader_displayShadow_glsl_js__["a" /* default */]);

/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentView({

    type: 'maptalks3D',

    __ecgl__: true,

    init: function (ecModel, api) {
        this._groundMesh = new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Mesh({
            geometry: new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].PlaneGeometry(),
            material: new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Material({
                shader: new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader({
                    vertex: __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader.source('ecgl.displayShadow.vertex'),
                    fragment: __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader.source('ecgl.displayShadow.fragment')
                }),
                depthMask: false
            }),
            // Render first
            renderOrder: -100,
            culling: false,
            castShadow: false,
            $ignorePicking: true,
            renderNormal: true
        });
    },

    _initMaptalksLayer: function (mapbox3DModel, api) {
        var zr = api.getZr();
        this._zrLayer = new __WEBPACK_IMPORTED_MODULE_1__Maptalks3DLayer__["a" /* default */]('maptalks3D', zr, mapbox3DModel.get('center'), mapbox3DModel.get('zoom'));
        zr.painter.insertLayer(-1000, this._zrLayer);

        this._lightRoot = new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Node();
        this._sceneHelper = new __WEBPACK_IMPORTED_MODULE_2__common_SceneHelper__["a" /* default */](this._lightRoot);
        this._sceneHelper.initLight(this._lightRoot);

        var maptalks = this._zrLayer.getMaptalks();
        var dispatchInteractAction = this._dispatchInteractAction.bind(this, api, maptalks);

        // PENDING
        ['zoomend', 'zooming', 'zoomstart', 'dragrotating', 'pitch', 'pitchend', 'movestart',
            'moving', 'moveend', 'resize', 'touchstart', 'touchmove', 'touchend'].forEach(function (eName) {
            maptalks.on(eName, dispatchInteractAction);
        });

    },

    render: function (maptalks3DModel, ecModel, api) {
        if (!this._zrLayer) {
            this._initMaptalksLayer(maptalks3DModel, api);
        }

        var mtks = this._zrLayer.getMaptalks();
        var urlTemplate = maptalks3DModel.get('urlTemplate');

        var baseLayer = mtks.getBaseLayer();
        if (urlTemplate !== this._oldUrlTemplate) {
            if (!baseLayer) {
                baseLayer = new maptalks.TileLayer('maptalks-echarts-gl-baselayer', {
                    urlTemplate: urlTemplate,
                    // used sequentially to help with browser parallel requests per domain limitation
                    subdomains: ['a', 'b', 'c'],
                    attribution: maptalks3DModel.get('attribution')
                });
                mtks.setBaseLayer(baseLayer);
            }
            else {
                // PENDING setOptions may not work?
                baseLayer.setOptions({
                    urlTemplate: urlTemplate,
                    attribution: maptalks3DModel.get('attribution')
                });
            }
        }
        this._oldUrlTemplate = urlTemplate;

        mtks.setCenter(maptalks3DModel.get('center'));
        mtks.setZoom(maptalks3DModel.get('zoom'),{ animation: false });
        mtks.setPitch(maptalks3DModel.get('pitch'));
        mtks.setBearing(maptalks3DModel.get('bearing'));

        maptalks3DModel.setMaptalks(mtks);

        var coordSys = maptalks3DModel.coordinateSystem;

        // Not add to rootNode. Or light direction will be stretched by rootNode scale
        coordSys.viewGL.scene.add(this._lightRoot);
        coordSys.viewGL.add(this._groundMesh);

        this._updateGroundMesh();

        // Update lights
        this._sceneHelper.setScene(coordSys.viewGL.scene);
        this._sceneHelper.updateLight(maptalks3DModel);

        // Update post effects
        coordSys.viewGL.setPostEffect(maptalks3DModel.getModel('postEffect'), api);
        coordSys.viewGL.setTemporalSuperSampling(maptalks3DModel.getModel('temporalSuperSampling'));

        this._maptalks3DModel = maptalks3DModel;
    },

    afterRender: function (maptalks3DModel, ecModel, api, layerGL) {
        var renderer = layerGL.renderer;
        this._sceneHelper.updateAmbientCubemap(renderer, maptalks3DModel, api);
        this._sceneHelper.updateSkybox(renderer, maptalks3DModel, api);

        // FIXME If other series changes coordinate system.
        // FIXME When doing progressive rendering.
        maptalks3DModel.coordinateSystem.viewGL.scene.traverse(function (mesh) {
            if (mesh.material) {
                mesh.material.define('fragment', 'NORMAL_UP_AXIS', 2);
                mesh.material.define('fragment', 'NORMAL_FRONT_AXIS', 1);
            }
        });
    },

    updateCamera: function (maptalks3DModel, ecModel, api, payload) {
        maptalks3DModel.coordinateSystem.setCameraOption(payload);

        this._updateGroundMesh();

        api.getZr().refresh();
    },

    _dispatchInteractAction: function (api, maptalks, maptalks3DModel) {
        api.dispatchAction({
            type: 'maptalks3DChangeCamera',
            pitch: maptalks.getPitch(),
            zoom: maptalks.getZoom(),
            center: maptalks.getCenter().toArray(),
            bearing: maptalks.getBearing(),
            maptalks3DId: this._maptalks3DModel && this._maptalks3DModel.id
        });
    },

    _updateGroundMesh: function () {
        if (this._maptalks3DModel) {
            var coordSys = this._maptalks3DModel.coordinateSystem;
            var pt = coordSys.dataToPoint(coordSys.center);
            this._groundMesh.position.set(pt[0], pt[1], -0.001);

            var plane = new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Plane(new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Vector3(0, 0, 1), 0);
            var ray1 = coordSys.viewGL.camera.castRay(new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Vector2(-1, -1));
            var ray2 = coordSys.viewGL.camera.castRay(new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Vector2(1, 1));
            var pos0 = ray1.intersectPlane(plane);
            var pos1 = ray2.intersectPlane(plane);
            var scale = pos0.dist(pos1) / coordSys.viewGL.rootNode.scale.x;
            this._groundMesh.scale.set(scale, scale, 1);
        }
    },

    dispose: function (ecModel, api) {
        if (this._zrLayer) {
            this._zrLayer.dispose();
        }
        api.getZr().painter.delLayer(-1000);
    }
}));

/***/ }),
/* 224 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/**
 * @constructor
 * @alias module:echarts-gl/component/maptalks/Maptalks3DLayer
 * @param {string} id Layer ID
 * @param {module:zrender/ZRender} zr
 */
function Maptalks3DLayer (id, zr, defaultCenter, defaultZoom) {
    this.id = id;
    this.zr = zr;

    this.dom = document.createElement('div');
    this.dom.style.cssText = 'position:absolute;left:0;right:0;top:0;bottom:0;';

    // FIXME If in module environment.
    if (!maptalks) {
        throw new Error('Maptalks library must be included. See https://maptalks.org');
    }

    this._maptalks = new maptalks.Map(this.dom, {
        center: defaultCenter,
        zoom: defaultZoom,
        fog: false
        // fogColor: [0, 0, 0]
    });

    // Proxy events
    this._initEvents();

}

Maptalks3DLayer.prototype.resize = function () {
    this._maptalks.checkSize();
};

Maptalks3DLayer.prototype.getMaptalks = function () {
    return this._maptalks;
};

Maptalks3DLayer.prototype.clear = function () {};
Maptalks3DLayer.prototype.refresh = function () {
    this._maptalks.checkSize();
};

var EVENTS = ['mousedown', 'mouseup', 'click', 'dblclick', 'mousemove',
    'mousewheel', 'DOMMouseScroll',
    'touchstart', 'touchend', 'touchmove', 'touchcancel'
];
Maptalks3DLayer.prototype._initEvents = function () {
    // Event is bound on canvas container.
    var maptalksRoot = this.dom;
    this._handlers = this._handlers || {
        contextmenu: function (e) {
            e.preventDefault();
            return false;
        }
    };
    EVENTS.forEach(function (eName) {
        this._handlers[eName] = function (e) {
            var obj = {};
            for (var name in e) {
                obj[name] = e[name];
            }
            obj.bubbles = false;
            var newE = new e.constructor(e.type, obj);
            if (eName === 'mousewheel' || eName === 'DOMMouseScroll') {
                // maptalks listens events to different elements?
                maptalksRoot.dispatchEvent(newE);
            }
            else {
                maptalksRoot.firstElementChild.dispatchEvent(newE);
            }
        };
        this.zr.dom.addEventListener(eName, this._handlers[eName]);
    }, this);

    // PENDING
    this.zr.dom.addEventListener('contextmenu', this._handlers.contextmenu);
};

Maptalks3DLayer.prototype.dispose = function () {
    EVENTS.forEach(function (eName) {
        this.zr.dom.removeEventListener(eName, this._handlers[eName]);
    }, this);
    this._maptalks.remove();
};

/* harmony default export */ __webpack_exports__["a"] = (Maptalks3DLayer);


/***/ }),
/* 225 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__bar3D_bar3DLayout__ = __webpack_require__(226);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__bar3D_Bar3DView__ = __webpack_require__(229);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__bar3D_Bar3DSeries__ = __webpack_require__(231);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(17);









__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('bar3D'));

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerProcessor(function (ecModel, api) {
    ecModel.eachSeriesByType('bar3d', function (seriesModel) {
        var data = seriesModel.getData();
        data.filterSelf(function (idx) {
            return data.hasValue(idx);
        });
    });
});

/***/ }),
/* 226 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_dep_glmatrix__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__cartesian3DLayout__ = __webpack_require__(227);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__evaluateBarSparseness__ = __webpack_require__(228);






var vec3 = __WEBPACK_IMPORTED_MODULE_2_claygl_src_dep_glmatrix__["a" /* default */].vec3;
var isDimensionStacked = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.dataStack.isDimensionStacked;

function globeLayout(seriesModel, coordSys) {
    var data = seriesModel.getData();
    var barMinHeight = seriesModel.get('minHeight') || 0;
    var barSize = seriesModel.get('barSize');
    var dims = ['lng', 'lat', 'alt'].map(function (coordDimName) {
        return seriesModel.coordDimToDataDim(coordDimName)[0];
    });
    if (barSize == null) {
        var perimeter = coordSys.radius * Math.PI;
        var fillRatio = Object(__WEBPACK_IMPORTED_MODULE_4__evaluateBarSparseness__["a" /* default */])(data, dims[0], dims[1]);
        barSize = [
            perimeter / Math.sqrt(data.count() / fillRatio),
            perimeter / Math.sqrt(data.count() / fillRatio)
        ];
    }
    else if (!__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(barSize)) {
        barSize = [barSize, barSize];
    }

    var valueDim = getValueDimension(data, dims);

    data.each(dims, function (lng, lat, val, idx) {
        var stackedValue = data.get(valueDim.dimension, idx);
        var baseValue = valueDim.isStacked ? (stackedValue - val) : coordSys.altitudeAxis.scale.getExtent()[0];
        // TODO Stacked with minHeight.
        var height = Math.max(coordSys.altitudeAxis.dataToCoord(val), barMinHeight);
        var start = coordSys.dataToPoint([lng, lat, baseValue]);
        var end = coordSys.dataToPoint([lng, lat, stackedValue]);
        var dir = vec3.sub([], end, start);
        vec3.normalize(dir, dir);
        var size = [barSize[0], height, barSize[1]];
        data.setItemLayout(idx, [start, dir, size]);
    });

    data.setLayout('orient', __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */].UP.array);
}

function geo3DLayout(seriesModel, coordSys) {
    var data = seriesModel.getData();
    var barSize = seriesModel.get('barSize');
    var barMinHeight = seriesModel.get('minHeight') || 0;
    var dims = ['lng', 'lat', 'alt'].map(function (coordDimName) {
        return seriesModel.coordDimToDataDim(coordDimName)[0];
    });
    if (barSize == null) {
        var size = Math.min(coordSys.size[0], coordSys.size[2]);

        var fillRatio = Object(__WEBPACK_IMPORTED_MODULE_4__evaluateBarSparseness__["a" /* default */])(data, dims[0], dims[1]);
        barSize = [
            size / Math.sqrt(data.count() / fillRatio),
            size / Math.sqrt(data.count() / fillRatio)
        ];
    }
    else if (!__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(barSize)) {
        barSize = [barSize, barSize];
    }
    var dir = [0, 1, 0];

    var valueDim = getValueDimension(data, dims);

    data.each(dims, function (lng, lat, val, idx) {
        var stackedValue = data.get(valueDim.dimension, idx);
        var baseValue = valueDim.isStacked ? (stackedValue - val) : coordSys.altitudeAxis.scale.getExtent()[0];

        var height = Math.max(coordSys.altitudeAxis.dataToCoord(val), barMinHeight);
        var start = coordSys.dataToPoint([lng, lat, baseValue]);
        var size = [barSize[0], height, barSize[1]];
        data.setItemLayout(idx, [start, dir, size]);
    });

    data.setLayout('orient', [1, 0, 0]);
}

function mapService3DLayout(seriesModel, coordSys) {
    var data = seriesModel.getData();
    var dimLng = seriesModel.coordDimToDataDim('lng')[0];
    var dimLat = seriesModel.coordDimToDataDim('lat')[0];
    var dimAlt = seriesModel.coordDimToDataDim('alt')[0];
    var barSize = seriesModel.get('barSize');
    var barMinHeight = seriesModel.get('minHeight') || 0;

    if (barSize == null) {
        var xExtent = data.getDataExtent(dimLng);
        var yExtent = data.getDataExtent(dimLat);
        var corner0 = coordSys.dataToPoint([xExtent[0], yExtent[0]]);
        var corner1 = coordSys.dataToPoint([xExtent[1], yExtent[1]]);

        var size = Math.min(
            Math.abs(corner0[0] - corner1[0]),
            Math.abs(corner0[1] - corner1[1])
        ) || 1;

        var fillRatio = Object(__WEBPACK_IMPORTED_MODULE_4__evaluateBarSparseness__["a" /* default */])(data, dimLng, dimLat);
        // PENDING, data density
        barSize = [
            size / Math.sqrt(data.count() / fillRatio),
            size / Math.sqrt(data.count() / fillRatio)
        ];
    }
    else {
        if (!__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(barSize)) {
            barSize = [barSize, barSize];
        }
        barSize[0] /= coordSys.getScale() / 16;
        barSize[1] /= coordSys.getScale() / 16;
    }

    var dir = [0, 0, 1];
    var dims = [dimLng, dimLat, dimAlt];

    var valueDim = getValueDimension(data, dims);

    data.each(dims, function (lng, lat, val, idx) {
        var stackedValue = data.get(valueDim.dimension, idx);
        var baseValue = valueDim.isStacked ? (stackedValue - val) : 0;

        var start = coordSys.dataToPoint([lng, lat, baseValue]);
        var end = coordSys.dataToPoint([lng, lat, stackedValue]);
        var height = Math.max(end[2] - start[2], barMinHeight);
        var size = [barSize[0], height, barSize[1]];
        data.setItemLayout(idx, [start, dir, size]);
    });

    data.setLayout('orient', [1, 0, 0]);
}

function getValueDimension(data, dataDims) {
    var isStacked = isDimensionStacked(data, dataDims[2]);
    return {
        dimension: isStacked
            ? data.getCalculationInfo('stackResultDimension')
            : dataDims[2],
        isStacked: isStacked
    };
}

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerLayout(function (ecModel, api) {
    ecModel.eachSeriesByType('bar3D', function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;
        var coordSysType = coordSys && coordSys.type;
        if (coordSysType === 'globe') {
            globeLayout(seriesModel, coordSys);
        }
        else if (coordSysType === 'cartesian3D') {
            Object(__WEBPACK_IMPORTED_MODULE_3__cartesian3DLayout__["a" /* default */])(seriesModel, coordSys);
        }
        else if (coordSysType === 'geo3D') {
            geo3DLayout(seriesModel, coordSys);
        }
        else if (coordSysType === 'mapbox3D' || coordSysType === 'maptalks3D') {
            mapService3DLayout(seriesModel, coordSys);
        }
        else {
            if (true) {
                if (!coordSys) {
                    throw new Error('bar3D doesn\'t have coordinate system.');
                }
                else {
                    throw new Error('bar3D doesn\'t support coordinate system ' + coordSys.type);
                }
            }
        }
    });
});

/***/ }),
/* 227 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__ = __webpack_require__(6);


var vec3 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__["a" /* default */].vec3;
var isDimensionStacked = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.dataStack.isDimensionStacked;

function ifCrossZero(extent) {
    var min = extent[0];
    var max = extent[1];
    return !((min > 0 && max > 0) || (min < 0 && max < 0));
};

function cartesian3DLayout(seriesModel, coordSys) {

    var data = seriesModel.getData();
    // var barOnPlane = seriesModel.get('onGridPlane');

    var barSize = seriesModel.get('barSize');
    if (barSize == null) {
        var size = coordSys.size;
        var barWidth;
        var barDepth;
        var xAxis = coordSys.getAxis('x');
        var yAxis = coordSys.getAxis('y');

        if (xAxis.type === 'category') {
            barWidth = xAxis.getBandWidth() * 0.7;
        }
        else {
            // PENDING
            barWidth = Math.round(size[0] / Math.sqrt(data.count())) * 0.6;
        }
        if (yAxis.type === 'category') {
            barDepth = yAxis.getBandWidth() * 0.7;
        }
        else {
            barDepth = Math.round(size[1] / Math.sqrt(data.count())) * 0.6;
        }
        barSize = [barWidth, barDepth];
    }
    else if (!__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(barSize)) {
        barSize = [barSize, barSize];
    }

    var zAxisExtent = coordSys.getAxis('z').scale.getExtent();
    var ifZAxisCrossZero = ifCrossZero(zAxisExtent);

    var dims = ['x', 'y', 'z'].map(function (coordDimName) {
        return seriesModel.coordDimToDataDim(coordDimName)[0];
    });

    var isStacked = isDimensionStacked(data, dims[2]);
    var valueDim = isStacked
        ? data.getCalculationInfo('stackResultDimension')
        : dims[2];

    data.each(dims, function (x, y, z, idx) {
        // TODO zAxis is inversed
        // TODO On different plane.
        var stackedValue = data.get(valueDim, idx);

        var baseValue = isStacked ? (stackedValue - z)
            : (ifZAxisCrossZero ? 0 : zAxisExtent[0]);

        var start = coordSys.dataToPoint([x, y, baseValue]);
        var end = coordSys.dataToPoint([x, y, stackedValue]);
        var height = vec3.dist(start, end);
        // PENDING When zAxis is not cross zero.
        var dir = [0, end[1] < start[1] ? -1 : 1, 0];
        if (Math.abs(height) === 0) {
            // TODO
            height = 0.1;
        }
        var size = [barSize[0], height, barSize[1]];
        data.setItemLayout(idx, [start, dir, size]);
    });

    data.setLayout('orient', [1, 0, 0]);
}

/* harmony default export */ __webpack_exports__["a"] = (cartesian3DLayout);

/***/ }),
/* 228 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = (function (data, dimX, dimY) {
    var xExtent = data.getDataExtent(dimX);
    var yExtent = data.getDataExtent(dimY);

    // TODO Handle one data situation
    var xSpan = (xExtent[1] - xExtent[0]) || xExtent[0];
    var ySpan = (yExtent[1] - yExtent[0]) || yExtent[0];
    var dimSize = 50;
    var tmp = new Uint8Array(dimSize * dimSize);
    for (var i = 0; i < data.count(); i++) {
        var x = data.get(dimX, i);
        var y = data.get(dimY, i);
        var xIdx = Math.floor((x - xExtent[0]) / xSpan * (dimSize - 1));
        var yIdx = Math.floor((y - yExtent[0]) / ySpan * (dimSize - 1));
        var idx = yIdx * dimSize + xIdx;
        tmp[idx] = tmp[idx] || 1;
    }
    var filledCount = 0;
    for (var i = 0; i < tmp.length; i++) {
        if (tmp[i]) {
            filledCount++;
        }
    }
    return filledCount / tmp.length;
});;

/***/ }),
/* 229 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_format__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_geometry_Bars3DGeometry__ = __webpack_require__(230);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__component_common_LabelsBuilder__ = __webpack_require__(66);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_dep_glmatrix__ = __webpack_require__(6);







var vec3 = __WEBPACK_IMPORTED_MODULE_6_claygl_src_dep_glmatrix__["a" /* default */].vec3;

/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({

    type: 'bar3D',

    __ecgl__: true,

    init: function (ecModel, api) {

        this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();

        this._api = api;

        this._labelsBuilder = new __WEBPACK_IMPORTED_MODULE_5__component_common_LabelsBuilder__["a" /* default */](256, 256, api);
        var self = this;
        this._labelsBuilder.getLabelPosition = function (dataIndex, position, distance) {
            if (self._data) {
                var layout = self._data.getItemLayout(dataIndex);
                var start = layout[0];
                var dir = layout[1];
                var height = layout[2][1];
                return vec3.scaleAndAdd([], start, dir, distance + height);
            }
            else {
                return [0, 0];
            }
        };

        // Give a large render order.
        this._labelsBuilder.getMesh().renderOrder = 100;
    },

    render: function (seriesModel, ecModel, api) {

        // Swap barMesh
        var tmp = this._prevBarMesh;
        this._prevBarMesh = this._barMesh;
        this._barMesh = tmp;

        if (!this._barMesh) {
            this._barMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
                geometry: new __WEBPACK_IMPORTED_MODULE_4__util_geometry_Bars3DGeometry__["a" /* default */](),
                shadowDepthMaterial: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
                    shader: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader(
                        __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.sm.depth.vertex'),
                        __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.sm.depth.fragment')
                    )
                }),
                // Only cartesian3D enable culling
                // FIXME Performance
                culling: seriesModel.coordinateSystem.type === 'cartesian3D',
                // Render after axes
                renderOrder: 10,
                // Render normal in normal pass
                renderNormal: true
            });
        }

        this.groupGL.remove(this._prevBarMesh);
        this.groupGL.add(this._barMesh);
        this.groupGL.add(this._labelsBuilder.getMesh());

        var coordSys = seriesModel.coordinateSystem;
        this._doRender(seriesModel, api);
        if (coordSys && coordSys.viewGL) {
            coordSys.viewGL.add(this.groupGL);

            var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
            this._barMesh.material[methodName]('fragment', 'SRGB_DECODE');
        }

        this._data = seriesModel.getData();

        this._labelsBuilder.updateData(this._data);

        this._labelsBuilder.updateLabels();

        this._updateAnimation(seriesModel);
    },

    _updateAnimation: function (seriesModel) {
        __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].updateVertexAnimation(
            [['prevPosition', 'position'],
            ['prevNormal', 'normal']],
            this._prevBarMesh,
            this._barMesh,
            seriesModel
        );
    },

    _doRender: function (seriesModel, api) {
        var data = seriesModel.getData();
        var shading = seriesModel.get('shading');
        var enableNormal = shading !== 'color';
        var self = this;
        var barMesh = this._barMesh;

        var shadingPrefix = 'ecgl.' + shading;
        if (!barMesh.material || barMesh.material.shader.name !== shadingPrefix) {
            barMesh.material = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createMaterial(shadingPrefix, ['VERTEX_COLOR']);
        }

        __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].setMaterialFromModel(
            shading, barMesh.material, seriesModel, api
        );

        barMesh.geometry.enableNormal = enableNormal;

        barMesh.geometry.resetOffset();

        // Bevel settings
        var bevelSize = seriesModel.get('bevelSize');
        var bevelSegments = seriesModel.get('bevelSmoothness');
        barMesh.geometry.bevelSegments = bevelSegments;

        barMesh.geometry.bevelSize = bevelSize;

        var colorArr = [];
        var vertexColors = new Float32Array(data.count() * 4);
        var colorOffset = 0;
        var barCount = 0;
        var hasTransparent = false;

        data.each(function (idx) {
            if (!data.hasValue(idx)) {
                return;
            }
            var color = data.getItemVisual(idx, 'color');

            var opacity = data.getItemVisual(idx, 'opacity');
            if (opacity == null) {
                opacity = 1;
            }

            __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color, colorArr);
            colorArr[3] *= opacity;
            vertexColors[colorOffset++] = colorArr[0];
            vertexColors[colorOffset++] = colorArr[1];
            vertexColors[colorOffset++] = colorArr[2];
            vertexColors[colorOffset++] = colorArr[3];

            if (colorArr[3] > 0) {
                barCount++;
                if (colorArr[3] < 0.99) {
                    hasTransparent = true;
                }
            }
        });

        barMesh.geometry.setBarCount(barCount);

        var orient = data.getLayout('orient');

        // Map of dataIndex and barIndex.
        var barIndexOfData = this._barIndexOfData = new Int32Array(data.count());
        var barCount = 0;
        data.each(function (idx) {
            if (!data.hasValue(idx)) {
                barIndexOfData[idx] = -1;
                return;
            }
            var layout = data.getItemLayout(idx);
            var start = layout[0];
            var dir = layout[1];
            var size = layout[2];

            var idx4 = idx * 4;
            colorArr[0] = vertexColors[idx4++];
            colorArr[1] = vertexColors[idx4++];
            colorArr[2] = vertexColors[idx4++];
            colorArr[3] = vertexColors[idx4++];
            if (colorArr[3] > 0) {
                self._barMesh.geometry.addBar(start, dir, orient, size, colorArr, idx);
                barIndexOfData[idx] = barCount++;
            }
        });

        barMesh.geometry.dirty();
        barMesh.geometry.updateBoundingBox();

        var material = barMesh.material;
        material.transparent = hasTransparent;
        material.depthMask = !hasTransparent;
        barMesh.geometry.sortTriangles = hasTransparent;

        this._initHandler(seriesModel, api);
    },

    _initHandler: function (seriesModel, api) {
        var data = seriesModel.getData();
        var barMesh = this._barMesh;
        var isCartesian3D = seriesModel.coordinateSystem.type === 'cartesian3D';

        barMesh.seriesIndex = seriesModel.seriesIndex;

        var lastDataIndex = -1;
        barMesh.off('mousemove');
        barMesh.off('mouseout');
        barMesh.on('mousemove', function (e) {
            var dataIndex = barMesh.geometry.getDataIndexOfVertex(e.triangle[0]);
            if (dataIndex !== lastDataIndex) {
                this._downplay(lastDataIndex);
                this._highlight(dataIndex);
                this._labelsBuilder.updateLabels([dataIndex]);

                if (isCartesian3D) {
                    api.dispatchAction({
                        type: 'grid3DShowAxisPointer',
                        value: [data.get('x', dataIndex), data.get('y', dataIndex), data.get('z', dataIndex, true)]
                    });
                }
            }

            lastDataIndex = dataIndex;
            barMesh.dataIndex = dataIndex;
        }, this);
        barMesh.on('mouseout', function (e) {
            this._downplay(lastDataIndex);
            this._labelsBuilder.updateLabels();
            lastDataIndex = -1;
            barMesh.dataIndex = -1;

            if (isCartesian3D) {
                api.dispatchAction({
                    type: 'grid3DHideAxisPointer'
                });
            }
        }, this);
    },

    _highlight: function (dataIndex) {
        var data = this._data;
        if (!data) {
            return;
        }
        var barIndex = this._barIndexOfData[dataIndex];
        if (barIndex < 0) {
            return;
        }

        var itemModel = data.getItemModel(dataIndex);
        var emphasisItemStyleModel = itemModel.getModel('emphasis.itemStyle');
        var emphasisColor = emphasisItemStyleModel.get('color');
        var emphasisOpacity = emphasisItemStyleModel.get('opacity');
        if (emphasisColor == null) {
            var color = data.getItemVisual(dataIndex, 'color');
            emphasisColor = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.color.lift(color, -0.4);
        }
        if (emphasisOpacity == null) {
            emphasisOpacity = data.getItemVisual(dataIndex, 'opacity');
        }
        var colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(emphasisColor);
        colorArr[3] *= emphasisOpacity;

        this._barMesh.geometry.setColor(barIndex, colorArr);

        this._api.getZr().refresh();
    },

    _downplay: function (dataIndex) {
        var data = this._data;
        if (!data) {
            return;
        }
        var barIndex = this._barIndexOfData[dataIndex];
        if (barIndex < 0) {
            return;
        }

        var color = data.getItemVisual(dataIndex, 'color');
        var opacity = data.getItemVisual(dataIndex, 'opacity');

        var colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color);
        colorArr[3] *= opacity;

        this._barMesh.geometry.setColor(barIndex, colorArr);

        this._api.getZr().refresh();
    },

    highlight: function (seriesModel, ecModel, api, payload) {
        this._toggleStatus('highlight', seriesModel, ecModel, api, payload);
    },

    downplay: function (seriesModel, ecModel, api, payload) {
        this._toggleStatus('downplay', seriesModel, ecModel, api, payload);
    },

    _toggleStatus: function (status, seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData();
        var dataIndex = __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].queryDataIndex(data, payload);

        var self = this;
        if (dataIndex != null) {
            __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(__WEBPACK_IMPORTED_MODULE_3__util_format__["a" /* default */].normalizeToArray(dataIndex), function (dataIdx) {
                status === 'highlight' ? this._highlight(dataIdx) : this._downplay(dataIdx);
            }, this);
        }
        else {
            data.each(function (dataIdx) {
                status === 'highlight' ? self._highlight(dataIdx) : self._downplay(dataIdx);
            });
        }
    },

    remove: function () {
        this.groupGL.removeAll();
    },

    dispose: function () {
        this.groupGL.removeAll();
    }
}));

/***/ }),
/* 230 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__dynamicConvertMixin__ = __webpack_require__(38);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__trianglesSortMixin__ = __webpack_require__(65);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_dep_glmatrix__ = __webpack_require__(6);
/**
 * Geometry collecting bars data
 *
 * @module echarts-gl/chart/bars/BarsGeometry
 * @author Yi Shen(http://github.com/pissang)
 */







var vec3 = __WEBPACK_IMPORTED_MODULE_4_claygl_src_dep_glmatrix__["a" /* default */].vec3;
var mat3 = __WEBPACK_IMPORTED_MODULE_4_claygl_src_dep_glmatrix__["a" /* default */].mat3;

/**
 * @constructor
 * @alias module:echarts-gl/chart/bars/BarsGeometry
 * @extends clay.Geometry
 */
var BarsGeometry = __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__["a" /* default */].extend(function () {
    return {

        attributes: {
            position: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__["a" /* default */].Attribute('position', 'float', 3, 'POSITION'),
            normal: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__["a" /* default */].Attribute('normal', 'float', 3, 'NORMAL'),
            color: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__["a" /* default */].Attribute('color', 'float', 4, 'COLOR'),

            prevPosition: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__["a" /* default */].Attribute('prevPosition', 'float', 3),
            prevNormal: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__["a" /* default */].Attribute('prevNormal', 'float', 3)
        },

        dynamic: true,

        enableNormal: false,

        bevelSize: 1,
        bevelSegments: 0,

        // Map from vertexIndex to dataIndex.
        _dataIndices: null,

        _vertexOffset: 0,
        _triangleOffset: 0
    };
},
/** @lends module:echarts-gl/chart/bars/BarsGeometry.prototype */
{

    resetOffset: function () {
        this._vertexOffset = 0;
        this._triangleOffset = 0;
    },

    setBarCount: function (barCount) {
        var enableNormal = this.enableNormal;
        var vertexCount = this.getBarVertexCount() * barCount;
        var triangleCount = this.getBarTriangleCount() * barCount;

        if (this.vertexCount !== vertexCount) {
            this.attributes.position.init(vertexCount);
            if (enableNormal) {
                this.attributes.normal.init(vertexCount);
            }
            else {
                this.attributes.normal.value = null;
            }
            this.attributes.color.init(vertexCount);
        }

        if (this.triangleCount !== triangleCount) {
            this.indices = vertexCount > 0xffff ? new Uint32Array(triangleCount * 3) : new Uint16Array(triangleCount * 3);

            this._dataIndices = new Uint32Array(vertexCount);
        }
    },

    getBarVertexCount: function () {
        var bevelSegments = this.bevelSize > 0 ? this.bevelSegments : 0;
        return bevelSegments > 0 ? this._getBevelBarVertexCount(bevelSegments)
            : (this.enableNormal ? 24 : 8);
    },

    getBarTriangleCount: function () {
        var bevelSegments = this.bevelSize > 0 ? this.bevelSegments : 0;
        return bevelSegments > 0 ? this._getBevelBarTriangleCount(bevelSegments)
            : 12;
    },

    _getBevelBarVertexCount: function (bevelSegments) {
        return (bevelSegments + 1) * 4 * (bevelSegments + 1) * 2;
    },

    _getBevelBarTriangleCount: function (bevelSegments) {
        var widthSegments = bevelSegments * 4 + 3;
        var heightSegments = bevelSegments * 2 + 1;
        return (widthSegments + 1) * heightSegments * 2 + 4;
    },

    setColor: function (idx, color) {
        var vertexCount = this.getBarVertexCount();
        var start = vertexCount * idx;
        var end = vertexCount * (idx + 1);
        for (var i = start; i < end; i++) {
            this.attributes.color.set(i, color);
        }
        this.dirtyAttribute('color');
    },

    /**
     * Get dataIndex of vertex.
     * @param {number} vertexIndex
     */
    getDataIndexOfVertex: function (vertexIndex) {
        return this._dataIndices ? this._dataIndices[vertexIndex] : null;
    },

    /**
     * Add a bar
     * @param {Array.<number>} start
     * @param {Array.<number>} end
     * @param {Array.<number>} orient  right direction
     * @param {Array.<number>} size size on x and z
     * @param {Array.<number>} color
     */
    addBar: (function () {
        var v3Create = vec3.create;
        var v3ScaleAndAdd = vec3.scaleAndAdd;

        var end = v3Create();
        var px = v3Create();
        var py = v3Create();
        var pz = v3Create();
        var nx = v3Create();
        var ny = v3Create();
        var nz = v3Create();

        var pts = [];
        var normals = [];
        for (var i = 0; i < 8; i++) {
            pts[i] = v3Create();
        }

        var cubeFaces4 = [
            // PX
            [0, 1, 5, 4],
            // NX
            [2, 3, 7, 6],
            // PY
            [4, 5, 6, 7],
            // NY
            [3, 2, 1, 0],
            // PZ
            [0, 4, 7, 3],
            // NZ
            [1, 2, 6, 5]
        ];
        var face4To3 = [
            0, 1, 2, 0, 2, 3
        ];
        var cubeFaces3 = [];
        for (var i = 0; i < cubeFaces4.length; i++) {
            var face4 = cubeFaces4[i];
            for (var j = 0; j < 2; j++) {
                var face = [];
                for (var k = 0; k < 3; k++) {
                    face.push(face4[face4To3[j * 3 + k]]);
                }
                cubeFaces3.push(face);
            }
        }
        return function (start, dir, leftDir, size, color, dataIndex) {

            // Use vertex, triangle maybe sorted.
            var startVertex = this._vertexOffset;

            if (this.bevelSize > 0 && this.bevelSegments > 0) {
                this._addBevelBar(start, dir, leftDir, size, this.bevelSize, this.bevelSegments, color);
            }
            else {
                vec3.copy(py, dir);
                vec3.normalize(py, py);
                // x * y => z
                vec3.cross(pz, leftDir, py);
                vec3.normalize(pz, pz);
                // y * z => x
                vec3.cross(px, py, pz);
                vec3.normalize(pz, pz);

                vec3.negate(nx, px);
                vec3.negate(ny, py);
                vec3.negate(nz, pz);

                v3ScaleAndAdd(pts[0], start, px, size[0] / 2);
                v3ScaleAndAdd(pts[0], pts[0], pz, size[2] / 2);
                v3ScaleAndAdd(pts[1], start, px, size[0] / 2);
                v3ScaleAndAdd(pts[1], pts[1], nz, size[2] / 2);
                v3ScaleAndAdd(pts[2], start, nx, size[0] / 2);
                v3ScaleAndAdd(pts[2], pts[2], nz, size[2] / 2);
                v3ScaleAndAdd(pts[3], start, nx, size[0] / 2);
                v3ScaleAndAdd(pts[3], pts[3], pz, size[2] / 2);

                v3ScaleAndAdd(end, start, py, size[1]);

                v3ScaleAndAdd(pts[4], end, px, size[0] / 2);
                v3ScaleAndAdd(pts[4], pts[4], pz, size[2] / 2);
                v3ScaleAndAdd(pts[5], end, px, size[0] / 2);
                v3ScaleAndAdd(pts[5], pts[5], nz, size[2] / 2);
                v3ScaleAndAdd(pts[6], end, nx, size[0] / 2);
                v3ScaleAndAdd(pts[6], pts[6], nz, size[2] / 2);
                v3ScaleAndAdd(pts[7], end, nx, size[0] / 2);
                v3ScaleAndAdd(pts[7], pts[7], pz, size[2] / 2);

                var attributes = this.attributes;
                if (this.enableNormal) {
                    normals[0] = px;
                    normals[1] = nx;
                    normals[2] = py;
                    normals[3] = ny;
                    normals[4] = pz;
                    normals[5] = nz;

                    var vertexOffset = this._vertexOffset;
                    for (var i = 0; i < cubeFaces4.length; i++) {
                        var idx3 = this._triangleOffset * 3;
                        for (var k = 0; k < 6; k++) {
                            this.indices[idx3++] = vertexOffset + face4To3[k];
                        }
                        vertexOffset += 4;
                        this._triangleOffset += 2;
                    }

                    for (var i = 0; i < cubeFaces4.length; i++) {
                        var normal = normals[i];
                        for (var k = 0; k < 4; k++) {
                            var idx = cubeFaces4[i][k];
                            attributes.position.set(this._vertexOffset, pts[idx]);
                            attributes.normal.set(this._vertexOffset, normal);
                            attributes.color.set(this._vertexOffset++, color);
                        }
                    }
                }
                else {
                    for (var i = 0; i < cubeFaces3.length; i++) {
                        var idx3 = this._triangleOffset * 3;
                        for (var k = 0; k < 3; k++) {
                            this.indices[idx3 + k] = cubeFaces3[i][k] + this._vertexOffset;
                        }
                        this._triangleOffset++;
                    }

                    for (var i = 0; i < pts.length; i++) {
                        attributes.position.set(this._vertexOffset, pts[i]);
                        attributes.color.set(this._vertexOffset++, color);
                    }
                }
            }

            var endVerex = this._vertexOffset;

            for (var i = startVertex; i < endVerex; i++) {
                this._dataIndices[i] = dataIndex;
            }
        };
    })(),

    /**
     * Add a bar with bevel
     * @param {Array.<number>} start
     * @param {Array.<number>} end
     * @param {Array.<number>} orient  right direction
     * @param {Array.<number>} size size on x and z
     * @param {number} bevelSize
     * @param {number} bevelSegments
     * @param {Array.<number>} color
     */
    _addBevelBar: (function () {
        var px = vec3.create();
        var py = vec3.create();
        var pz = vec3.create();

        var rotateMat = mat3.create();

        var bevelStartSize = [];

        var xOffsets = [1, -1, -1, 1];
        var zOffsets = [1, 1, -1, -1];
        var yOffsets = [2, 0];

        return function (start, dir, leftDir, size, bevelSize, bevelSegments, color) {
            vec3.copy(py, dir);
            vec3.normalize(py, py);
            // x * y => z
            vec3.cross(pz, leftDir, py);
            vec3.normalize(pz, pz);
            // y * z => x
            vec3.cross(px, py, pz);
            vec3.normalize(pz, pz);

            rotateMat[0] = px[0]; rotateMat[1] = px[1]; rotateMat[2] = px[2];
            rotateMat[3] = py[0]; rotateMat[4] = py[1]; rotateMat[5] = py[2];
            rotateMat[6] = pz[0]; rotateMat[7] = pz[1]; rotateMat[8] = pz[2];

            bevelSize = Math.min(size[0], size[2]) / 2 * bevelSize;

            for (var i = 0; i < 3; i++) {
                bevelStartSize[i] = Math.max(size[i] - bevelSize * 2, 0);
            }
            var rx = (size[0] - bevelStartSize[0]) / 2;
            var ry = (size[1] - bevelStartSize[1]) / 2;
            var rz = (size[2] - bevelStartSize[2]) / 2;

            var pos = [];
            var normal = [];
            var vertexOffset = this._vertexOffset;

            var endIndices = [];
            for (var i = 0; i < 2; i++) {
                endIndices[i] = endIndices[i] = [];

                for (var m = 0; m <= bevelSegments; m++) {
                    for (var j = 0; j < 4; j++) {
                        if ((m === 0 && i === 0) || (i === 1 && m === bevelSegments)) {
                            endIndices[i].push(vertexOffset);
                        }
                        for (var n = 0; n <= bevelSegments; n++) {

                            var phi = n / bevelSegments * Math.PI / 2 + Math.PI / 2 * j;
                            var theta = m / bevelSegments * Math.PI / 2 + Math.PI / 2 * i;
                            // var r = rx < ry ? (rz < rx ? rz : rx) : (rz < ry ? rz : ry);
                            normal[0] = rx * Math.cos(phi) * Math.sin(theta);
                            normal[1] = ry * Math.cos(theta);
                            normal[2] = rz * Math.sin(phi) * Math.sin(theta);
                            pos[0] = normal[0] + xOffsets[j] * bevelStartSize[0] / 2;
                            pos[1] = (normal[1] + ry) + yOffsets[i] * bevelStartSize[1] / 2;
                            pos[2] = normal[2] + zOffsets[j] * bevelStartSize[2] / 2;

                            // Normal is not right if rx, ry, rz not equal.
                            if (!(Math.abs(rx - ry) < 1e-6 && Math.abs(ry - rz) < 1e-6)) {
                                normal[0] /= rx * rx;
                                normal[1] /= ry * ry;
                                normal[2] /= rz * rz;
                            }
                            vec3.normalize(normal, normal);

                            vec3.transformMat3(pos, pos, rotateMat);
                            vec3.transformMat3(normal, normal, rotateMat);
                            vec3.add(pos, pos, start);

                            this.attributes.position.set(vertexOffset, pos);
                            if (this.enableNormal) {
                                this.attributes.normal.set(vertexOffset, normal);
                            }
                            this.attributes.color.set(vertexOffset, color);
                            vertexOffset++;
                        }
                    }
                }
            }

            var widthSegments = bevelSegments * 4 + 3;
            var heightSegments = bevelSegments * 2 + 1;

            var len = widthSegments + 1;

            for (var j = 0; j < heightSegments; j ++) {
                for (var i = 0; i <= widthSegments; i ++) {
                    var i2 = j * len + i + this._vertexOffset;
                    var i1 = (j * len + (i + 1) % len) + this._vertexOffset;
                    var i4 = (j + 1) * len + (i + 1) % len + this._vertexOffset;
                    var i3 = (j + 1) * len + i + this._vertexOffset;

                    this.setTriangleIndices(this._triangleOffset++, [i4, i2, i1]);
                    this.setTriangleIndices(this._triangleOffset++, [i4, i3, i2]);
                }
            }

            // Close top and bottom
            this.setTriangleIndices(this._triangleOffset++, [endIndices[0][0], endIndices[0][2], endIndices[0][1]]);
            this.setTriangleIndices(this._triangleOffset++, [endIndices[0][0], endIndices[0][3], endIndices[0][2]]);
            this.setTriangleIndices(this._triangleOffset++, [endIndices[1][0], endIndices[1][1], endIndices[1][2]]);
            this.setTriangleIndices(this._triangleOffset++, [endIndices[1][0], endIndices[1][2], endIndices[1][3]]);

            this._vertexOffset = vertexOffset;
        };
    })()
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.defaults(BarsGeometry.prototype, __WEBPACK_IMPORTED_MODULE_1__dynamicConvertMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.defaults(BarsGeometry.prototype, __WEBPACK_IMPORTED_MODULE_2__trianglesSortMixin__["a" /* default */]);

/* harmony default export */ __webpack_exports__["a"] = (BarsGeometry);

/***/ }),
/* 231 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__component_common_componentShadingMixin__ = __webpack_require__(31);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_format__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_formatTooltip__ = __webpack_require__(39);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_createList__ = __webpack_require__(50);






var Bar3DSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({

    type: 'series.bar3D',

    dependencies: ['globe'],

    visualColorAccessPath: 'itemStyle.color',

    getInitialData: function (option, ecModel) {
        return Object(__WEBPACK_IMPORTED_MODULE_4__common_createList__["a" /* default */])(this);
    },

    getFormattedLabel: function (dataIndex, status, dataType, dimIndex) {
        var text = __WEBPACK_IMPORTED_MODULE_2__util_format__["a" /* default */].getFormattedLabel(this, dataIndex, status, dataType, dimIndex);
        if (text == null) {
            text = this.getData().get('z', dataIndex);
        }
        return text;
    },

    formatTooltip: function (dataIndex) {
        return Object(__WEBPACK_IMPORTED_MODULE_3__common_formatTooltip__["a" /* default */])(this, dataIndex);
    },

    defaultOption: {

        coordinateSystem: 'cartesian3D',

        globeIndex: 0,

        grid3DIndex: 0,

        zlevel: -10,

        // bevelSize, 0 has no bevel
        bevelSize: 0,
        // higher is smoother
        bevelSmoothness: 2,

        // Bar width and depth
        // barSize: [1, 1],

        // On grid plane when coordinateSystem is cartesian3D
        onGridPlane: 'xy',

        // Shading of globe
        shading: 'color',

        minHeight: 0,

        itemStyle: {
            opacity: 1
        },

        label: {
            show: false,
            distance: 2,
            textStyle: {
                fontSize: 14,
                color: '#000',
                backgroundColor: 'rgba(255,255,255,0.7)',
                padding: 3,
                borderRadius: 3
            }
        },

        emphasis: {
            label: {
                show: true
            }
        },

        animationDurationUpdate: 500
    }
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Bar3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_1__component_common_componentShadingMixin__["a" /* default */]);

/* unused harmony default export */ var _unused_webpack_default_export = (Bar3DSeries);

/***/ }),
/* 232 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__line3D_Line3DSeries__ = __webpack_require__(233);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__line3D_Line3DView__ = __webpack_require__(234);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__ = __webpack_require__(51);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(17);








__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default()('line3D', 'circle', null));

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('line3D'));

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerLayout(function (ecModel, api) {
    ecModel.eachSeriesByType('line3D', function (seriesModel) {
        var data = seriesModel.getData();
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys) {
            if (coordSys.type !== 'cartesian3D') {
                if (true) {
                    console.error('line3D needs cartesian3D coordinateSystem');
                }
                return;
            }
            var points = new Float32Array(data.count() * 3);

            var item = [];
            var out = [];

            var coordDims = coordSys.dimensions;
            var dims = coordDims.map(function (coordDim) {
                return seriesModel.coordDimToDataDim(coordDim)[0];
            });

            if (coordSys) {
                data.each(dims, function (x, y, z, idx) {
                    item[0] = x;
                    item[1] = y;
                    item[2] = z;

                    coordSys.dataToPoint(item, out);
                    points[idx * 3] = out[0];
                    points[idx * 3 + 1] = out[1];
                    points[idx * 3 + 2] = out[2];
                });
            }
            data.setLayout('points', points);
        }
    });
});

/***/ }),
/* 233 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_formatTooltip__ = __webpack_require__(39);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_createList__ = __webpack_require__(50);




var Line3DSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({

    type: 'series.line3D',

    dependencies: ['grid3D'],

    visualColorAccessPath: 'lineStyle.color',

    getInitialData: function (option, ecModel) {
        return Object(__WEBPACK_IMPORTED_MODULE_2__common_createList__["a" /* default */])(this);
    },

    formatTooltip: function (dataIndex) {
        return Object(__WEBPACK_IMPORTED_MODULE_1__common_formatTooltip__["a" /* default */])(this, dataIndex);
    },

    defaultOption: {
        coordinateSystem: 'cartesian3D',
        zlevel: -10,

        // Cartesian coordinate system
        grid3DIndex: 0,

        lineStyle: {
            width: 2
        },

        animationDurationUpdate: 500
    }
});

/* unused harmony default export */ var _unused_webpack_default_export = (Line3DSeries);

/***/ }),
/* 234 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_math_Matrix4__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Vector3__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_zrender_lib_contain_line__ = __webpack_require__(235);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_zrender_lib_contain_line___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_zrender_lib_contain_line__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_claygl_src_dep_glmatrix__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__util_shader_lines3D_glsl_js__ = __webpack_require__(46);











var vec3 = __WEBPACK_IMPORTED_MODULE_7_claygl_src_dep_glmatrix__["a" /* default */].vec3;

__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_8__util_shader_lines3D_glsl_js__["a" /* default */]);

/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({

    type: 'line3D',

    __ecgl__: true,

    init: function (ecModel, api) {

        this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();

        this._api = api;
    },

    render: function (seriesModel, ecModel, api) {
        var tmp = this._prevLine3DMesh;
        this._prevLine3DMesh = this._line3DMesh;
        this._line3DMesh = tmp;

        if (!this._line3DMesh) {
            this._line3DMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
                geometry: new __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__["a" /* default */]({
                    useNativeLine: false,
                    sortTriangles: true
                }),
                material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
                    shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.meshLines3D')
                }),
                // Render after axes
                renderOrder: 10
            });
            this._line3DMesh.geometry.pick = this._pick.bind(this);
        }

        this.groupGL.remove(this._prevLine3DMesh);
        this.groupGL.add(this._line3DMesh);

        var coordSys = seriesModel.coordinateSystem;
        if (coordSys && coordSys.viewGL) {
            coordSys.viewGL.add(this.groupGL);
            // TODO
            var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
            this._line3DMesh.material[methodName]('fragment', 'SRGB_DECODE');
        }
        this._doRender(seriesModel, api);

        this._data = seriesModel.getData();

        this._camera = coordSys.viewGL.camera;

        this.updateCamera();

        this._updateAnimation(seriesModel);
    },

    updateCamera: function () {
        this._updateNDCPosition();
    },

    _doRender: function (seriesModel, api) {
        var data = seriesModel.getData();
        var lineMesh = this._line3DMesh;

        lineMesh.geometry.resetOffset();

        var points = data.getLayout('points');

        var colorArr = [];
        var vertexColors = new Float32Array(points.length / 3 * 4);
        var colorOffset = 0;
        var hasTransparent = false;

        data.each(function (idx) {
            var color = data.getItemVisual(idx, 'color');
            var opacity = data.getItemVisual(idx, 'opacity');
            if (opacity == null) {
                opacity = 1;
            }

            __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color, colorArr);
            colorArr[3] *= opacity;
            vertexColors[colorOffset++] = colorArr[0];
            vertexColors[colorOffset++] = colorArr[1];
            vertexColors[colorOffset++] = colorArr[2];
            vertexColors[colorOffset++] = colorArr[3];

            if (colorArr[3] < 0.99) {
                hasTransparent = true;
            }
        });

        lineMesh.geometry.setVertexCount(
            lineMesh.geometry.getPolylineVertexCount(points)
        );
        lineMesh.geometry.setTriangleCount(
            lineMesh.geometry.getPolylineTriangleCount(points)
        );

        lineMesh.geometry.addPolyline(
            points, vertexColors,
            __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].firstNotNull(seriesModel.get('lineStyle.width'), 1)
        );

        lineMesh.geometry.dirty();
        lineMesh.geometry.updateBoundingBox();

        var material = lineMesh.material;
        material.transparent = hasTransparent;
        material.depthMask = !hasTransparent;

        var debugWireframeModel = seriesModel.getModel('debug.wireframe');
        if (debugWireframeModel.get('show')) {
            lineMesh.geometry.createAttribute('barycentric', 'float', 3);
            lineMesh.geometry.generateBarycentric();
            lineMesh.material.set('both', 'WIREFRAME_TRIANGLE');
            lineMesh.material.set(
                'wireframeLineColor', __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(
                    debugWireframeModel.get('lineStyle.color') || 'rgba(0,0,0,0.5)'
                )
            );
            lineMesh.material.set(
                'wireframeLineWidth', __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].firstNotNull(
                    debugWireframeModel.get('lineStyle.width'), 1
                )
            );
        }
        else {
            lineMesh.material.set('both', 'WIREFRAME_TRIANGLE');
        }

        this._points = points;

        this._initHandler(seriesModel, api);
    },

    _updateAnimation: function (seriesModel) {
        __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].updateVertexAnimation(
            [['prevPosition', 'position'],
            ['prevPositionPrev', 'positionPrev'],
            ['prevPositionNext', 'positionNext']],
            this._prevLine3DMesh,
            this._line3DMesh,
            seriesModel
        );
    },

    _initHandler: function (seriesModel, api) {
        var data = seriesModel.getData();
        var coordSys = seriesModel.coordinateSystem;
        var lineMesh = this._line3DMesh;

        var lastDataIndex = -1;

        lineMesh.seriesIndex = seriesModel.seriesIndex;

        lineMesh.off('mousemove');
        lineMesh.off('mouseout');
        lineMesh.on('mousemove', function (e) {
            var value = coordSys.pointToData(e.point.array);
            var dataIndex = data.indicesOfNearest('x', value[0])[0];
            if (dataIndex !== lastDataIndex) {
                // this._downplay(lastDataIndex);
                // this._highlight(dataIndex);

                api.dispatchAction({
                    type: 'grid3DShowAxisPointer',
                    value: [data.get('x', dataIndex), data.get('y', dataIndex), data.get('z', dataIndex)]
                });

                lineMesh.dataIndex = dataIndex;
            }


            lastDataIndex = dataIndex;
        }, this);
        lineMesh.on('mouseout', function (e) {
            // this._downplay(lastDataIndex);
            lastDataIndex = -1;
            lineMesh.dataIndex = -1;
            api.dispatchAction({
                type: 'grid3DHideAxisPointer'
            });
        }, this);
    },

    // _highlight: function (dataIndex) {
    //     var data = this._data;
    //     if (!data) {
    //         return;
    //     }

    // },

    // _downplay: function (dataIndex) {
    //     var data = this._data;
    //     if (!data) {
    //         return;
    //     }
    // },

    _updateNDCPosition: function () {

        var worldViewProjection = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_math_Matrix4__["a" /* default */]();
        var camera = this._camera;
        __WEBPACK_IMPORTED_MODULE_4_claygl_src_math_Matrix4__["a" /* default */].multiply(worldViewProjection, camera.projectionMatrix, camera.viewMatrix);

        var positionNDC = this._positionNDC;
        var points = this._points;
        var nPoints = points.length / 3;
        if (!positionNDC || positionNDC.length / 2 !== nPoints) {
            positionNDC = this._positionNDC = new Float32Array(nPoints * 2);
        }
        var pos = [];
        for (var i = 0; i < nPoints; i++) {
            var i3 = i * 3;
            var i2 = i * 2;
            pos[0] = points[i3];
            pos[1] = points[i3 + 1];
            pos[2] = points[i3 + 2];
            pos[3] = 1;

            vec3.transformMat4(pos, pos, worldViewProjection.array);
            positionNDC[i2] = pos[0] / pos[3];
            positionNDC[i2 + 1] = pos[1] / pos[3];
        }
    },

    _pick: function (x, y, renderer, camera, renderable, out) {
        var positionNDC = this._positionNDC;
        var seriesModel = this._data.hostModel;
        var lineWidth = seriesModel.get('lineStyle.width');

        var dataIndex = -1;
        var width = renderer.viewport.width;
        var height = renderer.viewport.height;

        var halfWidth = width * 0.5;
        var halfHeight = height * 0.5;
        x = (x + 1) * halfWidth;
        y = (y + 1) * halfHeight;

        for (var i = 1; i < positionNDC.length / 2; i++) {
            var x0 = (positionNDC[(i - 1) * 2] + 1) * halfWidth;
            var y0 = (positionNDC[(i - 1) * 2 + 1] + 1) * halfHeight;
            var x1 = (positionNDC[i * 2] + 1) * halfWidth;
            var y1 = (positionNDC[i * 2 + 1] + 1) * halfHeight;

            if (__WEBPACK_IMPORTED_MODULE_6_zrender_lib_contain_line___default.a.containStroke(x0, y0, x1, y1, lineWidth, x, y)) {
                var dist0 = (x0 - x) * (x0 - x) + (y0 - y) * (y0 - y);
                var dist1 = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y);
                // Nearest point.
                dataIndex = dist0 < dist1 ? (i - 1) : i;
            }
        }

        if (dataIndex >= 0) {
            var i3 = dataIndex * 3;
            var point = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Vector3__["a" /* default */](
                this._points[i3],
                this._points[i3 + 1],
                this._points[i3 + 2]
            );

            out.push({
                dataIndex: dataIndex,
                point: point,
                pointWorld: point.clone(),
                target: this._line3DMesh,
                distance: this._camera.getWorldPosition().dist(point)
            });
        }
    },

    remove: function () {
        this.groupGL.removeAll();
    },

    dispose: function () {
        this.groupGL.removeAll();
    }
}));

/***/ }),
/* 235 */
/***/ (function(module, exports) {

/**
 * 线段包含判断
 * @param  {number}  x0
 * @param  {number}  y0
 * @param  {number}  x1
 * @param  {number}  y1
 * @param  {number}  lineWidth
 * @param  {number}  x
 * @param  {number}  y
 * @return {boolean}
 */
function containStroke(x0, y0, x1, y1, lineWidth, x, y) {
  if (lineWidth === 0) {
    return false;
  }

  var _l = lineWidth;
  var _a = 0;
  var _b = x0; // Quick reject

  if (y > y0 + _l && y > y1 + _l || y < y0 - _l && y < y1 - _l || x > x0 + _l && x > x1 + _l || x < x0 - _l && x < x1 - _l) {
    return false;
  }

  if (x0 !== x1) {
    _a = (y0 - y1) / (x0 - x1);
    _b = (x0 * y1 - x1 * y0) / (x0 - x1);
  } else {
    return Math.abs(x - x0) <= _l / 2;
  }

  var tmp = _a * x - y + _b;

  var _s = tmp * tmp / (_a * _a + 1);

  return _s <= _l / 2 * _l / 2;
}

exports.containStroke = containStroke;

/***/ }),
/* 236 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__scatter3D_Scatter3DSeries__ = __webpack_require__(237);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__scatter3D_Scatter3DView__ = __webpack_require__(238);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__ = __webpack_require__(51);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(17);







__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default()('scatter3D', 'circle', null));

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('scatter3D'));

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerLayout({
    seriesType: 'scatter3D',
    reset: function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys) {
            var coordDims = coordSys.dimensions;
            if (coordDims.length < 3) {
                if (true) {
                    console.error('scatter3D needs 3D coordinateSystem');
                }
                return;
            }
            var dims = coordDims.map(function (coordDim) {
                return seriesModel.coordDimToDataDim(coordDim)[0];
            });

            var item = [];
            var out = [];

            return {
                progress: function (params, data) {
                    var points = new Float32Array((params.end - params.start) * 3);
                    for (var idx = params.start; idx < params.end; idx++) {
                        var idx3 = (idx - params.start) * 3;
                        item[0] = data.get(dims[0], idx);
                        item[1] = data.get(dims[1], idx);
                        item[2] = data.get(dims[2], idx);
                        coordSys.dataToPoint(item, out);
                        points[idx3] = out[0];
                        points[idx3 + 1] = out[1];
                        points[idx3 + 2] = out[2];
                    }
                    data.setLayout('points', points);
                }
            };
        }
    }
});

/***/ }),
/* 237 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_format__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_formatTooltip__ = __webpack_require__(39);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_createList__ = __webpack_require__(50);





__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({

    type: 'series.scatter3D',

    dependencies: ['globe', 'grid3D', 'geo3D'],

    visualColorAccessPath: 'itemStyle.color',

    getInitialData: function (option, ecModel) {
        return Object(__WEBPACK_IMPORTED_MODULE_3__common_createList__["a" /* default */])(this);
    },

    getFormattedLabel: function (dataIndex, status, dataType, dimIndex) {
        var text = __WEBPACK_IMPORTED_MODULE_1__util_format__["a" /* default */].getFormattedLabel(this, dataIndex, status, dataType, dimIndex);
        if (text == null) {
            var data = this.getData();
            var lastDim = data.dimensions[data.dimensions.length - 1];
            text = data.get(lastDim, dataIndex);
        }
        return text;
    },

    formatTooltip: function (dataIndex) {
        return Object(__WEBPACK_IMPORTED_MODULE_2__common_formatTooltip__["a" /* default */])(this, dataIndex);
    },

    defaultOption: {
        coordinateSystem: 'cartesian3D',
        zlevel: -10,

        progressive: 1e5,
        progressiveThreshold: 1e5,

        // Cartesian coordinate system
        grid3DIndex: 0,

        globeIndex: 0,

        symbol: 'circle',
        symbolSize: 10,

        // Support source-over, lighter
        blendMode: 'source-over',

        label: {
            show: false,
            position: 'right',
            // Screen space distance
            distance: 5,

            textStyle: {
                fontSize: 14,
                color: '#000',
                backgroundColor: 'rgba(255,255,255,0.7)',
                padding: 3,
                borderRadius: 3
            }
        },

        itemStyle: {
            opacity: 0.8
        },

        emphasis: {
            label: {
                show: true
            }
        },

        animationDurationUpdate: 500
    }
});

/***/ }),
/* 238 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_format__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_PointsBuilder__ = __webpack_require__(67);







__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({

    type: 'scatter3D',

    __ecgl__: true,

    init: function (ecModel, api) {

        this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();

        this._pointsBuilderList = [];
        this._currentStep = 0;
    },

    render: function (seriesModel, ecModel, api) {
        this.groupGL.removeAll();
        if (!seriesModel.getData().count()) {
            return;
        }

        var coordSys = seriesModel.coordinateSystem;
        if (coordSys && coordSys.viewGL) {
            coordSys.viewGL.add(this.groupGL);
            this._camera = coordSys.viewGL.camera;

            var pointsBuilder = this._pointsBuilderList[0];
            if (!pointsBuilder) {
                pointsBuilder = this._pointsBuilderList[0] = new __WEBPACK_IMPORTED_MODULE_4__common_PointsBuilder__["a" /* default */](false, api);
            }
            this._pointsBuilderList.length = 1;

            this.groupGL.add(pointsBuilder.rootNode);
            pointsBuilder.update(seriesModel, ecModel, api);
            pointsBuilder.updateView(coordSys.viewGL.camera);
        }
        else {
            if (true) {
                throw new Error('Invalid coordinate system');
            }
        }
    },

    incrementalPrepareRender: function (seriesModel, ecModel, api) {
        var coordSys = seriesModel.coordinateSystem;
        if (coordSys && coordSys.viewGL) {
            coordSys.viewGL.add(this.groupGL);
            this._camera = coordSys.viewGL.camera;
        }
        else {
            if (true) {
                throw new Error('Invalid coordinate system');
            }
        }

        this.groupGL.removeAll();
        this._currentStep = 0;
    },

    incrementalRender: function (params, seriesModel, ecModel, api) {
        // TODO Sort transparency.
        if (params.end <= params.start) {
            return;
        }
        var pointsBuilder = this._pointsBuilderList[this._currentStep];
        if (!pointsBuilder) {
            pointsBuilder = new __WEBPACK_IMPORTED_MODULE_4__common_PointsBuilder__["a" /* default */](false, api);
            this._pointsBuilderList[this._currentStep] = pointsBuilder;
        }
        this.groupGL.add(pointsBuilder.rootNode);

        pointsBuilder.update(seriesModel, ecModel, api, params.start, params.end);
        pointsBuilder.updateView(seriesModel.coordinateSystem.viewGL.camera);

        this._currentStep++;
    },

    updateCamera: function () {
        this._pointsBuilderList.forEach(function (pointsBuilder) {
            pointsBuilder.updateView(this._camera);
        }, this);
    },

    highlight: function (seriesModel, ecModel, api, payload) {
        this._toggleStatus('highlight', seriesModel, ecModel, api, payload);
    },

    downplay: function (seriesModel, ecModel, api, payload) {
        this._toggleStatus('downplay', seriesModel, ecModel, api, payload);
    },

    _toggleStatus: function (status, seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData();
        var dataIndex = __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].queryDataIndex(data, payload);

        var isHighlight = status === 'highlight';
        if (dataIndex != null) {
            __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(__WEBPACK_IMPORTED_MODULE_3__util_format__["a" /* default */].normalizeToArray(dataIndex), function (dataIdx) {
                for (var i = 0; i < this._pointsBuilderList.length; i++) {
                    var pointsBuilder = this._pointsBuilderList[i];
                    isHighlight ? pointsBuilder.highlight(data, dataIdx) : pointsBuilder.downplay(data, dataIdx);
                }
            }, this);
        }
        else {
            // PENDING, OPTIMIZE
            data.each(function (dataIdx) {
                for (var i = 0; i < this._pointsBuilderList.length; i++) {
                    var pointsBuilder = this._pointsBuilderList[i];
                    isHighlight ? pointsBuilder.highlight(data, dataIdx) : pointsBuilder.downplay(data, dataIdx);
                }
            });
        }
    },

    dispose: function () {
        this.groupGL.removeAll();
    },

    remove: function () {
        this.groupGL.removeAll();
    }
});

/***/ }),
/* 239 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


function makeSprite(size, canvas, draw) {
    // http://simonsarris.com/blog/346-how-you-clear-your-canvas-matters
    // http://jsperf.com/canvasclear
    // Set width and height is fast
    // And use the exist canvas if possible
    // http://jsperf.com/create-canvas-vs-set-width-height/2
    var canvas = canvas || document.createElement('canvas');
    canvas.width = size;
    canvas.height = size;
    var ctx = canvas.getContext('2d');

    draw && draw(ctx);

    return canvas;
}

function makePath(symbol, symbolSize, style, marginBias) {
    if (!__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(symbolSize)) {
        symbolSize = [symbolSize, symbolSize];
    }
    var margin = spriteUtil.getMarginByStyle(style, marginBias);
    var width = symbolSize[0] + margin.left + margin.right;
    var height = symbolSize[1] + margin.top + margin.bottom;
    var path = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.createSymbol(symbol, 0, 0, symbolSize[0], symbolSize[1]);

    var size = Math.max(width, height);

    path.position = [margin.left, margin.top];
    if (width > height) {
        path.position[1] += (size - height) / 2;
    }
    else {
        path.position[0] += (size - width) / 2;
    }

    var rect = path.getBoundingRect();
    path.position[0] -= rect.x;
    path.position[1] -= rect.y;

    path.setStyle(style);

    path.update();

    path.__size = size;

    return path;
}

    // http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf
function generateSDF(ctx, sourceImageData, range) {

    var sourceWidth = sourceImageData.width;
    var sourceHeight = sourceImageData.height;

    var width = ctx.canvas.width;
    var height = ctx.canvas.height;

    var scaleX = sourceWidth / width;
    var scaleY = sourceHeight / height;

    function sign(r) {
        return r < 128 ? 1 : -1;
    }
    function searchMinDistance(x, y) {
        var minDistSqr = Infinity;
        x = Math.floor(x * scaleX);
        y = Math.floor(y * scaleY);
        var i = y * sourceWidth + x;
        var r = sourceImageData.data[i * 4];
        var a = sign(r);
        // Search for min distance
        for (var y2 = Math.max(y - range, 0); y2 < Math.min(y + range, sourceHeight); y2++) {
            for (var x2 = Math.max(x - range, 0); x2 < Math.min(x + range, sourceWidth); x2++) {
                var i = y2 * sourceWidth + x2;
                var r2 = sourceImageData.data[i * 4];
                var b = sign(r2);
                var dx = x2 - x;
                var dy = y2 - y;
                if (a !== b) {
                    var distSqr = dx * dx + dy * dy;
                    if (distSqr < minDistSqr) {
                        minDistSqr = distSqr;
                    }
                }
            }
        }
        return a * Math.sqrt(minDistSqr);
    }

    var sdfImageData = ctx.createImageData(width, height);
    for (var y = 0; y < height; y++) {
        for (var x = 0; x < width; x++) {
            var dist = searchMinDistance(x, y);

            var normalized = dist / range * 0.5 + 0.5;
            var i = (y * width + x) * 4;
            sdfImageData.data[i++] = (1.0 - normalized) * 255;
            sdfImageData.data[i++] = (1.0 - normalized) * 255;
            sdfImageData.data[i++] = (1.0 - normalized) * 255;
            sdfImageData.data[i++] = 255;
        }
    }

    return sdfImageData;
}

var spriteUtil = {

    getMarginByStyle: function (style) {
        var minMargin = style.minMargin || 0;

        var lineWidth = 0;
        if (style.stroke && style.stroke !== 'none') {
            lineWidth = style.lineWidth == null ? 1 : style.lineWidth;
        }
        var shadowBlurSize = style.shadowBlur || 0;
        var shadowOffsetX = style.shadowOffsetX || 0;
        var shadowOffsetY = style.shadowOffsetY || 0;

        var margin = {};
        margin.left = Math.max(lineWidth / 2, -shadowOffsetX + shadowBlurSize, minMargin);
        margin.right = Math.max(lineWidth / 2, shadowOffsetX + shadowBlurSize, minMargin);
        margin.top = Math.max(lineWidth / 2, -shadowOffsetY + shadowBlurSize, minMargin);
        margin.bottom = Math.max(lineWidth / 2, shadowOffsetY + shadowBlurSize, minMargin);

        return margin;
    },

    // TODO Not consider shadowOffsetX, shadowOffsetY.
    /**
     * @param {string} symbol
     * @param {number | Array.<number>} symbolSize
     * @param {Object} style
     */
    createSymbolSprite: function (symbol, symbolSize, style, canvas) {
        var path = makePath(symbol, symbolSize, style);

        var margin = spriteUtil.getMarginByStyle(style);

        return {
            image: makeSprite(path.__size, canvas, function (ctx) {
                path.brush(ctx);
            }),
            margin: margin
        };
    },

    createSDFFromCanvas: function (canvas, size, range, outCanvas) {
        // TODO Create a low resolution SDF from high resolution image.
        return makeSprite(size, outCanvas, function (outCtx) {
            var ctx = canvas.getContext('2d');
            var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);

            outCtx.putImageData(generateSDF(outCtx, imgData, range), 0, 0);
        });
    },

    createSimpleSprite: function (size, canvas) {
        return makeSprite(size, canvas, function (ctx) {
            var halfSize = size / 2;
            ctx.beginPath();
            ctx.arc(halfSize, halfSize, 60, 0, Math.PI * 2, false) ;
            ctx.closePath();

            var gradient = ctx.createRadialGradient(
                halfSize, halfSize, 0, halfSize, halfSize, halfSize
            );
            gradient.addColorStop(0, 'rgba(255, 255, 255, 1)');
            gradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.5)');
            gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
            ctx.fillStyle = gradient;
            ctx.fill();
        });
    }
};

/* harmony default export */ __webpack_exports__["a"] = (spriteUtil);

/***/ }),
/* 240 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_geometry_verticesSortMixin__ = __webpack_require__(241);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__sdfSprite_glsl_js__ = __webpack_require__(242);




var vec4 = __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__["a" /* default */].vec4;


__WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_4__sdfSprite_glsl_js__["a" /* default */]);

var PointsMesh = __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Mesh.extend(function () {
    var geometry = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Geometry({
        dynamic: true,
        attributes: {
            color: new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Geometry.Attribute('color', 'float', 4, 'COLOR'),
            position: new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Geometry.Attribute('position', 'float', 3, 'POSITION'),
            size: new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Geometry.Attribute('size', 'float', 1),
            prevPosition: new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Geometry.Attribute('prevPosition', 'float', 3),
            prevSize: new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Geometry.Attribute('prevSize', 'float', 1)
        }
    });
    __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default.a.util.extend(geometry, __WEBPACK_IMPORTED_MODULE_1__util_geometry_verticesSortMixin__["a" /* default */]);

    var material = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Material({
        shader: __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].createShader('ecgl.sdfSprite'),
        transparent: true,
        depthMask: false
    });
    material.enableTexture('sprite');
    material.define('both', 'VERTEX_COLOR');
    material.define('both', 'VERTEX_SIZE');

    var sdfTexture = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Texture2D({
        image: document.createElement('canvas'),
        flipY: false
    });

    material.set('sprite', sdfTexture);

    // Custom pick methods.
    geometry.pick = this._pick.bind(this);

    return {
        geometry: geometry,
        material: material,
        mode: __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Mesh.POINTS,

        sizeScale: 1
    };
}, {

    _pick: function (x, y, renderer, camera, renderable, out) {
        var positionNDC = this._positionNDC;
        if (!positionNDC) {
            return;
        }

        var viewport = renderer.viewport;
        var ndcScaleX = 2 / viewport.width;
        var ndcScaleY = 2 / viewport.height;
        // From near to far. indices have been sorted.
        for (var i = this.geometry.vertexCount - 1; i >= 0; i--) {
            var idx;
            if (!this.geometry.indices) {
                idx = i;
            }
            else {
                idx = this.geometry.indices[i];
            }

            var cx = positionNDC[idx * 2];
            var cy = positionNDC[idx * 2 + 1];

            var size = this.geometry.attributes.size.get(idx) / this.sizeScale;
            var halfSize = size / 2;

            if (
                x > (cx - halfSize * ndcScaleX) && x < (cx + halfSize * ndcScaleX)
                && y > (cy - halfSize * ndcScaleY) && y < (cy + halfSize * ndcScaleY)
            ) {
                var point = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Vector3();
                var pointWorld = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Vector3();
                this.geometry.attributes.position.get(idx, point.array);
                __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Vector3.transformMat4(pointWorld, point, this.worldTransform);
                out.push({
                    vertexIndex: idx,
                    point: point,
                    pointWorld: pointWorld,
                    target: this,
                    distance: pointWorld.distance(camera.getWorldPosition())
                });
            }
        }
    },

    updateNDCPosition: function (worldViewProjection, is2D, api) {
        var positionNDC = this._positionNDC;
        var geometry = this.geometry;
        if (!positionNDC || positionNDC.length / 2 !== geometry.vertexCount) {
            positionNDC = this._positionNDC = new Float32Array(geometry.vertexCount * 2);
        }

        var pos = vec4.create();
        for (var i = 0; i < geometry.vertexCount; i++) {
            geometry.attributes.position.get(i, pos);
            pos[3] = 1;
            vec4.transformMat4(pos, pos, worldViewProjection.array);
            vec4.scale(pos, pos, 1 / pos[3]);

            positionNDC[i * 2] = pos[0];
            positionNDC[i * 2 + 1] = pos[1];
        }
    }
});

/* harmony default export */ __webpack_exports__["a"] = (PointsMesh);

/***/ }),
/* 241 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__ProgressiveQuickSort__ = __webpack_require__(97);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__ = __webpack_require__(6);


var vec3 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__["a" /* default */].vec3;

/* harmony default export */ __webpack_exports__["a"] = ({

    needsSortVertices: function () {
        return this.sortVertices;
    },

    needsSortVerticesProgressively: function () {
        return this.needsSortVertices() && this.vertexCount >= 2e4;
    },

    doSortVertices: function (cameraPos, frame) {
        var indices = this.indices;
        var p = vec3.create();

        if (!indices) {
            indices = this.indices = this.vertexCount > 0xffff ? new Uint32Array(this.vertexCount) : new Uint16Array(this.vertexCount);
            for (var i = 0; i < indices.length; i++) {
                indices[i] = i;
            }
        }
        // Do progressive quick sort.
        if (frame === 0) {
            var posAttr = this.attributes.position;
            var cameraPos = cameraPos.array;
            var noneCount = 0;
            if (!this._zList || this._zList.length !== this.vertexCount) {
                this._zList = new Float32Array(this.vertexCount);
            }

            var firstZ;
            for (var i = 0; i < this.vertexCount; i++) {
                posAttr.get(i, p);
                // Camera position is in object space
                var z = vec3.sqrDist(p, cameraPos);
                if (isNaN(z)) {
                    // Put far away, NaN value may cause sort slow
                    z = 1e7;
                    noneCount++;
                }
                if (i === 0) {
                    firstZ = z;
                    z = 0;
                }
                else {
                    // Only store the difference to avoid the precision issue.
                    z = z - firstZ;
                }
                this._zList[i] = z;
            }

            this._noneCount = noneCount;
        }

        if (this.vertexCount < 2e4) {
            // Use simple native sort for simple geometries.
            if (frame === 0) {
                this._simpleSort(this._noneCount / this.vertexCount > 0.05);
            }
        }
        else {
            for (var i = 0; i < 3; i++) {
                this._progressiveQuickSort(frame * 3 + i);
            }
        }

        this.dirtyIndices();
    },

    _simpleSort: function (useNativeQuickSort) {
        var zList = this._zList;
        var indices = this.indices;
        function compare(a, b) {
            // Sort from far to near. which is descending order
            return zList[b] - zList[a];
        }

        // When too much value are equal, using native quick sort with three partition..
        // or the simple quick sort will be nearly O(n*n)
        // http://stackoverflow.com/questions/5126586/quicksort-complexity-when-all-the-elements-are-same

        // Otherwise simple quicksort is more effecient than v8 native quick sort when data all different.
        if (useNativeQuickSort) {
            Array.prototype.sort.call(indices, compare);
        }
        else {
            __WEBPACK_IMPORTED_MODULE_0__ProgressiveQuickSort__["a" /* default */].sort(indices, compare, 0, indices.length - 1);
        }
    },

    _progressiveQuickSort: function (frame) {
        var zList = this._zList;
        var indices = this.indices;

        this._quickSort = this._quickSort || new __WEBPACK_IMPORTED_MODULE_0__ProgressiveQuickSort__["a" /* default */]();

        this._quickSort.step(indices, function (a, b) {
            return zList[b] - zList[a];
        }, frame);
    }
});

/***/ }),
/* 242 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.sdfSprite.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform float elapsedTime : 0;\n\nattribute vec3 position : POSITION;\n\n#ifdef VERTEX_SIZE\nattribute float size;\n#else\nuniform float u_Size;\n#endif\n\n#ifdef VERTEX_COLOR\nattribute vec4 a_FillColor: COLOR;\nvarying vec4 v_Color;\n#endif\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nattribute float prevSize;\nuniform float percent : 1.0;\n#endif\n\n\n#ifdef POSITIONTEXTURE_ENABLED\nuniform sampler2D positionTexture;\n#endif\n\nvarying float v_Size;\n\nvoid main()\n{\n\n#ifdef POSITIONTEXTURE_ENABLED\n gl_Position = worldViewProjection * vec4(texture2D(positionTexture, position.xy).xy, -10.0, 1.0);\n#else\n\n #ifdef VERTEX_ANIMATION\n vec3 pos = mix(prevPosition, position, percent);\n #else\n vec3 pos = position;\n #endif\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n#endif\n\n#ifdef VERTEX_SIZE\n#ifdef VERTEX_ANIMATION\n v_Size = mix(prevSize, size, percent);\n#else\n v_Size = size;\n#endif\n#else\n v_Size = u_Size;\n#endif\n\n#ifdef VERTEX_COLOR\n v_Color = a_FillColor;\n #endif\n\n gl_PointSize = v_Size;\n}\n\n@end\n\n@export ecgl.sdfSprite.fragment\n\nuniform vec4 color: [1, 1, 1, 1];\nuniform vec4 strokeColor: [1, 1, 1, 1];\nuniform float smoothing: 0.07;\n\nuniform float lineWidth: 0.0;\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\nvarying float v_Size;\n\nuniform sampler2D sprite;\n\n@import clay.util.srgb\n\nvoid main()\n{\n gl_FragColor = color;\n\n vec4 _strokeColor = strokeColor;\n\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n #endif\n\n#ifdef SPRITE_ENABLED\n float d = texture2D(sprite, gl_PointCoord).r;\n gl_FragColor.a *= smoothstep(0.5 - smoothing, 0.5 + smoothing, d);\n\n if (lineWidth > 0.0) {\n float sLineWidth = lineWidth / 2.0;\n\n float outlineMaxValue0 = 0.5 + sLineWidth;\n float outlineMaxValue1 = 0.5 + sLineWidth + smoothing;\n float outlineMinValue0 = 0.5 - sLineWidth - smoothing;\n float outlineMinValue1 = 0.5 - sLineWidth;\n\n if (d <= outlineMaxValue1 && d >= outlineMinValue0) {\n float a = _strokeColor.a;\n if (d <= outlineMinValue1) {\n a = a * smoothstep(outlineMinValue0, outlineMinValue1, d);\n }\n else {\n a = a * smoothstep(outlineMaxValue1, outlineMaxValue0, d);\n }\n gl_FragColor.rgb = mix(gl_FragColor.rgb * gl_FragColor.a, _strokeColor.rgb, a);\n gl_FragColor.a = gl_FragColor.a * (1.0 - a) + a;\n }\n }\n#endif\n\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n}\n@end");


/***/ }),
/* 243 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__lines3D_lines3DLayout__ = __webpack_require__(244);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__lines3D_Lines3DView__ = __webpack_require__(245);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__lines3D_Lines3DSeries__ = __webpack_require__(248);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(17);









__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('lines3D'));


__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'lines3DPauseEffect',
    event: 'lines3deffectpaused',
    update: 'series.lines3D:pauseEffect'
}, function () {});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'lines3DResumeEffect',
    event: 'lines3deffectresumed',
    update: 'series.lines3D:resumeEffect'
}, function () {});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'lines3DToggleEffect',
    event: 'lines3deffectchanged',
    update: 'series.lines3D:toggleEffect'
}, function () {});

/***/ }),
/* 244 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__ = __webpack_require__(6);


var vec3 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__["a" /* default */].vec3;
var vec2 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__["a" /* default */].vec2;
var normalize = vec3.normalize;
var cross = vec3.cross;
var sub = vec3.sub;
var add = vec3.add;
var create = vec3.create;

var normal = create();
var tangent = create();
var bitangent = create();
var halfVector = create();

var coord0 = [];
var coord1 = [];

function getCubicPointsOnGlobe(coords, coordSys) {
    vec2.copy(coord0, coords[0]);
    vec2.copy(coord1, coords[1]);

    var pts = [];
    var p0 = pts[0] = create();
    var p1 = pts[1] = create();
    var p2 = pts[2] = create();
    var p3 = pts[3] = create();
    coordSys.dataToPoint(coord0, p0);
    coordSys.dataToPoint(coord1, p3);
    // Get p1
    normalize(normal, p0);
    // TODO p0-p3 is parallel with normal
    sub(tangent, p3, p0);
    normalize(tangent, tangent);
    cross(bitangent, tangent, normal);
    normalize(bitangent, bitangent);
    cross(tangent, normal, bitangent);
    // p1 is half vector of p0 and tangent on p0
    add(p1, normal, tangent);
    normalize(p1, p1);

    // Get p2
    normalize(normal, p3);
    sub(tangent, p0, p3);
    normalize(tangent, tangent);
    cross(bitangent, tangent, normal);
    normalize(bitangent, bitangent);
    cross(tangent, normal, bitangent);
    // p2 is half vector of p3 and tangent on p3
    add(p2, normal, tangent);
    normalize(p2, p2);

    // Project distance of p0 on halfVector
    add(halfVector, p0, p3);
    normalize(halfVector, halfVector);
    var projDist = vec3.dot(p0, halfVector);
    // Angle of halfVector and p1
    var cosTheta = vec3.dot(halfVector, p1);

    var len = (Math.max(vec3.len(p0), vec3.len(p3)) - projDist) / cosTheta * 2;

    vec3.scaleAndAdd(p1, p0, p1, len);
    vec3.scaleAndAdd(p2, p3, p2, len);

    return pts;
}

function getCubicPointsOnPlane(coords, coordSys, up) {
    var pts = [];
    var p0 = pts[0] = vec3.create();
    var p1 = pts[1] = vec3.create();
    var p2 = pts[2] = vec3.create();
    var p3 = pts[3] = vec3.create();

    coordSys.dataToPoint(coords[0], p0);
    coordSys.dataToPoint(coords[1], p3);

    var len = vec3.dist(p0, p3);
    vec3.lerp(p1, p0, p3, 0.3);
    vec3.lerp(p2, p0, p3, 0.3);

    vec3.scaleAndAdd(p1, p1, up, Math.min(len * 0.1, 10));
    vec3.scaleAndAdd(p2, p2, up, Math.min(len * 0.1, 10));

    return pts;
}

function getPolylinePoints(coords, coordSys) {
    var pts = new Float32Array(coords.length * 3);
    var off = 0;
    var pt = [];
    for (var i = 0; i < coords.length; i++) {
        coordSys.dataToPoint(coords[i], pt);
        pts[off++] = pt[0];
        pts[off++] = pt[1];
        pts[off++] = pt[2];
    }
    return pts;
}

function prepareCoords(data) {
    var coordsList = [];

    data.each(function (idx) {
        var itemModel = data.getItemModel(idx);
        var coords = (itemModel.option instanceof Array) ?
            itemModel.option : itemModel.getShallow('coords', true);

        if (true) {
            if (!(coords instanceof Array && coords.length > 0 && coords[0] instanceof Array)) {
                throw new Error('Invalid coords ' + JSON.stringify(coords) + '. Lines must have 2d coords array in data item.');
            }
        }
        coordsList.push(coords);
    });

    return {
        coordsList: coordsList
    };
}

function layoutGlobe(seriesModel, coordSys) {
    var data = seriesModel.getData();
    var isPolyline = seriesModel.get('polyline');

    data.setLayout('lineType', isPolyline ? 'polyline' : 'cubicBezier');

    var res = prepareCoords(data);

    data.each(function (idx) {
        var coords = res.coordsList[idx];
        var getPointsMethod = isPolyline ? getPolylinePoints : getCubicPointsOnGlobe;
        data.setItemLayout(idx, getPointsMethod(coords, coordSys));
    });
}

function layoutOnPlane(seriesModel, coordSys, normal) {
    var data = seriesModel.getData();
    var isPolyline = seriesModel.get('polyline');

    var res = prepareCoords(data);

    data.setLayout('lineType', isPolyline ? 'polyline' : 'cubicBezier');

    data.each(function (idx) {
        var coords = res.coordsList[idx];
        var pts = isPolyline ? getPolylinePoints(coords, coordSys)
            : getCubicPointsOnPlane(coords, coordSys, normal);
        data.setItemLayout(idx, pts);
    });
}

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerLayout(function (ecModel, api) {
    ecModel.eachSeriesByType('lines3D', function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;
        if (coordSys.type === 'globe') {
            layoutGlobe(seriesModel, coordSys);
        }
        else if (coordSys.type === 'geo3D') {
            layoutOnPlane(seriesModel, coordSys, [0, 1, 0]);
        }
        else if (coordSys.type === 'mapbox3D' || coordSys.type === 'maptalks3D') {
            layoutOnPlane(seriesModel, coordSys, [0, 0, 1]);
        }
    });
});

/***/ }),
/* 245 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_geometry_Lines3D__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__TrailMesh2__ = __webpack_require__(246);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_shader_lines3D_glsl_js__ = __webpack_require__(46);



// import TrailMesh from './TrailMesh';



__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_4__util_shader_lines3D_glsl_js__["a" /* default */]);

function getCoordSysSize(coordSys) {
    if (coordSys.radius != null) {
        return coordSys.radius;
    }
    if (coordSys.size != null) {
        return Math.max(coordSys.size[0], coordSys.size[1], coordSys.size[2]);
    }
    else {
        return 100;
    }
}

/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({

    type: 'lines3D',

    __ecgl__: true,

    init: function (ecModel, api) {
        this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();

        this._meshLinesMaterial = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
            shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.meshLines3D'),
            transparent: true,
            depthMask: false
        });
        this._linesMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
            geometry: new __WEBPACK_IMPORTED_MODULE_2__util_geometry_Lines3D__["a" /* default */](),
            material: this._meshLinesMaterial,
            $ignorePicking: true
        });

        // this._trailMesh = new TrailMesh();
        this._trailMesh = new __WEBPACK_IMPORTED_MODULE_3__TrailMesh2__["a" /* default */]();
    },

    render: function (seriesModel, ecModel, api) {

        this.groupGL.add(this._linesMesh);

        var coordSys = seriesModel.coordinateSystem;
        var data = seriesModel.getData();

        if (coordSys && coordSys.viewGL) {
            var viewGL = coordSys.viewGL;
            viewGL.add(this.groupGL);

            this._updateLines(seriesModel, ecModel, api);

            var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
            this._linesMesh.material[methodName]('fragment', 'SRGB_DECODE');
            this._trailMesh.material[methodName]('fragment', 'SRGB_DECODE');
        }

        var trailMesh = this._trailMesh;
        trailMesh.stopAnimation();

        if (seriesModel.get('effect.show')) {
            this.groupGL.add(trailMesh);

            trailMesh.updateData(data, api, this._linesMesh.geometry);

            trailMesh.__time = trailMesh.__time || 0;
            var time = 3600 * 1000; // 1hour
            this._curveEffectsAnimator = trailMesh.animate('', { loop: true })
                .when(time, {
                    __time: time
                })
                .during(function () {
                    trailMesh.setAnimationTime(trailMesh.__time);
                })
                .start();
        }
        else {
            this.groupGL.remove(trailMesh);
            this._curveEffectsAnimator = null;
        }

        this._linesMesh.material.blend = this._trailMesh.material.blend
            = seriesModel.get('blendMode') === 'lighter'
            ? __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].additiveBlend : null;
    },

    pauseEffect: function () {
        if (this._curveEffectsAnimator) {
            this._curveEffectsAnimator.pause();
        }
    },

    resumeEffect: function () {
        if (this._curveEffectsAnimator) {
            this._curveEffectsAnimator.resume();
        }
    },

    toggleEffect: function () {
        var animator = this._curveEffectsAnimator;
        if (animator) {
            animator.isPaused() ? animator.resume() : animator.pause();
        }
    },

    _updateLines: function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();
        var coordSys = seriesModel.coordinateSystem;
        var geometry = this._linesMesh.geometry;
        var isPolyline = seriesModel.get('polyline');

        geometry.expandLine = true;

        var size = getCoordSysSize(coordSys);
        geometry.segmentScale = size / 20;

        var lineWidthQueryPath = 'lineStyle.width'.split('.');
        var dpr = api.getDevicePixelRatio();
        var maxLineWidth = 0;
        data.each(function (idx) {
            var itemModel = data.getItemModel(idx);
            var lineWidth = itemModel.get(lineWidthQueryPath);
            if (lineWidth == null) {
                lineWidth = 1;
            }
            data.setItemVisual(idx, 'lineWidth', lineWidth);
            maxLineWidth = Math.max(lineWidth, maxLineWidth);
        });

        // Must set useNativeLine before calling any other methods
        geometry.useNativeLine = false;

        var nVertex = 0;
        var nTriangle = 0;
        data.each(function (idx) {
            var pts = data.getItemLayout(idx);
            if (isPolyline) {
                nVertex += geometry.getPolylineVertexCount(pts);
                nTriangle += geometry.getPolylineTriangleCount(pts);
            }
            else {
                nVertex += geometry.getCubicCurveVertexCount(pts[0], pts[1], pts[2], pts[3]);
                nTriangle += geometry.getCubicCurveTriangleCount(pts[0], pts[1], pts[2], pts[3]);
            }
        });

        geometry.setVertexCount(nVertex);
        geometry.setTriangleCount(nTriangle);
        geometry.resetOffset();

        var colorArr = [];
        data.each(function (idx) {
            var pts = data.getItemLayout(idx);
            var color = data.getItemVisual(idx, 'color');
            var opacity = data.getItemVisual(idx, 'opacity');
            var lineWidth = data.getItemVisual(idx, 'lineWidth') * dpr;
            if (opacity == null) {
                opacity = 1;
            }

            colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color, colorArr);
            colorArr[3] *= opacity;
            if (isPolyline) {
                geometry.addPolyline(pts, colorArr, lineWidth);
            }
            else {
                geometry.addCubicCurve(pts[0], pts[1], pts[2], pts[3], colorArr, lineWidth);
            }
        });

        geometry.dirty();
    },

    remove: function () {
        this.groupGL.removeAll();
    },

    dispose: function () {
        this.groupGL.removeAll();
    }
}));

/***/ }),
/* 246 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_dep_glmatrix__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__shader_trail2_glsl_js__ = __webpack_require__(247);







var vec3 = __WEBPACK_IMPORTED_MODULE_2_claygl_src_dep_glmatrix__["a" /* default */].vec3;

function sign(a) {
    return a > 0 ? 1 : -1;
}

__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_4__shader_trail2_glsl_js__["a" /* default */]);

/* harmony default export */ __webpack_exports__["a"] = (__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.extend(function () {

    var material = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
        shader: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader(
            __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.trail2.vertex'),
            __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.trail2.fragment')
        ),
        transparent: true,
        depthMask: false
    });

    var geometry = new __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__["a" /* default */]({
        dynamic: true
    });
    geometry.createAttribute('dist', 'float', 1);
    geometry.createAttribute('distAll', 'float', 1);
    geometry.createAttribute('start', 'float', 1);

    return {
        geometry: geometry,
        material: material,
        culling: false,
        $ignorePicking: true
    };
}, {

    updateData: function (data, api, lines3DGeometry) {
        var seriesModel = data.hostModel;
        var geometry = this.geometry;

        var effectModel = seriesModel.getModel('effect');
        var size = effectModel.get('trailWidth') * api.getDevicePixelRatio();
        var trailLength = effectModel.get('trailLength');

        var speed = seriesModel.get('effect.constantSpeed');
        var period = seriesModel.get('effect.period') * 1000;
        var useConstantSpeed = speed != null;

        if (true) {
            if (!this.getScene()) {
                console.error('TrailMesh must been add to scene before updateData');
            }
        }

        useConstantSpeed
            ? this.material.set('speed', speed / 1000)
            : this.material.set('period', period);

        this.material[useConstantSpeed ? 'define' : 'undefine']('vertex', 'CONSTANT_SPEED');

        var isPolyline = seriesModel.get('polyline');

        geometry.trailLength = trailLength;
        this.material.set('trailLength', trailLength);

        geometry.resetOffset();

        ['position', 'positionPrev', 'positionNext'].forEach(function (attrName) {
            geometry.attributes[attrName].value = lines3DGeometry.attributes[attrName].value;
        });

        var extraAttrs = ['dist', 'distAll', 'start', 'offset', 'color'];

        extraAttrs.forEach(function (attrName) {
            geometry.attributes[attrName].init(geometry.vertexCount);
        });
        geometry.indices = lines3DGeometry.indices;

        var colorArr = [];
        var effectColor = effectModel.get('trailColor');
        var effectOpacity = effectModel.get('trailOpacity');
        var hasEffectColor = effectColor != null;
        var hasEffectOpacity = effectOpacity != null;

        this.updateWorldTransform();
        var xScale = this.worldTransform.x.len();
        var yScale = this.worldTransform.y.len();
        var zScale = this.worldTransform.z.len();

        var vertexOffset = 0;

        var maxDistance = 0;

        data.each(function (idx) {
            var pts = data.getItemLayout(idx);
            var opacity = hasEffectOpacity ? effectOpacity : data.getItemVisual(idx, 'opacity');
            var color = data.getItemVisual(idx, 'color');

            if (opacity == null) {
                opacity = 1;
            }
            colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(hasEffectColor ? effectColor : color, colorArr);
            colorArr[3] *= opacity;

            var vertexCount = isPolyline
                ? lines3DGeometry.getPolylineVertexCount(pts)
                : lines3DGeometry.getCubicCurveVertexCount(pts[0], pts[1], pts[2], pts[3])

            var dist = 0;
            var pos = [];
            var posPrev = [];
            for (var i = vertexOffset; i < vertexOffset + vertexCount; i++) {
                geometry.attributes.position.get(i, pos);
                pos[0] *= xScale;
                pos[1] *= yScale;
                pos[2] *= zScale;
                if (i > vertexOffset) {
                    dist += vec3.dist(pos, posPrev);
                }
                geometry.attributes.dist.set(i, dist);
                vec3.copy(posPrev, pos);
            }

            maxDistance = Math.max(maxDistance, dist);

            var randomStart = Math.random() * (useConstantSpeed ? dist : period);
            for (var i = vertexOffset; i < vertexOffset + vertexCount; i++) {
                geometry.attributes.distAll.set(i, dist);
                geometry.attributes.start.set(i, randomStart);

                geometry.attributes.offset.set(
                    i, sign(lines3DGeometry.attributes.offset.get(i)) * size / 2
                );
                geometry.attributes.color.set(i, colorArr);
            }

            vertexOffset += vertexCount;
        });

        this.material.set('spotSize', maxDistance * 0.1 * trailLength);
        this.material.set('spotIntensity', effectModel.get('spotIntensity'));

        geometry.dirty();
    },

    setAnimationTime: function (time) {
        this.material.set('time', time);
    }
}));

/***/ }),
/* 247 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.trail2.vertex\nattribute vec3 position: POSITION;\nattribute vec3 positionPrev;\nattribute vec3 positionNext;\nattribute float offset;\nattribute float dist;\nattribute float distAll;\nattribute float start;\n\nattribute vec4 a_Color : COLOR;\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec4 viewport : VIEWPORT;\nuniform float near : NEAR;\n\nuniform float speed : 0;\nuniform float trailLength: 0.3;\nuniform float time;\nuniform float period: 1000;\n\nuniform float spotSize: 1;\n\nvarying vec4 v_Color;\nvarying float v_Percent;\nvarying float v_SpotPercent;\n\n@import ecgl.common.wireframe.vertexHeader\n\n@import ecgl.lines3D.clipNear\n\nvoid main()\n{\n @import ecgl.lines3D.expandLine\n\n gl_Position = currProj;\n\n v_Color = a_Color;\n\n @import ecgl.common.wireframe.vertexMain\n\n#ifdef CONSTANT_SPEED\n float t = mod((speed * time + start) / distAll, 1. + trailLength) - trailLength;\n#else\n float t = mod((time + start) / period, 1. + trailLength) - trailLength;\n#endif\n\n float trailLen = distAll * trailLength;\n\n v_Percent = (dist - t * distAll) / trailLen;\n\n v_SpotPercent = spotSize / distAll;\n\n }\n@end\n\n\n@export ecgl.trail2.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\nuniform float spotIntensity: 5;\n\nvarying vec4 v_Color;\nvarying float v_Percent;\nvarying float v_SpotPercent;\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.util.srgb\n\nvoid main()\n{\n if (v_Percent > 1.0 || v_Percent < 0.0) {\n discard;\n }\n\n float fade = v_Percent;\n\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color * v_Color);\n#else\n gl_FragColor = color * v_Color;\n#endif\n\n @import ecgl.common.wireframe.fragmentMain\n\n if (v_Percent > (1.0 - v_SpotPercent)) {\n gl_FragColor.rgb *= spotIntensity;\n }\n\n gl_FragColor.a *= fade;\n}\n\n@end");


/***/ }),
/* 248 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({

    type: 'series.lines3D',

    dependencies: ['globe'],

    visualColorAccessPath: 'lineStyle.color',

    getInitialData: function (option, ecModel) {
        var lineData = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(['value'], this);
        lineData.hasItemOption = false;
        lineData.initData(option.data, [], function (dataItem, dimName, dataIndex, dimIndex) {
            // dataItem is simply coords
            if (dataItem instanceof Array) {
                return NaN;
            }
            else {
                lineData.hasItemOption = true;
                var value = dataItem.value;
                if (value != null) {
                    return value instanceof Array ? value[dimIndex] : value;
                }
            }
        });

        return lineData;
    },

    defaultOption: {

        coordinateSystem: 'globe',

        globeIndex: 0,

        geo3DIndex: 0,

        zlevel: -10,

        polyline: false,

        effect: {
            show: false,
            period: 4,
            // Trail width
            trailWidth: 4,
            trailLength: 0.2,

            spotIntensity: 6
        },

        silent: true,

        // Support source-over, lighter
        blendMode: 'source-over',

        lineStyle: {
            width: 1,
            opacity: 0.5
            // color
        }
    }
});

/***/ }),
/* 249 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__polygons3D_Polygons3DSeries__ = __webpack_require__(250);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__polygons3D_Polygons3DView__ = __webpack_require__(251);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_opacityVisual__ = __webpack_require__(17);







__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_3__common_opacityVisual__["a" /* default */])('polygons3D'));

/***/ }),
/* 250 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__component_common_componentShadingMixin__ = __webpack_require__(31);



function transformPolygon(coordSys, poly) {
    var ret = [];
    for (var i = 0; i < poly.length; i++) {
        ret.push(coordSys.dataToPoint(poly[i]));
    }
    return ret;
}

var Polygons3DSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({

    type: 'series.polygons3D',

    getRegionModel: function (idx) {
        return this.getData().getItemModel(idx);
    },

    getRegionPolygonCoords: function (idx) {
        var coordSys = this.coordinateSystem;
        var itemModel = this.getData().getItemModel(idx);
        var coords = itemModel.option instanceof Array
            ? itemModel.option : itemModel.getShallow('coords');
        if (!itemModel.get('multiPolygon')) {
            coords = [coords];
        }
        // TODO Validate
        var out = [];
        for (var i = 0; i < coords.length; i++) {
            // TODO Convert here ?
            var interiors = [];
            for (var k = 1; k < coords[i].length; k++) {
                interiors.push(transformPolygon(coordSys, coords[i][k]));
            }
            out.push({
                exterior: transformPolygon(coordSys, coords[i][0]),
                interiors: interiors
            });
        }
        return out;
    },

    getInitialData: function (option) {
        var polygonsData = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(['value'], this);
        polygonsData.hasItemOption = false;
        polygonsData.initData(option.data, [], function (dataItem, dimName, dataIndex, dimIndex) {
            // dataItem is simply coords
            if (dataItem instanceof Array) {
                return NaN;
            }
            else {
                polygonsData.hasItemOption = true;
                var value = dataItem.value;
                if (value != null) {
                    return value instanceof Array ? value[dimIndex] : value;
                }
            }
        });

        return polygonsData;
    },

    defaultOption: {

        show: true,

        data: null,

        multiPolygon: false,

        progressiveThreshold: 1e3,
        progressive: 1e3,

        zlevel: -10,

        label: {
            show: false,
            // Distance in 3d space.
            distance: 2,

            textStyle: {
                fontSize: 20,
                color: '#000',
                backgroundColor: 'rgba(255,255,255,0.7)',
                padding: 3,
                borderRadius: 4
            }
        },

        itemStyle: {
            color: '#fff',
            borderWidth: 0,
            borderColor: '#333'
        },

        emphasis: {
            itemStyle: {
                color: '#639fc0'
            },
            label: {
                show: true
            }
        }
    }
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Polygons3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_1__component_common_componentShadingMixin__["a" /* default */]);

/* unused harmony default export */ var _unused_webpack_default_export = (Polygons3DSeries);

/***/ }),
/* 251 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__component_common_Geo3DBuilder__ = __webpack_require__(64);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__ = __webpack_require__(1);




__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({

    type: 'polygons3D',

    __ecgl__: true,

    init: function (ecModel, api) {
        this.groupGL = new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Node();

        this._geo3DBuilderList = [];

        this._currentStep = 0;
    },

    render: function (seriesModel, ecModel, api) {
        this.groupGL.removeAll();

        var coordSys = seriesModel.coordinateSystem;
        if (coordSys && coordSys.viewGL) {
            coordSys.viewGL.add(this.groupGL);
        }

        var geo3DBuilder = this._geo3DBuilderList[0];
        if (!geo3DBuilder) {
            geo3DBuilder = new __WEBPACK_IMPORTED_MODULE_1__component_common_Geo3DBuilder__["a" /* default */](api);
            geo3DBuilder.extrudeY = coordSys.type !== 'mapbox3D'
                && coordSys.type !== 'maptalks3D';
            this._geo3DBuilderList[0] = geo3DBuilder;
        }
        this._updateShaderDefines(coordSys, geo3DBuilder);

        geo3DBuilder.update(seriesModel, ecModel, api);
        this._geo3DBuilderList.length = 1;

        this.groupGL.add(geo3DBuilder.rootNode);
    },

    incrementalPrepareRender: function (seriesModel, ecModel, api) {
        this.groupGL.removeAll();

        var coordSys = seriesModel.coordinateSystem;
        if (coordSys && coordSys.viewGL) {
            coordSys.viewGL.add(this.groupGL);
        }

        this._currentStep = 0;
    },

    incrementalRender: function (params, seriesModel, ecModel, api) {
        var geo3DBuilder = this._geo3DBuilderList[this._currentStep];
        var coordSys = seriesModel.coordinateSystem;
        if (!geo3DBuilder) {
            geo3DBuilder = new __WEBPACK_IMPORTED_MODULE_1__component_common_Geo3DBuilder__["a" /* default */](api);
            geo3DBuilder.extrudeY = coordSys.type !== 'mapbox3D'
                && coordSys.type !== 'maptalks3D';
            this._geo3DBuilderList[this._currentStep] = geo3DBuilder;
        }
        geo3DBuilder.update(seriesModel, ecModel, api, params.start, params.end);
        this.groupGL.add(geo3DBuilder.rootNode);

        this._updateShaderDefines(coordSys, geo3DBuilder);

        this._currentStep++;
    },

    _updateShaderDefines: function (coordSys, geo3DBuilder) {
        var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
        geo3DBuilder.rootNode.traverse(function (mesh) {
            if (mesh.material) {
                mesh.material[methodName]('fragment', 'SRGB_DECODE');

                // FIXME
                if (coordSys.type === 'mapbox3D' || coordSys.type === 'maptalks3D') {
                    mesh.material.define('fragment', 'NORMAL_UP_AXIS', 2);
                    mesh.material.define('fragment', 'NORMAL_FRONT_AXIS', 1);
                }
            }
        });
    },

    remove: function () {
        this.groupGL.removeAll();
    },

    dispose: function () {
        this.groupGL.removeAll();
    }
});

/***/ }),
/* 252 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__surface_SurfaceSeries__ = __webpack_require__(253);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__surface_SurfaceView__ = __webpack_require__(254);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__surface_surfaceLayout__ = __webpack_require__(255);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(17);








__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('surface'));


/***/ }),
/* 253 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__component_common_componentShadingMixin__ = __webpack_require__(31);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_formatTooltip__ = __webpack_require__(39);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_createList__ = __webpack_require__(50);





var SurfaceSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({

    type: 'series.surface',

    dependencies: ['globe', 'grid3D', 'geo3D'],

    visualColorAccessPath: 'itemStyle.color',

    formatTooltip: function (dataIndex) {
        return Object(__WEBPACK_IMPORTED_MODULE_2__common_formatTooltip__["a" /* default */])(this, dataIndex);
    },

    getInitialData: function (option, ecModel) {
        var data = option.data;

        function validateDimension(dimOpts) {
            return !(isNaN(dimOpts.min) || isNaN(dimOpts.max) || isNaN(dimOpts.step));
        }

        function getPrecision(dimOpts) {
            var getPrecision = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.getPrecisionSafe;
            return Math.max(
                getPrecision(dimOpts.min), getPrecision(dimOpts.max), getPrecision(dimOpts.step)
            ) + 1;
        }

        if (!data) {
            if (!option.parametric) {
                // From surface equation
                var equation = option.equation || {};
                var xOpts = equation.x || {};
                var yOpts = equation.y || {};

                ['x', 'y'].forEach(function (dim) {
                    if (!validateDimension(equation[dim])) {
                        if (true) {
                            console.error('Invalid equation.%s', dim);
                        }
                        return;
                    }
                });
                if (typeof equation.z !== 'function') {
                    if (true) {
                        console.error('equation.z needs to be function');
                    }
                    return;
                }
                var xCount = Math.floor((xOpts.max + xOpts.step - xOpts.min) / xOpts.step);
                var yCount = Math.floor((yOpts.max + yOpts.step - yOpts.min) / yOpts.step);
                data = new Float32Array(xCount * yCount * 3);

                var xPrecision = getPrecision(xOpts);
                var yPrecision = getPrecision(yOpts);

                var off = 0;
                for (var j = 0; j < yCount; j++) {
                    for (var i = 0; i < xCount; i++) {
                        var x = i * xOpts.step + xOpts.min;
                        var y = j * yOpts.step + yOpts.min;
                        var x2 = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.round(Math.min(x, xOpts.max), xPrecision);
                        var y2 = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.round(Math.min(y, yOpts.max), yPrecision);
                        var z = equation.z(x2, y2);
                        data[off++] = x2;
                        data[off++] = y2;
                        data[off++] = z;
                    }
                }
            }
            else {
                var parametricEquation = option.parametricEquation || {};
                var uOpts = parametricEquation.u || {};
                var vOpts = parametricEquation.v || {};

                ['u', 'v'].forEach(function (dim) {
                    if (!validateDimension(parametricEquation[dim])) {
                        if (true) {
                            console.error('Invalid parametricEquation.%s', dim);
                        }
                        return;
                    }
                });
                ['x', 'y', 'z'].forEach(function (dim) {
                    if (typeof parametricEquation[dim] !== 'function') {
                        if (true) {
                            console.error('parametricEquation.%s needs to be function', dim);
                        }
                        return;
                    }
                });

                var uCount = Math.floor((uOpts.max + uOpts.step - uOpts.min) / uOpts.step);
                var vCount = Math.floor((vOpts.max + vOpts.step - vOpts.min) / vOpts.step);
                data = new Float32Array(uCount * vCount * 5);


                var uPrecision = getPrecision(uOpts);
                var vPrecision = getPrecision(vOpts);
                var off = 0;
                for (var j = 0; j < vCount; j++) {
                    for (var i = 0; i < uCount; i++) {
                        var u = i * uOpts.step + uOpts.min;
                        var v = j * vOpts.step + vOpts.min;
                        var u2 = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.round(Math.min(u, uOpts.max), uPrecision);
                        var v2 = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.round(Math.min(v, vOpts.max), vPrecision);
                        var x = parametricEquation.x(u2, v2);
                        var y = parametricEquation.y(u2, v2);
                        var z = parametricEquation.z(u2, v2);
                        data[off++] = x;
                        data[off++] = y;
                        data[off++] = z;
                        data[off++] = u2;
                        data[off++] = v2;
                    }
                }
            }
        }

        var dims = ['x', 'y', 'z'];
        if (option.parametric) {
            dims.push('u', 'v');
        }
        // PENDING getSource?
        var list = Object(__WEBPACK_IMPORTED_MODULE_3__common_createList__["a" /* default */])(this, dims, data);
        return list;
    },

    defaultOption: {
        coordinateSystem: 'cartesian3D',
        zlevel: -10,

        // Cartesian coordinate system
        grid3DIndex: 0,

        // Surface needs lambert shading to show the difference
        shading: 'lambert',

        // If parametric surface
        parametric: false,

        wireframe: {
            show: true,

            lineStyle: {
                color: 'rgba(0,0,0,0.5)',
                width: 1
            }
        },
        /**
         * Generate surface data from z = f(x, y) equation
         */
        equation: {
            // [min, max, step]
            x: {
                min: -1,
                max: 1,
                step: 0.1
            },
            y: {
                min: -1,
                max: 1,
                step: 0.1
            },
            z: null
        },

        parametricEquation: {
            // [min, max, step]
            u: {
                min: -1,
                max: 1,
                step: 0.1
            },
            v: {
                min: -1,
                max: 1,
                step: 0.1
            },
            // [x, y, z] = f(x, y)
            x: null,
            y: null,
            z: null
        },

        itemStyle: {
            // Color
        },

        animationDurationUpdate: 500
    }
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(SurfaceSeries.prototype, __WEBPACK_IMPORTED_MODULE_1__component_common_componentShadingMixin__["a" /* default */]);

/* unused harmony default export */ var _unused_webpack_default_export = (SurfaceSeries);

/***/ }),
/* 254 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_geometry_trianglesSortMixin__ = __webpack_require__(65);






var vec3 = __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__["a" /* default */].vec3;

function isPointsNaN(pt) {
    return isNaN(pt[0]) || isNaN(pt[1]) || isNaN(pt[2]);
}

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({

    type: 'surface',

    __ecgl__: true,

    init: function (ecModel, api) {

        this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
    },

    render: function (seriesModel, ecModel, api) {
        // Swap surfaceMesh
        var tmp = this._prevSurfaceMesh;
        this._prevSurfaceMesh = this._surfaceMesh;
        this._surfaceMesh = tmp;

        if (!this._surfaceMesh) {
            this._surfaceMesh = this._createSurfaceMesh();
        }

        this.groupGL.remove(this._prevSurfaceMesh);
        this.groupGL.add(this._surfaceMesh);

        var coordSys = seriesModel.coordinateSystem;
        var shading = seriesModel.get('shading');
        var data = seriesModel.getData();

        var shadingPrefix = 'ecgl.' + shading;
        if (!this._surfaceMesh.material || this._surfaceMesh.material.shader.name !== shadingPrefix) {
            this._surfaceMesh.material = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createMaterial(shadingPrefix, ['VERTEX_COLOR', 'DOUBLE_SIDED']);
        }

        __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].setMaterialFromModel(
            shading, this._surfaceMesh.material, seriesModel, api
        );

        if (coordSys && coordSys.viewGL) {
            coordSys.viewGL.add(this.groupGL);
            var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
            this._surfaceMesh.material[methodName]('fragment', 'SRGB_DECODE');
        }

        var isParametric = seriesModel.get('parametric');

        var dataShape = this._getDataShape(data, isParametric);

        var wireframeModel = seriesModel.getModel('wireframe');
        var wireframeLineWidth = wireframeModel.get('lineStyle.width');
        var showWireframe = wireframeModel.get('show') && wireframeLineWidth > 0;
        this._updateSurfaceMesh(this._surfaceMesh, seriesModel, dataShape, showWireframe);

        var material = this._surfaceMesh.material;
        if (showWireframe) {
            material.define('WIREFRAME_QUAD');
            material.set('wireframeLineWidth', wireframeLineWidth);
            material.set('wireframeLineColor', __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(wireframeModel.get('lineStyle.color')));
        }
        else {
            material.undefine('WIREFRAME_QUAD');
        }

        this._initHandler(seriesModel, api);

        this._updateAnimation(seriesModel);
    },

    _updateAnimation: function (seriesModel) {
        __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].updateVertexAnimation(
            [['prevPosition', 'position'],
            ['prevNormal', 'normal']],
            this._prevSurfaceMesh,
            this._surfaceMesh,
            seriesModel
        );
    },

    _createSurfaceMesh: function () {
        var mesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
            geometry: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry({
                dynamic: true,
                sortTriangles: true
            }),
            shadowDepthMaterial: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
                shader: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader(__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.sm.depth.vertex'), __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.sm.depth.fragment'))
            }),
            culling: false,
            // Render after axes
            renderOrder: 10,
            // Render normal in normal pass
            renderNormal: true
        });
        mesh.geometry.createAttribute('barycentric', 'float', 4);
        mesh.geometry.createAttribute('prevPosition', 'float', 3);
        mesh.geometry.createAttribute('prevNormal', 'float', 3);

        __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.extend(mesh.geometry, __WEBPACK_IMPORTED_MODULE_4__util_geometry_trianglesSortMixin__["a" /* default */]);

        return mesh;
    },

    _initHandler: function (seriesModel, api) {
        var data = seriesModel.getData();
        var surfaceMesh = this._surfaceMesh;

        var coordSys = seriesModel.coordinateSystem;

        function getNearestPointIdx(triangle, point) {
            var nearestDist = Infinity;
            var nearestIdx = -1;
            var pos = [];
            for (var i = 0; i < triangle.length; i++) {
                surfaceMesh.geometry.attributes.position.get(triangle[i], pos);
                var dist = vec3.dist(point.array, pos);
                if (dist < nearestDist) {
                    nearestDist = dist;
                    nearestIdx = triangle[i];
                }
            }
            return nearestIdx;
        }

        surfaceMesh.seriesIndex = seriesModel.seriesIndex;

        var lastDataIndex = -1;

        surfaceMesh.off('mousemove');
        surfaceMesh.off('mouseout');
        surfaceMesh.on('mousemove', function (e) {
            var idx = getNearestPointIdx(e.triangle, e.point);
            if (idx >= 0) {
                var point = [];
                surfaceMesh.geometry.attributes.position.get(idx, point);
                var value = coordSys.pointToData(point);

                var minDist = Infinity;
                var dataIndex = -1;
                var item = [];
                for (var i = 0; i < data.count(); i++) {
                    item[0] = data.get('x', i);
                    item[1] = data.get('y', i);
                    item[2] = data.get('z', i);
                    var dist = vec3.squaredDistance(item, value);
                    if (dist < minDist) {
                        dataIndex = i;
                        minDist = dist;
                    }
                }

                if (dataIndex !== lastDataIndex) {
                    api.dispatchAction({
                        type: 'grid3DShowAxisPointer',
                        value: value
                    });
                }

                lastDataIndex = dataIndex;
                surfaceMesh.dataIndex = dataIndex;
            }
            else {
                surfaceMesh.dataIndex = -1;
            }
        }, this);
        surfaceMesh.on('mouseout', function (e) {
            lastDataIndex = -1;
            surfaceMesh.dataIndex = -1;

            api.dispatchAction({
                type: 'grid3DHideAxisPointer'
            });
        }, this);
    },

    _updateSurfaceMesh: function (surfaceMesh, seriesModel, dataShape, showWireframe) {

        var geometry = surfaceMesh.geometry;
        var data = seriesModel.getData();
        var pointsArr = data.getLayout('points');

        var invalidDataCount = 0;
        data.each(function (idx) {
            if (!data.hasValue(idx)) {
                invalidDataCount++;
            }
        });
        var needsSplitQuad = invalidDataCount || showWireframe;

        var positionAttr = geometry.attributes.position;
        var normalAttr = geometry.attributes.normal;
        var texcoordAttr = geometry.attributes.texcoord0;
        var barycentricAttr = geometry.attributes.barycentric;
        var colorAttr = geometry.attributes.color;
        var row = dataShape.row;
        var column = dataShape.column;
        var shading = seriesModel.get('shading');
        var needsNormal = shading !== 'color';

        if (needsSplitQuad) {
            // TODO, If needs remove the invalid points, or set color transparent.
            var vertexCount = (row - 1) * (column - 1) * 4;
            positionAttr.init(vertexCount);
            if (showWireframe) {
                barycentricAttr.init(vertexCount);
            }
        }
        else {
            positionAttr.value = new Float32Array(pointsArr);
        }
        colorAttr.init(geometry.vertexCount);
        texcoordAttr.init(geometry.vertexCount);

        var quadToTriangle = [0, 3, 1, 1, 3, 2];
        // 3----2
        // 0----1
        // Make sure pixels on 1---3 edge will not have channel 0.
        // And pixels on four edges have at least one channel 0.
        var quadBarycentric = [
            [1, 1, 0, 0],
            [0, 1, 0, 1],
            [1, 0, 0, 1],
            [1, 0, 1, 0]
        ];

        var indices = geometry.indices = new (geometry.vertexCount > 0xffff ? Uint32Array : Uint16Array)((row - 1) * (column - 1) * 6);
        var getQuadIndices = function (i, j, out) {
            out[1] = i * column + j;
            out[0] = i * column + j + 1;
            out[3] = (i + 1) * column + j + 1;
            out[2] = (i + 1) * column + j;
        };

        var isTransparent = false;

        if (needsSplitQuad) {
            var quadIndices = [];
            var pos = [];
            var faceOffset = 0;

            if (needsNormal) {
                normalAttr.init(geometry.vertexCount);
            }
            else {
                normalAttr.value = null;
            }

            var pts = [[], [], []];
            var v21 = [], v32 = [];
            var normal = vec3.create();

            var getFromArray = function (arr, idx, out) {
                var idx3 = idx * 3;
                out[0] = arr[idx3];
                out[1] = arr[idx3 + 1];
                out[2] = arr[idx3 + 2];
                return out;
            };
            var vertexNormals = new Float32Array(pointsArr.length);
            var vertexColors = new Float32Array(pointsArr.length / 3 * 4);

            for (var i = 0; i < data.count(); i++) {
                if (data.hasValue(i)) {
                    var rgbaArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(data.getItemVisual(i, 'color'));
                    var opacity = data.getItemVisual(i, 'opacity');
                    rgbaArr[3] *= opacity;
                    if (rgbaArr[3] < 0.99) {
                        isTransparent = true;
                    }
                    for (var k = 0; k < 4; k++) {
                        vertexColors[i * 4 + k] = rgbaArr[k];
                    }
                }
            }
            var farPoints = [1e7, 1e7, 1e7];
            for (var i = 0; i < row - 1; i++) {
                for (var j = 0; j < column - 1; j++) {
                    var dataIndex = i * (column - 1) + j;
                    var vertexOffset = dataIndex * 4;

                    getQuadIndices(i, j, quadIndices);

                    var invisibleQuad = false;
                    for (var k = 0; k < 4; k++) {
                        getFromArray(pointsArr, quadIndices[k], pos);
                        if (isPointsNaN(pos)) {
                            // Quad is invisible if any point is NaN
                            invisibleQuad = true;
                        }
                    }

                    for (var k = 0; k < 4; k++) {
                        if (invisibleQuad) {
                            // Move point far away
                            positionAttr.set(vertexOffset + k, farPoints);
                        }
                        else {
                            getFromArray(pointsArr, quadIndices[k], pos);
                            positionAttr.set(vertexOffset + k, pos);
                        }
                        if (showWireframe) {
                            barycentricAttr.set(vertexOffset + k, quadBarycentric[k]);
                        }
                    }
                    for (var k = 0; k < 6; k++) {
                        indices[faceOffset++] = quadToTriangle[k] + vertexOffset;
                    }
                    // Vertex normals
                    if (needsNormal && !invisibleQuad) {
                        for (var k = 0; k < 2; k++) {
                            var k3 = k * 3;

                            for (var m = 0; m < 3; m++) {
                                var idx = quadIndices[quadToTriangle[k3] + m];
                                getFromArray(pointsArr, idx, pts[m]);
                            }

                            vec3.sub(v21, pts[0], pts[1]);
                            vec3.sub(v32, pts[1], pts[2]);
                            vec3.cross(normal, v21, v32);
                            // Weighted by the triangle area
                            for (var m = 0; m < 3; m++) {
                                var idx3 = quadIndices[quadToTriangle[k3] + m] * 3;
                                vertexNormals[idx3] = vertexNormals[idx3] + normal[0];
                                vertexNormals[idx3 + 1] = vertexNormals[idx3 + 1] + normal[1];
                                vertexNormals[idx3 + 2] = vertexNormals[idx3 + 2] + normal[2];
                            }
                        }
                    }

                }
            }
            if (needsNormal) {
                for (var i = 0; i < vertexNormals.length / 3; i++) {
                    getFromArray(vertexNormals, i, normal);
                    vec3.normalize(normal, normal);
                    vertexNormals[i * 3] = normal[0];
                    vertexNormals[i * 3 + 1] = normal[1];
                    vertexNormals[i * 3 + 2] = normal[2];
                }
            }
            // Split normal and colors, write to the attributes.
            var rgbaArr = [];
            var uvArr = [];
            for (var i = 0; i < row - 1; i++) {
                for (var j = 0; j < column - 1; j++) {
                    var dataIndex = i * (column - 1) + j;
                    var vertexOffset = dataIndex * 4;

                    getQuadIndices(i, j, quadIndices);
                    for (var k = 0; k < 4; k++) {
                        for (var m = 0; m < 4; m++) {
                            rgbaArr[m] = vertexColors[quadIndices[k] * 4 + m];
                        }
                        colorAttr.set(vertexOffset + k, rgbaArr);

                        if (needsNormal) {
                            getFromArray(vertexNormals, quadIndices[k], normal);
                            normalAttr.set(vertexOffset + k, normal);
                        }

                        var idx = quadIndices[k];
                        uvArr[0] = (idx % column) / (column - 1);
                        uvArr[1] = Math.floor(idx / column) / (row - 1);
                        texcoordAttr.set(vertexOffset + k, uvArr);
                    }
                    dataIndex++;
                }
            }
        }
        else {
            var uvArr = [];
            for (var i = 0; i < data.count(); i++) {
                uvArr[0] = (i % column) / (column - 1);
                uvArr[1] = Math.floor(i / column) / (row - 1);
                var rgbaArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(data.getItemVisual(i, 'color'));
                var opacity = data.getItemVisual(i, 'opacity');
                rgbaArr[3] *= opacity;
                if (rgbaArr[3] < 0.99) {
                    isTransparent = true;
                }
                colorAttr.set(i, rgbaArr);
                texcoordAttr.set(i, uvArr);
            }
            var quadIndices = [];
            // Triangles
            var cursor = 0;
            for (var i = 0; i < row - 1; i++) {
                for (var j = 0; j < column - 1; j++) {

                    getQuadIndices(i, j, quadIndices);

                    for (var k = 0; k < 6; k++) {
                        indices[cursor++] = quadIndices[quadToTriangle[k]];
                    }
                }
            }
            if (needsNormal) {
                geometry.generateVertexNormals();
            }
            else {
                normalAttr.value = null;
            }
        }
        if (surfaceMesh.material.get('normalMap')) {
            geometry.generateTangents();
        }


        geometry.updateBoundingBox();
        geometry.dirty();

        surfaceMesh.material.transparent = isTransparent;
        surfaceMesh.material.depthMask = !isTransparent;
    },

    _getDataShape: function (data, isParametric) {

        var prevX = -Infinity;
        var rowCount = 0;
        var columnCount = 0;
        var prevColumnCount = 0;

        var rowDim = isParametric ? 'u' : 'x';

        // Check data format
        for (var i = 0; i < data.count(); i++) {
            var x = data.get(rowDim, i);
            if (x < prevX) {
                if (prevColumnCount && prevColumnCount !== columnCount) {
                    if (true) {
                        throw new Error('Invalid data. data should be a row major 2d array.')
                    }
                }
                // A new row.
                prevColumnCount = columnCount;
                columnCount = 0;
                rowCount++;
            }
            prevX = x;
            columnCount++;
        }

        return {
            row: rowCount + 1,
            column: columnCount
        };
    },

    dispose: function () {
        this.groupGL.removeAll();
    },

    remove: function () {
        this.groupGL.removeAll();
    }
});

/***/ }),
/* 255 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerLayout(function (ecModel, api) {
    ecModel.eachSeriesByType('surface', function (surfaceModel) {
        var cartesian = surfaceModel.coordinateSystem;
        if (!cartesian || cartesian.type !== 'cartesian3D') {
            if (true) {
                console.error('Surface chart only support cartesian3D coordinateSystem');
            }
        }
        var data = surfaceModel.getData();
        var points = new Float32Array(3 * data.count());
        var nanPoint = [NaN, NaN, NaN];

        if (cartesian && cartesian.type === 'cartesian3D') {
            var coordDims = cartesian.dimensions;
            var dims = coordDims.map(function (coordDim) {
                return surfaceModel.coordDimToDataDim(coordDim)[0];
            });
            data.each(dims, function (x, y, z, idx) {
                var pt;
                if (!data.hasValue(idx)) {
                    pt = nanPoint;
                }
                else {
                    pt = cartesian.dataToPoint([x, y, z]);
                }
                points[idx * 3] = pt[0];
                points[idx * 3 + 1] = pt[1];
                points[idx * 3 + 2] = pt[2];
            });
        }
        data.setLayout('points', points);
    });
});

/***/ }),
/* 256 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__coord_geo3D_Geo3D__ = __webpack_require__(99);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__map3D_Map3DSeries__ = __webpack_require__(257);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__map3D_Map3DView__ = __webpack_require__(258);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(17);








__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('map3D'));

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'map3DChangeCamera',
    event: 'map3dcamerachanged',
    update: 'series:updateCamera'
}, function (payload, ecModel) {
    ecModel.eachComponent({
        mainType: 'series', subType: 'map3D', query: payload
    }, function (componentModel) {
        componentModel.setView(payload);
    });
});

/***/ }),
/* 257 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__component_common_componentViewControlMixin__ = __webpack_require__(44);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__component_common_componentPostEffectMixin__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__component_common_componentLightMixin__ = __webpack_require__(29);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__component_common_componentShadingMixin__ = __webpack_require__(31);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__coord_geo3D_geo3DModelMixin__ = __webpack_require__(96);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__util_format__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__common_formatTooltip__ = __webpack_require__(39);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__coord_geo3DCreator__ = __webpack_require__(98);










function transformPolygon(mapbox3DCoordSys, poly) {
    var newPoly = [];
    for (var k = 0; k < poly.length; k++) {
        newPoly.push(mapbox3DCoordSys.dataToPoint(poly[k]));
    }
    return newPoly;
}

var Map3DSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({

    type: 'series.map3D',

    layoutMode: 'box',

    coordinateSystem: null,

    visualColorAccessPath: 'itemStyle.color',

    optionUpdated: function (newOpt) {
        newOpt = newOpt || {};
        var coordSysType = this.get('coordinateSystem');
        if (coordSysType == null || coordSysType === 'geo3D') {
            return;
        }

        if (true) {
            var propsNeedToCheck = [
                'left', 'top', 'width', 'height',
                'boxWidth', 'boxDepth', 'boxHeight',
                'light', 'viewControl', 'postEffect', 'temporalSuperSampling',
                'environment', 'groundPlane'
            ];
            var ignoredProperties = [];
            propsNeedToCheck.forEach(function (propName) {
                if (newOpt[propName] != null) {
                    ignoredProperties.push(propName);
                }
            });
            if (ignoredProperties.length) {
                console.warn(
                    'Property %s in map3D series will be ignored if coordinate system is %s',
                    ignoredProperties.join(', '), coordSysType
                );
            }
        }

        if (this.get('groundPlane.show')) {
            // Force disable groundPlane if map3D has other coordinate systems.
            this.option.groundPlane.show = false;
        }

        // Reset geo.
        this._geo = null;
    },

    getInitialData: function (option) {
        option.data = this.getFilledRegions(option.data, option.map);

        var dimensions = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.completeDimensions(['value'], option.data);
        var list = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(dimensions, this);
        list.initData(option.data);

        var regionModelMap = {};
        list.each(function (idx) {
            var name = list.getName(idx);
            var itemModel = list.getItemModel(idx);
            regionModelMap[name] = itemModel;
        });

        this._regionModelMap = regionModelMap;

        return list;
    },

    formatTooltip: function (dataIndex) {
        return Object(__WEBPACK_IMPORTED_MODULE_7__common_formatTooltip__["a" /* default */])(this, dataIndex);
    },

    getRegionModel: function (idx) {
        var name = this.getData().getName(idx);
        return this._regionModelMap[name] || new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Model(null, this);
    },

    getRegionPolygonCoords: function (idx) {
        var coordSys = this.coordinateSystem;
        var name = this.getData().getName(idx);
        if (coordSys.transform) {
            var region = coordSys.getRegion(name);
            return region ? region.geometries : [];
        }
        else {
            if (!this._geo) {
                this._geo = __WEBPACK_IMPORTED_MODULE_8__coord_geo3DCreator__["a" /* default */].createGeo3D(this);
            }
            var region = this._geo.getRegion(name);
            var ret = [];
            for (var k = 0; k < region.geometries.length; k++) {
                var geo = region.geometries[k];
                var interiors = [];
                var exterior = transformPolygon(coordSys, geo.exterior);
                if (interiors && interiors.length) {
                    for (var m = 0; m < geo.interiors.length; m++) {
                        interiors.push(transformPolygon(coordSys, interiors[m]));
                    }
                }
                ret.push({
                    interiors: interiors,
                    exterior: exterior
                });
            }
            return ret;
        }
    },

    /**
     * Format label
     * @param {string} name Region name
     * @param {string} [status='normal'] 'normal' or 'emphasis'
     * @return {string}
     */
    getFormattedLabel: function (dataIndex, status) {
        var text = __WEBPACK_IMPORTED_MODULE_6__util_format__["a" /* default */].getFormattedLabel(this, dataIndex, status);
        if (text == null) {
            text = this.getData().getName(dataIndex);
        }
        return text;
    },

    defaultOption: {
        // Support geo3D, mapbox, maptalks3D
        coordinateSystem: 'geo3D',
        // itemStyle: {},
        // height,
        // label: {}
        data: null
    }
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Map3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_5__coord_geo3D_geo3DModelMixin__["a" /* default */]);

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Map3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_1__component_common_componentViewControlMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Map3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_2__component_common_componentPostEffectMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Map3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_3__component_common_componentLightMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Map3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_4__component_common_componentShadingMixin__["a" /* default */]);

/* unused harmony default export */ var _unused_webpack_default_export = (Map3DSeries);

/***/ }),
/* 258 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_OrbitControl__ = __webpack_require__(45);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__component_common_SceneHelper__ = __webpack_require__(30);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__component_common_Geo3DBuilder__ = __webpack_require__(64);







/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({

    type: 'map3D',

    __ecgl__: true,

    init: function (ecModel, api) {
        this._geo3DBuilder = new __WEBPACK_IMPORTED_MODULE_4__component_common_Geo3DBuilder__["a" /* default */](api);
        this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
    },

    render: function (map3DModel, ecModel, api) {

        var coordSys = map3DModel.coordinateSystem;

        if (!coordSys || !coordSys.viewGL) {
            return;
        }

        this.groupGL.add(this._geo3DBuilder.rootNode);
        coordSys.viewGL.add(this.groupGL);

        var geo3D;
        if (coordSys.type === 'geo3D') {
            geo3D = coordSys;

            if (!this._sceneHelper) {
                this._sceneHelper = new __WEBPACK_IMPORTED_MODULE_3__component_common_SceneHelper__["a" /* default */]();
                this._sceneHelper.initLight(this.groupGL);
            }

            this._sceneHelper.setScene(coordSys.viewGL.scene);
            this._sceneHelper.updateLight(map3DModel);

            // Set post effect
            coordSys.viewGL.setPostEffect(map3DModel.getModel('postEffect'), api);
            coordSys.viewGL.setTemporalSuperSampling(map3DModel.getModel('temporalSuperSampling'));

            var control = this._control;
            if (!control) {
                control = this._control = new __WEBPACK_IMPORTED_MODULE_2__util_OrbitControl__["a" /* default */]({
                    zr: api.getZr()
                });
                this._control.init();
            }
            var viewControlModel = map3DModel.getModel('viewControl');
            control.setViewGL(coordSys.viewGL);
            control.setFromViewControlModel(viewControlModel, 0);

            control.off('update');
            control.on('update', function () {
                api.dispatchAction({
                    type: 'map3DChangeCamera',
                    alpha: control.getAlpha(),
                    beta: control.getBeta(),
                    distance: control.getDistance(),
                    from: this.uid,
                    map3DId: map3DModel.id
                });
            });

            this._geo3DBuilder.extrudeY = true;
        }
        else {
            if (this._control) {
                this._control.dispose();
                this._control = null;
            }
            if (this._sceneHelper) {
                this._sceneHelper.dispose();
                this._sceneHelper = null;
            }
            geo3D = map3DModel.getData().getLayout('geo3D');

            this._geo3DBuilder.extrudeY = false;
        }

        this._geo3DBuilder.update(map3DModel, ecModel, api, 0, map3DModel.getData().count());


        // Must update after geo3D.viewGL.setPostEffect to determine linear space
        var srgbDefineMethod = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
        this._geo3DBuilder.rootNode.traverse(function (mesh) {
            if (mesh.material) {
                mesh.material[srgbDefineMethod]('fragment', 'SRGB_DECODE');
            }
        });
    },

    afterRender: function (map3DModel, ecModel, api, layerGL) {
        var renderer = layerGL.renderer;
        var coordSys = map3DModel.coordinateSystem;
        if (coordSys && coordSys.type === 'geo3D') {
            this._sceneHelper.updateAmbientCubemap(renderer, map3DModel, api);
            this._sceneHelper.updateSkybox(renderer, map3DModel, api);
        }
    },

    dispose: function () {
        this.groupGL.removeAll();
        this._control.dispose();
    }
}));

/***/ }),
/* 259 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__scatterGL_ScatterGLSeries__ = __webpack_require__(260);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__scatterGL_ScatterGLView__ = __webpack_require__(261);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__ = __webpack_require__(51);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(17);








__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default()('scatterGL', 'circle', null));

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('scatterGL'));

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerLayout({
    seriesType: 'scatterGL',
    reset: function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;

        var progress;
        if (coordSys) {
            var dims = coordSys.dimensions;
            var pt = [];
            if (dims.length === 1) {
                progress = function (params, data) {
                    var points = new Float32Array((params.end - params.start) * 2);
                    for (var idx = params.start; idx < params.end; idx++) {
                        var offset = (idx - params.start) * 2;
                        var x = data.get(dims[0], idx);
                        var pt = coordSys.dataToPoint(x);
                        points[offset] = pt[0];
                        points[offset + 1] = pt[1];
                    }
                    data.setLayout('points', points);
                };
            }
            else if (dims.length === 2) {
                progress = function (params, data) {
                    var points = new Float32Array((params.end - params.start) * 2);
                    for (var idx = params.start; idx < params.end; idx++) {
                        var offset = (idx - params.start) * 2;
                        var x = data.get(dims[0], idx);
                        var y = data.get(dims[1], idx);
                        pt[0] = x;
                        pt[1] = y;

                        pt = coordSys.dataToPoint(pt);
                        points[offset] = pt[0];
                        points[offset + 1] = pt[1];
                    }
                    data.setLayout('points', points);
                };
            }
        }

        return { progress: progress };
    }
});

/***/ }),
/* 260 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({

    type: 'series.scatterGL',

    dependencies: ['grid', 'polar', 'geo', 'singleAxis'],

    visualColorAccessPath: 'itemStyle.color',

    getInitialData: function () {
        return __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.createList(this);
    },

    defaultOption: {
        coordinateSystem: 'cartesian2d',
        zlevel: 10,

        progressive: 1e5,
        progressiveThreshold: 1e5,

        // Cartesian coordinate system
        // xAxisIndex: 0,
        // yAxisIndex: 0,

        // Polar coordinate system
        // polarIndex: 0,

        // Geo coordinate system
        // geoIndex: 0,

        large: false,

        symbol: 'circle',
        symbolSize: 10,

        // symbolSize scale when zooming.
        zoomScale: 0,

        // Support source-over, lighter
        blendMode: 'source-over',

        itemStyle: {
            opacity: 0.8
        },


        postEffect: {
            enable: false,
            colorCorrection: {
                exposure: 0,
                brightness: 0,
                contrast: 1,
                saturation: 1,
                enable: true
            }
        }

    }
});

/***/ }),
/* 261 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_ViewGL__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_PointsBuilder__ = __webpack_require__(67);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_GLViewHelper__ = __webpack_require__(103);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_retrieve__ = __webpack_require__(2);








__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({

    type: 'scatterGL',

    __ecgl__: true,

    init: function (ecModel, api) {

        this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
        this.viewGL = new __WEBPACK_IMPORTED_MODULE_2__core_ViewGL__["a" /* default */]('orthographic');

        this.viewGL.add(this.groupGL);

        this._pointsBuilderList = [];
        this._currentStep = 0;

        this._sizeScale = 1;

        this._glViewHelper = new __WEBPACK_IMPORTED_MODULE_4__common_GLViewHelper__["a" /* default */](this.viewGL);
    },

    render: function (seriesModel, ecModel, api) {
        this.groupGL.removeAll();
        this._glViewHelper.reset(seriesModel, api);

        if (!seriesModel.getData().count()) {
            return;
        }

        var pointsBuilder = this._pointsBuilderList[0];
        if (!pointsBuilder) {
            pointsBuilder = this._pointsBuilderList[0] = new __WEBPACK_IMPORTED_MODULE_3__common_PointsBuilder__["a" /* default */](true, api);
        }
        this._pointsBuilderList.length = 1;

        this.groupGL.add(pointsBuilder.rootNode);

        this._removeTransformInPoints(seriesModel.getData().getLayout('points'));
        pointsBuilder.update(seriesModel, ecModel, api);

        this.viewGL.setPostEffect(seriesModel.getModel('postEffect'), api);
    },

    incrementalPrepareRender: function (seriesModel, ecModel, api) {
        this.groupGL.removeAll();
        this._glViewHelper.reset(seriesModel, api);

        this._currentStep = 0;

        this.viewGL.setPostEffect(seriesModel.getModel('postEffect'), api);
    },

    incrementalRender: function (params, seriesModel, ecModel, api) {
        if (params.end <= params.start) {
            return;
        }

        var pointsBuilder = this._pointsBuilderList[this._currentStep];
        if (!pointsBuilder) {
            pointsBuilder = new __WEBPACK_IMPORTED_MODULE_3__common_PointsBuilder__["a" /* default */](true, api);
            this._pointsBuilderList[this._currentStep] = pointsBuilder;
        }
        this.groupGL.add(pointsBuilder.rootNode);

        this._removeTransformInPoints(seriesModel.getData().getLayout('points'));

        pointsBuilder.setSizeScale(this._sizeScale);
        pointsBuilder.update(seriesModel, ecModel, api, params.start, params.end);

        api.getZr().refresh();

        this._currentStep++;
    },

    updateTransform: function (seriesModel, ecModel, api) {
        if (seriesModel.coordinateSystem.getRoamTransform) {
            this._glViewHelper.updateTransform(seriesModel, api);

            var zoom = this._glViewHelper.getZoom();
            var sizeScale = Math.max((seriesModel.get('zoomScale') || 0) * (zoom - 1) + 1, 0);
            this._sizeScale = sizeScale;

            this._pointsBuilderList.forEach(function (pointsBuilder) {
                pointsBuilder.setSizeScale(sizeScale);
            });
        }
    },

    _removeTransformInPoints: function (points) {
        if (!points) {
            return;
        }
        var pt = [];
        for (var i = 0; i < points.length; i += 2) {
            pt[0] = points[i];
            pt[1] = points[i + 1];
            this._glViewHelper.removeTransformInPoint(pt);
            points[i] = pt[0];
            points[i + 1] = pt[1];
        }
    },


    dispose: function () {
        this.groupGL.removeAll();
    },

    remove: function () {
        this.groupGL.removeAll();
    }
});

/***/ }),
/* 262 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__graphGL_GraphGLSeries__ = __webpack_require__(263);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__graphGL_GraphGLView__ = __webpack_require__(268);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__ = __webpack_require__(51);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(17);







__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default()('graphGL', 'circle', null));

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('graphGL'));

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(function (ecModel) {
    var paletteScope = {};
    ecModel.eachSeriesByType('graphGL', function (seriesModel) {
        var categoriesData = seriesModel.getCategoriesData();
        var data = seriesModel.getData();

        var categoryNameIdxMap = {};

        categoriesData.each(function (idx) {
            var name = categoriesData.getName(idx);
            categoryNameIdxMap[name] = idx;

            var itemModel = categoriesData.getItemModel(idx);
            var color = itemModel.get('itemStyle.color')
                || seriesModel.getColorFromPalette(name, paletteScope);
            categoriesData.setItemVisual(idx, 'color', color);
        });

        // Assign category color to visual
        if (categoriesData.count()) {
            data.each(function (idx) {
                var model = data.getItemModel(idx);
                var category = model.getShallow('category');
                if (category != null) {
                    if (typeof category === 'string') {
                        category = categoryNameIdxMap[category];
                    }
                    if (!data.getItemVisual(idx, 'color', true)) {
                        data.setItemVisual(
                            idx, 'color',
                            categoriesData.getItemVisual(category, 'color')
                        );
                    }
                }
            });
        }
    });
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(function (ecModel) {
    ecModel.eachSeriesByType('graphGL', function (seriesModel) {
        var graph = seriesModel.getGraph();
        var edgeData = seriesModel.getEdgeData();

        var colorQuery = 'lineStyle.color'.split('.');
        var opacityQuery = 'lineStyle.opacity'.split('.');

        edgeData.setVisual('color', seriesModel.get(colorQuery));
        edgeData.setVisual('opacity', seriesModel.get(opacityQuery));

        edgeData.each(function (idx) {
            var itemModel = edgeData.getItemModel(idx);
            var edge = graph.getEdgeByIndex(idx);
            // Edge visual must after node visual
            var color = itemModel.get(colorQuery);
            var opacity = itemModel.get(opacityQuery);
            switch (color) {
                case 'source':
                    color = edge.node1.getVisual('color');
                    break;
                case 'target':
                    color = edge.node2.getVisual('color');
                    break;
            }

            edge.setVisual('color', color);
            edge.setVisual('opacity', opacity);
        });
    });
});

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'graphGLRoam',
    event: 'graphglroam',
    update: 'series.graphGL:roam'
}, function (payload, ecModel) {
    ecModel.eachComponent({
        mainType: 'series', query: payload
    }, function (componentModel) {
        componentModel.setView(payload);
    });
});

function noop() {}

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'graphGLStartLayout',
    event: 'graphgllayoutstarted',
    update: 'series.graphGL:startLayout'
}, noop);

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'graphGLStopLayout',
    event: 'graphgllayoutstopped',
    update: 'series.graphGL:stopLayout'
}, noop);

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'graphGLFocusNodeAdjacency',
    event: 'graphGLFocusNodeAdjacency',
    update: 'series.graphGL:focusNodeAdjacency'
}, noop);


__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
    type: 'graphGLUnfocusNodeAdjacency',
    event: 'graphGLUnfocusNodeAdjacency',
    update: 'series.graphGL:unfocusNodeAdjacency'
}, noop);

/***/ }),
/* 263 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__createGraphFromNodeEdge__ = __webpack_require__(264);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_format__ = __webpack_require__(32);




var GraphSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({

    type: 'series.graphGL',

    visualColorAccessPath: 'itemStyle.color',

    init: function (option) {
        GraphSeries.superApply(this, 'init', arguments);

        // Provide data for legend select
        this.legendDataProvider = function () {
            return this._categoriesData;
        };

        this._updateCategoriesData();
    },

    mergeOption: function (option) {
        GraphSeries.superApply(this, 'mergeOption', arguments);

        this._updateCategoriesData();
    },

    getFormattedLabel: function (dataIndex, status, dataType, dimIndex) {
        var text = __WEBPACK_IMPORTED_MODULE_2__util_format__["a" /* default */].getFormattedLabel(this, dataIndex, status, dataType, dimIndex);
        if (text == null) {
            var data = this.getData();
            var lastDim = data.dimensions[data.dimensions.length - 1];
            text = data.get(lastDim, dataIndex);
        }
        return text;
    },

    getInitialData: function (option, ecModel) {
        var edges = option.edges || option.links || [];
        var nodes = option.data || option.nodes || [];
        var self = this;

        if (nodes && edges) {
            return Object(__WEBPACK_IMPORTED_MODULE_1__createGraphFromNodeEdge__["a" /* default */])(nodes, edges, this, true, beforeLink).data;
        }

        function beforeLink(nodeData, edgeData) {
            // Overwrite nodeData.getItemModel to
            nodeData.wrapMethod('getItemModel', function (model) {
                var categoriesModels = self._categoriesModels;
                var categoryIdx = model.getShallow('category');
                var categoryModel = categoriesModels[categoryIdx];
                if (categoryModel) {
                    categoryModel.parentModel = model.parentModel;
                    model.parentModel = categoryModel;
                }
                return model;
            });

            var edgeLabelModel = self.getModel('edgeLabel');
            // For option `edgeLabel` can be found by label.xxx.xxx on item mode.
            var fakeSeriesModel = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Model(
                { label: edgeLabelModel.option },
                edgeLabelModel.parentModel,
                ecModel
            );

            edgeData.wrapMethod('getItemModel', function (model) {
                model.customizeGetParent(edgeGetParent);
                return model;
            });

            function edgeGetParent(path) {
                path = this.parsePath(path);
                return (path && path[0] === 'label')
                    ? fakeSeriesModel
                    : this.parentModel;
            }
        }
    },

    /**
     * @return {module:echarts/data/Graph}
     */
    getGraph: function () {
        return this.getData().graph;
    },

    /**
     * @return {module:echarts/data/List}
     */
    getEdgeData: function () {
        return this.getGraph().edgeData;
    },

    /**
     * @return {module:echarts/data/List}
     */
    getCategoriesData: function () {
        return this._categoriesData;
    },

    /**
     * @override
     */
    formatTooltip: function (dataIndex, multipleSeries, dataType) {
        if (dataType === 'edge') {
            var nodeData = this.getData();
            var params = this.getDataParams(dataIndex, dataType);
            var edge = nodeData.graph.getEdgeByIndex(dataIndex);
            var sourceName = nodeData.getName(edge.node1.dataIndex);
            var targetName = nodeData.getName(edge.node2.dataIndex);

            var html = [];
            sourceName != null && html.push(sourceName);
            targetName != null && html.push(targetName);
            html = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.encodeHTML(html.join(' > '));

            if (params.value) {
                html += ' : ' + __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.encodeHTML(params.value);
            }
            return html;
        }
        else { // dataType === 'node' or empty
            return GraphSeries.superApply(this, 'formatTooltip', arguments);
        }
    },

    _updateCategoriesData: function () {
        var categories = (this.option.categories || []).map(function (category) {
            // Data must has value
            return category.value != null ? category : __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.extend({
                value: 0
            }, category);
        });
        var categoriesData = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(['value'], this);
        categoriesData.initData(categories);

        this._categoriesData = categoriesData;

        this._categoriesModels = categoriesData.mapArray(function (idx) {
            return categoriesData.getItemModel(idx, true);
        });
    },

    setView: function (payload) {
        if (payload.zoom != null) {
            this.option.zoom = payload.zoom;
        }
        if (payload.offset != null) {
            this.option.offset = payload.offset;
        }
    },

    setNodePosition: function (points) {
        for (var i = 0; i < points.length / 2; i++) {
            var x = points[i * 2];
            var y = points[i * 2 + 1];

            var opt = this.getData().getRawDataItem(i);
            opt.x = x;
            opt.y = y;
        }
    },

    isAnimationEnabled: function () {
        return GraphSeries.superCall(this, 'isAnimationEnabled')
            // Not enable animation when do force layout
            && !(this.get('layout') === 'force' && this.get('force.layoutAnimation'));
    },

    defaultOption: {
        zlevel: 10,
        z: 2,

        legendHoverLink: true,

        // Only support forceAtlas2
        layout: 'forceAtlas2',

        // Configuration of force directed layout
        forceAtlas2: {
            initLayout: null,

            GPU: true,

            steps: 1,

            // barnesHutOptimize

            // Maxp layout steps.
            maxSteps: 1000,

            repulsionByDegree: true,
            linLogMode: false,
            strongGravityMode: false,
            gravity: 1.0,
            // scaling: 1.0,

            edgeWeightInfluence: 1.0,

            // Edge weight range.
            edgeWeight: [1, 4],
            // Node weight range.
            nodeWeight: [1, 4],

            // jitterTolerence: 0.1,
            preventOverlap: false,
            gravityCenter: null
        },

        focusNodeAdjacency: true,

        focusNodeAdjacencyOn: 'mouseover',

        left: 'center',
        top: 'center',
        // right: null,
        // bottom: null,
        // width: '80%',
        // height: '80%',

        symbol: 'circle',
        symbolSize: 5,

        roam: false,

        // Default on center of graph
        center: null,

        zoom: 1,

        // categories: [],

        // data: []
        // Or
        // nodes: []
        //
        // links: []
        // Or
        // edges: []

        label: {
            show: false,
            formatter: '{b}',
            position: 'right',
            distance: 5,
            textStyle: {
                fontSize: 14
            }
        },

        itemStyle: {},

        lineStyle: {
            color: '#aaa',
            width: 1,
            opacity: 0.5
        },

        emphasis: {
            label: {
                show: true
            }
        },

        animation: false
    }
});

/* unused harmony default export */ var _unused_webpack_default_export = (GraphSeries);

/***/ }),
/* 264 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_data_Graph__ = __webpack_require__(265);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_data_Graph___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_data_Graph__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_helper_linkList__ = __webpack_require__(267);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_helper_linkList___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_helper_linkList__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_retrieve__ = __webpack_require__(2);





/* harmony default export */ __webpack_exports__["a"] = (function (nodes, edges, hostModel, directed, beforeLink) {
    var graph = new __WEBPACK_IMPORTED_MODULE_1_echarts_lib_data_Graph___default.a(directed);
    for (var i = 0; i < nodes.length; i++) {
        graph.addNode(__WEBPACK_IMPORTED_MODULE_3__util_retrieve__["a" /* default */].firstNotNull(
            // Id, name, dataIndex
            nodes[i].id, nodes[i].name, i
        ), i);
    }

    var linkNameList = [];
    var validEdges = [];
    var linkCount = 0;
    for (var i = 0; i < edges.length; i++) {
        var link = edges[i];
        var source = link.source;
        var target = link.target;
        // addEdge may fail when source or target not exists
        if (graph.addEdge(source, target, linkCount)) {
            validEdges.push(link);
            linkNameList.push(__WEBPACK_IMPORTED_MODULE_3__util_retrieve__["a" /* default */].firstNotNull(link.id, source + ' > ' + target));
            linkCount++;
        }
    }

    var nodeData;

    // FIXME, support more coordinate systems.
    var dimensionNames = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.completeDimensions(
        ['value'], nodes
    );
    nodeData = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(dimensionNames, hostModel);
    nodeData.initData(nodes);

    var edgeData = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(['value'], hostModel);
    edgeData.initData(validEdges, linkNameList);

    beforeLink && beforeLink(nodeData, edgeData);

    __WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_helper_linkList___default()({
        mainData: nodeData,
        struct: graph,
        structAttr: 'graph',
        datas: {node: nodeData, edge: edgeData},
        datasAttr: {node: 'data', edge: 'edgeData'}
    });

    // Update dataIndex of nodes and edges because invalid edge may be removed
    graph.update();

    return graph;
});;

/***/ }),
/* 265 */
/***/ (function(module, exports, __webpack_require__) {

var _config = __webpack_require__(104);

var __DEV__ = _config.__DEV__;

var zrUtil = __webpack_require__(13);

var _clazz = __webpack_require__(266);

var enableClassCheck = _clazz.enableClassCheck;

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

/**
 * Graph data structure
 *
 * @module echarts/data/Graph
 * @author Yi Shen(https://www.github.com/pissang)
 */
// id may be function name of Object, add a prefix to avoid this problem.
function generateNodeKey(id) {
  return '_EC_' + id;
}
/**
 * @alias module:echarts/data/Graph
 * @constructor
 * @param {boolean} directed
 */


var Graph = function (directed) {
  /**
   * 是否是有向图
   * @type {boolean}
   * @private
   */
  this._directed = directed || false;
  /**
   * @type {Array.<module:echarts/data/Graph.Node>}
   * @readOnly
   */

  this.nodes = [];
  /**
   * @type {Array.<module:echarts/data/Graph.Edge>}
   * @readOnly
   */

  this.edges = [];
  /**
   * @type {Object.<string, module:echarts/data/Graph.Node>}
   * @private
   */

  this._nodesMap = {};
  /**
   * @type {Object.<string, module:echarts/data/Graph.Edge>}
   * @private
   */

  this._edgesMap = {};
  /**
   * @type {module:echarts/data/List}
   * @readOnly
   */

  this.data;
  /**
   * @type {module:echarts/data/List}
   * @readOnly
   */

  this.edgeData;
};

var graphProto = Graph.prototype;
/**
 * @type {string}
 */

graphProto.type = 'graph';
/**
 * If is directed graph
 * @return {boolean}
 */

graphProto.isDirected = function () {
  return this._directed;
};
/**
 * Add a new node
 * @param {string} id
 * @param {number} [dataIndex]
 */


graphProto.addNode = function (id, dataIndex) {
  id = id || '' + dataIndex;
  var nodesMap = this._nodesMap;

  if (nodesMap[generateNodeKey(id)]) {
    return;
  }

  var node = new Node(id, dataIndex);
  node.hostGraph = this;
  this.nodes.push(node);
  nodesMap[generateNodeKey(id)] = node;
  return node;
};
/**
 * Get node by data index
 * @param  {number} dataIndex
 * @return {module:echarts/data/Graph~Node}
 */


graphProto.getNodeByIndex = function (dataIndex) {
  var rawIdx = this.data.getRawIndex(dataIndex);
  return this.nodes[rawIdx];
};
/**
 * Get node by id
 * @param  {string} id
 * @return {module:echarts/data/Graph.Node}
 */


graphProto.getNodeById = function (id) {
  return this._nodesMap[generateNodeKey(id)];
};
/**
 * Add a new edge
 * @param {number|string|module:echarts/data/Graph.Node} n1
 * @param {number|string|module:echarts/data/Graph.Node} n2
 * @param {number} [dataIndex=-1]
 * @return {module:echarts/data/Graph.Edge}
 */


graphProto.addEdge = function (n1, n2, dataIndex) {
  var nodesMap = this._nodesMap;
  var edgesMap = this._edgesMap; // PNEDING

  if (typeof n1 === 'number') {
    n1 = this.nodes[n1];
  }

  if (typeof n2 === 'number') {
    n2 = this.nodes[n2];
  }

  if (!Node.isInstance(n1)) {
    n1 = nodesMap[generateNodeKey(n1)];
  }

  if (!Node.isInstance(n2)) {
    n2 = nodesMap[generateNodeKey(n2)];
  }

  if (!n1 || !n2) {
    return;
  }

  var key = n1.id + '-' + n2.id; // PENDING

  if (edgesMap[key]) {
    return;
  }

  var edge = new Edge(n1, n2, dataIndex);
  edge.hostGraph = this;

  if (this._directed) {
    n1.outEdges.push(edge);
    n2.inEdges.push(edge);
  }

  n1.edges.push(edge);

  if (n1 !== n2) {
    n2.edges.push(edge);
  }

  this.edges.push(edge);
  edgesMap[key] = edge;
  return edge;
};
/**
 * Get edge by data index
 * @param  {number} dataIndex
 * @return {module:echarts/data/Graph~Node}
 */


graphProto.getEdgeByIndex = function (dataIndex) {
  var rawIdx = this.edgeData.getRawIndex(dataIndex);
  return this.edges[rawIdx];
};
/**
 * Get edge by two linked nodes
 * @param  {module:echarts/data/Graph.Node|string} n1
 * @param  {module:echarts/data/Graph.Node|string} n2
 * @return {module:echarts/data/Graph.Edge}
 */


graphProto.getEdge = function (n1, n2) {
  if (Node.isInstance(n1)) {
    n1 = n1.id;
  }

  if (Node.isInstance(n2)) {
    n2 = n2.id;
  }

  var edgesMap = this._edgesMap;

  if (this._directed) {
    return edgesMap[n1 + '-' + n2];
  } else {
    return edgesMap[n1 + '-' + n2] || edgesMap[n2 + '-' + n1];
  }
};
/**
 * Iterate all nodes
 * @param  {Function} cb
 * @param  {*} [context]
 */


graphProto.eachNode = function (cb, context) {
  var nodes = this.nodes;
  var len = nodes.length;

  for (var i = 0; i < len; i++) {
    if (nodes[i].dataIndex >= 0) {
      cb.call(context, nodes[i], i);
    }
  }
};
/**
 * Iterate all edges
 * @param  {Function} cb
 * @param  {*} [context]
 */


graphProto.eachEdge = function (cb, context) {
  var edges = this.edges;
  var len = edges.length;

  for (var i = 0; i < len; i++) {
    if (edges[i].dataIndex >= 0 && edges[i].node1.dataIndex >= 0 && edges[i].node2.dataIndex >= 0) {
      cb.call(context, edges[i], i);
    }
  }
};
/**
 * Breadth first traverse
 * @param {Function} cb
 * @param {module:echarts/data/Graph.Node} startNode
 * @param {string} [direction='none'] 'none'|'in'|'out'
 * @param {*} [context]
 */


graphProto.breadthFirstTraverse = function (cb, startNode, direction, context) {
  if (!Node.isInstance(startNode)) {
    startNode = this._nodesMap[generateNodeKey(startNode)];
  }

  if (!startNode) {
    return;
  }

  var edgeType = direction === 'out' ? 'outEdges' : direction === 'in' ? 'inEdges' : 'edges';

  for (var i = 0; i < this.nodes.length; i++) {
    this.nodes[i].__visited = false;
  }

  if (cb.call(context, startNode, null)) {
    return;
  }

  var queue = [startNode];

  while (queue.length) {
    var currentNode = queue.shift();
    var edges = currentNode[edgeType];

    for (var i = 0; i < edges.length; i++) {
      var e = edges[i];
      var otherNode = e.node1 === currentNode ? e.node2 : e.node1;

      if (!otherNode.__visited) {
        if (cb.call(context, otherNode, currentNode)) {
          // Stop traversing
          return;
        }

        queue.push(otherNode);
        otherNode.__visited = true;
      }
    }
  }
}; // TODO
// graphProto.depthFirstTraverse = function (
//     cb, startNode, direction, context
// ) {
// };
// Filter update


graphProto.update = function () {
  var data = this.data;
  var edgeData = this.edgeData;
  var nodes = this.nodes;
  var edges = this.edges;

  for (var i = 0, len = nodes.length; i < len; i++) {
    nodes[i].dataIndex = -1;
  }

  for (var i = 0, len = data.count(); i < len; i++) {
    nodes[data.getRawIndex(i)].dataIndex = i;
  }

  edgeData.filterSelf(function (idx) {
    var edge = edges[edgeData.getRawIndex(idx)];
    return edge.node1.dataIndex >= 0 && edge.node2.dataIndex >= 0;
  }); // Update edge

  for (var i = 0, len = edges.length; i < len; i++) {
    edges[i].dataIndex = -1;
  }

  for (var i = 0, len = edgeData.count(); i < len; i++) {
    edges[edgeData.getRawIndex(i)].dataIndex = i;
  }
};
/**
 * @return {module:echarts/data/Graph}
 */


graphProto.clone = function () {
  var graph = new Graph(this._directed);
  var nodes = this.nodes;
  var edges = this.edges;

  for (var i = 0; i < nodes.length; i++) {
    graph.addNode(nodes[i].id, nodes[i].dataIndex);
  }

  for (var i = 0; i < edges.length; i++) {
    var e = edges[i];
    graph.addEdge(e.node1.id, e.node2.id, e.dataIndex);
  }

  return graph;
};
/**
 * @alias module:echarts/data/Graph.Node
 */


function Node(id, dataIndex) {
  /**
  * @type {string}
  */
  this.id = id == null ? '' : id;
  /**
  * @type {Array.<module:echarts/data/Graph.Edge>}
  */

  this.inEdges = [];
  /**
  * @type {Array.<module:echarts/data/Graph.Edge>}
  */

  this.outEdges = [];
  /**
  * @type {Array.<module:echarts/data/Graph.Edge>}
  */

  this.edges = [];
  /**
   * @type {module:echarts/data/Graph}
   */

  this.hostGraph;
  /**
   * @type {number}
   */

  this.dataIndex = dataIndex == null ? -1 : dataIndex;
}

Node.prototype = {
  constructor: Node,

  /**
   * @return {number}
   */
  degree: function () {
    return this.edges.length;
  },

  /**
   * @return {number}
   */
  inDegree: function () {
    return this.inEdges.length;
  },

  /**
  * @return {number}
  */
  outDegree: function () {
    return this.outEdges.length;
  },

  /**
   * @param {string} [path]
   * @return {module:echarts/model/Model}
   */
  getModel: function (path) {
    if (this.dataIndex < 0) {
      return;
    }

    var graph = this.hostGraph;
    var itemModel = graph.data.getItemModel(this.dataIndex);
    return itemModel.getModel(path);
  }
};
/**
 * 图边
 * @alias module:echarts/data/Graph.Edge
 * @param {module:echarts/data/Graph.Node} n1
 * @param {module:echarts/data/Graph.Node} n2
 * @param {number} [dataIndex=-1]
 */

function Edge(n1, n2, dataIndex) {
  /**
   * 节点1，如果是有向图则为源节点
   * @type {module:echarts/data/Graph.Node}
   */
  this.node1 = n1;
  /**
   * 节点2，如果是有向图则为目标节点
   * @type {module:echarts/data/Graph.Node}
   */

  this.node2 = n2;
  this.dataIndex = dataIndex == null ? -1 : dataIndex;
}
/**
 * @param {string} [path]
 * @return {module:echarts/model/Model}
 */


Edge.prototype.getModel = function (path) {
  if (this.dataIndex < 0) {
    return;
  }

  var graph = this.hostGraph;
  var itemModel = graph.edgeData.getItemModel(this.dataIndex);
  return itemModel.getModel(path);
};

var createGraphDataProxyMixin = function (hostName, dataName) {
  return {
    /**
     * @param {string=} [dimension='value'] Default 'value'. can be 'a', 'b', 'c', 'd', 'e'.
     * @return {number}
     */
    getValue: function (dimension) {
      var data = this[hostName][dataName];
      return data.get(data.getDimension(dimension || 'value'), this.dataIndex);
    },

    /**
     * @param {Object|string} key
     * @param {*} [value]
     */
    setVisual: function (key, value) {
      this.dataIndex >= 0 && this[hostName][dataName].setItemVisual(this.dataIndex, key, value);
    },

    /**
     * @param {string} key
     * @return {boolean}
     */
    getVisual: function (key, ignoreParent) {
      return this[hostName][dataName].getItemVisual(this.dataIndex, key, ignoreParent);
    },

    /**
     * @param {Object} layout
     * @return {boolean} [merge=false]
     */
    setLayout: function (layout, merge) {
      this.dataIndex >= 0 && this[hostName][dataName].setItemLayout(this.dataIndex, layout, merge);
    },

    /**
     * @return {Object}
     */
    getLayout: function () {
      return this[hostName][dataName].getItemLayout(this.dataIndex);
    },

    /**
     * @return {module:zrender/Element}
     */
    getGraphicEl: function () {
      return this[hostName][dataName].getItemGraphicEl(this.dataIndex);
    },

    /**
     * @return {number}
     */
    getRawIndex: function () {
      return this[hostName][dataName].getRawIndex(this.dataIndex);
    }
  };
};

zrUtil.mixin(Node, createGraphDataProxyMixin('hostGraph', 'data'));
zrUtil.mixin(Edge, createGraphDataProxyMixin('hostGraph', 'edgeData'));
Graph.Node = Node;
Graph.Edge = Edge;
enableClassCheck(Node);
enableClassCheck(Edge);
var _default = Graph;
module.exports = _default;

/***/ }),
/* 266 */
/***/ (function(module, exports, __webpack_require__) {

var _config = __webpack_require__(104);

var __DEV__ = _config.__DEV__;

var zrUtil = __webpack_require__(13);

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

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

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

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


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


function enableClassExtend(RootClass, mandatoryMethods) {
  RootClass.$constructor = RootClass;

  RootClass.extend = function (proto) {
    var superClass = this;

    var ExtendedClass = function () {
      if (!proto.$constructor) {
        superClass.apply(this, arguments);
      } else {
        proto.$constructor.apply(this, arguments);
      }
    };

    zrUtil.extend(ExtendedClass.prototype, proto);
    ExtendedClass.extend = this.extend;
    ExtendedClass.superCall = superCall;
    ExtendedClass.superApply = superApply;
    zrUtil.inherits(ExtendedClass, this);
    ExtendedClass.superClass = superClass;
    return ExtendedClass;
  };
}

var classBase = 0;
/**
 * Can not use instanceof, consider different scope by
 * cross domain or es module import in ec extensions.
 * Mount a method "isInstance()" to Clz.
 */

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

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


function superCall(context, methodName) {
  var args = zrUtil.slice(arguments, 2);
  return this.superClass.prototype[methodName].apply(context, args);
}

function superApply(context, methodName, args) {
  return this.superClass.prototype[methodName].apply(context, args);
}
/**
 * @param {Object} entity
 * @param {Object} options
 * @param {boolean} [options.registerWhenExtend]
 * @public
 */


function enableClassManagement(entity, options) {
  options = options || {};
  /**
   * Component model classes
   * key: componentType,
   * value:
   *     componentClass, when componentType is 'xxx'
   *     or Object.<subKey, componentClass>, when componentType is 'xxx.yy'
   * @type {Object}
   */

  var storage = {};

  entity.registerClass = function (Clazz, componentType) {
    if (componentType) {
      checkClassType(componentType);
      componentType = parseClassType(componentType);

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

    return Clazz;
  };

  entity.getClass = function (componentMainType, subType, throwWhenNotFound) {
    var Clazz = storage[componentMainType];

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

    if (throwWhenNotFound && !Clazz) {
      throw new Error(!subType ? componentMainType + '.' + 'type should be specified.' : 'Component ' + componentMainType + '.' + (subType || '') + ' not exists. Load it first.');
    }

    return Clazz;
  };

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

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

    return result;
  };

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


  entity.getAllClassMainTypes = function () {
    var types = [];
    zrUtil.each(storage, function (obj, type) {
      types.push(type);
    });
    return types;
  };
  /**
   * If a main type is container and has sub types
   * @param  {string}  mainType
   * @return {boolean}
   */


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

  entity.parseClassType = parseClassType;

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

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

    return container;
  }

  if (options.registerWhenExtend) {
    var originalExtend = entity.extend;

    if (originalExtend) {
      entity.extend = function (proto) {
        var ExtendedClass = originalExtend.call(this, proto);
        return entity.registerClass(ExtendedClass, proto.type);
      };
    }
  }

  return entity;
}
/**
 * @param {string|Array.<string>} properties
 */


function setReadOnly(obj, properties) {// FIXME It seems broken in IE8 simulation of IE11
  // if (!zrUtil.isArray(properties)) {
  //     properties = properties != null ? [properties] : [];
  // }
  // zrUtil.each(properties, function (prop) {
  //     var value = obj[prop];
  //     Object.defineProperty
  //         && Object.defineProperty(obj, prop, {
  //             value: value, writable: false
  //         });
  //     zrUtil.isArray(obj[prop])
  //         && Object.freeze
  //         && Object.freeze(obj[prop]);
  // });
}

exports.parseClassType = parseClassType;
exports.enableClassExtend = enableClassExtend;
exports.enableClassCheck = enableClassCheck;
exports.enableClassManagement = enableClassManagement;
exports.setReadOnly = setReadOnly;

/***/ }),
/* 267 */
/***/ (function(module, exports, __webpack_require__) {

var zrUtil = __webpack_require__(13);

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

/**
 * Link lists and struct (graph or tree)
 */
var each = zrUtil.each;
var DATAS = '\0__link_datas';
var MAIN_DATA = '\0__link_mainData'; // Caution:
// In most case, either list or its shallow clones (see list.cloneShallow)
// is active in echarts process. So considering heap memory consumption,
// we do not clone tree or graph, but share them among list and its shallow clones.
// But in some rare case, we have to keep old list (like do animation in chart). So
// please take care that both the old list and the new list share the same tree/graph.

/**
 * @param {Object} opt
 * @param {module:echarts/data/List} opt.mainData
 * @param {Object} [opt.struct] For example, instance of Graph or Tree.
 * @param {string} [opt.structAttr] designation: list[structAttr] = struct;
 * @param {Object} [opt.datas] {dataType: data},
 *                 like: {node: nodeList, edge: edgeList}.
 *                 Should contain mainData.
 * @param {Object} [opt.datasAttr] {dataType: attr},
 *                 designation: struct[datasAttr[dataType]] = list;
 */

function linkList(opt) {
  var mainData = opt.mainData;
  var datas = opt.datas;

  if (!datas) {
    datas = {
      main: mainData
    };
    opt.datasAttr = {
      main: 'data'
    };
  }

  opt.datas = opt.mainData = null;
  linkAll(mainData, datas, opt); // Porxy data original methods.

  each(datas, function (data) {
    each(mainData.TRANSFERABLE_METHODS, function (methodName) {
      data.wrapMethod(methodName, zrUtil.curry(transferInjection, opt));
    });
  }); // Beyond transfer, additional features should be added to `cloneShallow`.

  mainData.wrapMethod('cloneShallow', zrUtil.curry(cloneShallowInjection, opt)); // Only mainData trigger change, because struct.update may trigger
  // another changable methods, which may bring about dead lock.

  each(mainData.CHANGABLE_METHODS, function (methodName) {
    mainData.wrapMethod(methodName, zrUtil.curry(changeInjection, opt));
  }); // Make sure datas contains mainData.

  zrUtil.assert(datas[mainData.dataType] === mainData);
}

function transferInjection(opt, res) {
  if (isMainData(this)) {
    // Transfer datas to new main data.
    var datas = zrUtil.extend({}, this[DATAS]);
    datas[this.dataType] = res;
    linkAll(res, datas, opt);
  } else {
    // Modify the reference in main data to point newData.
    linkSingle(res, this.dataType, this[MAIN_DATA], opt);
  }

  return res;
}

function changeInjection(opt, res) {
  opt.struct && opt.struct.update(this);
  return res;
}

function cloneShallowInjection(opt, res) {
  // cloneShallow, which brings about some fragilities, may be inappropriate
  // to be exposed as an API. So for implementation simplicity we can make
  // the restriction that cloneShallow of not-mainData should not be invoked
  // outside, but only be invoked here.
  each(res[DATAS], function (data, dataType) {
    data !== res && linkSingle(data.cloneShallow(), dataType, res, opt);
  });
  return res;
}
/**
 * Supplement method to List.
 *
 * @public
 * @param {string} [dataType] If not specified, return mainData.
 * @return {module:echarts/data/List}
 */


function getLinkedData(dataType) {
  var mainData = this[MAIN_DATA];
  return dataType == null || mainData == null ? mainData : mainData[DATAS][dataType];
}

function isMainData(data) {
  return data[MAIN_DATA] === data;
}

function linkAll(mainData, datas, opt) {
  mainData[DATAS] = {};
  each(datas, function (data, dataType) {
    linkSingle(data, dataType, mainData, opt);
  });
}

function linkSingle(data, dataType, mainData, opt) {
  mainData[DATAS][dataType] = data;
  data[MAIN_DATA] = mainData;
  data.dataType = dataType;

  if (opt.struct) {
    data[opt.structAttr] = opt.struct;
    opt.struct[opt.datasAttr[dataType]] = data;
  } // Supplement method.


  data.getLinkedData = getLinkedData;
}

var _default = linkList;
module.exports = _default;

/***/ }),
/* 268 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_util_layout__ = __webpack_require__(47);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_util_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_util_layout__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_geometry_Lines2D__ = __webpack_require__(105);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__ForceAtlas2GPU__ = __webpack_require__(269);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__ForceAtlas2__ = __webpack_require__(271);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_zrender_lib_animation_requestAnimationFrame__ = __webpack_require__(80);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_zrender_lib_animation_requestAnimationFrame___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_zrender_lib_animation_requestAnimationFrame__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_claygl_src_dep_glmatrix__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__util_Roam2DControl__ = __webpack_require__(273);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__common_PointsBuilder__ = __webpack_require__(67);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__util_shader_lines2D_glsl_js__ = __webpack_require__(274);











var vec2 = __WEBPACK_IMPORTED_MODULE_9_claygl_src_dep_glmatrix__["a" /* default */].vec2;






__WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_12__util_shader_lines2D_glsl_js__["a" /* default */]);

var globalLayoutId = 1;

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({

    type: 'graphGL',

    __ecgl__: true,

    init: function (ecModel, api) {

        this.groupGL = new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Node();
        this.viewGL = new __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__["a" /* default */]('orthographic');
        this.viewGL.camera.left = this.viewGL.camera.right = 0;

        this.viewGL.add(this.groupGL);

        this._pointsBuilder = new __WEBPACK_IMPORTED_MODULE_11__common_PointsBuilder__["a" /* default */](true, api);

        // Mesh used during force directed layout.
        this._forceEdgesMesh = new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Mesh({
            material: new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Material({
                shader: __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].createShader('ecgl.forceAtlas2.edges'),
                transparent: true,
                depthMask: false,
                depthTest: false
            }),
            $ignorePicking: true,
            geometry: new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Geometry({
                attributes: {
                    node: new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Geometry.Attribute('node', 'float', 2),
                    color: new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Geometry.Attribute('color', 'float', 4, 'COLOR')
                },
                dynamic: true,
                mainAttribute: 'node'
            }),
            renderOrder: -1,
            mode: __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Mesh.LINES
        });

        // Mesh used after force directed layout.
        this._edgesMesh = new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Mesh({
            material: new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Material({
                shader: __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].createShader('ecgl.meshLines2D'),
                transparent: true,
                depthMask: false,
                depthTest: false
            }),
            $ignorePicking: true,
            geometry: new __WEBPACK_IMPORTED_MODULE_4__util_geometry_Lines2D__["a" /* default */]({
                useNativeLine: false,
                dynamic: true
            }),
            renderOrder: -1,
            culling: false
        });

        this._layoutId = 0;

        this._control = new __WEBPACK_IMPORTED_MODULE_10__util_Roam2DControl__["a" /* default */]({
            zr: api.getZr(),
            viewGL: this.viewGL
        });
        this._control.setTarget(this.groupGL);
        this._control.init();


        this._clickHandler = this._clickHandler.bind(this);
    },

    render: function (seriesModel, ecModel, api) {
        this.groupGL.add(this._pointsBuilder.rootNode);

        this._model = seriesModel;
        this._api = api;

        this._initLayout(seriesModel, ecModel, api);

        this._pointsBuilder.update(seriesModel, ecModel, api);

        if (!(this._forceLayoutInstance instanceof __WEBPACK_IMPORTED_MODULE_6__ForceAtlas2GPU__["a" /* default */])) {
            this.groupGL.remove(this._forceEdgesMesh);
        }

        this._updateCamera(seriesModel, api);

        this._control.off('update');
        this._control.on('update', function () {
            api.dispatchAction({
                type: 'graphGLRoam',
                seriesId: seriesModel.id,
                zoom: this._control.getZoom(),
                offset: this._control.getOffset()
            });

            this._pointsBuilder.updateView(this.viewGL.camera);
        }, this);

        this._control.setZoom(__WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(seriesModel.get('zoom'), 1));
        this._control.setOffset(seriesModel.get('offset') || [0, 0]);

        var mesh = this._pointsBuilder.getPointsMesh();
        mesh.off('mousemove', this._mousemoveHandler);
        mesh.off('mouseout', this._mouseOutHandler, this);
        api.getZr().off('click', this._clickHandler);

        this._pointsBuilder.highlightOnMouseover = true;
        if (seriesModel.get('focusNodeAdjacency')) {
            var focusNodeAdjacencyOn = seriesModel.get('focusNodeAdjacencyOn');
            if (focusNodeAdjacencyOn === 'click') {
                // Remove default emphasis effect
                api.getZr().on('click', this._clickHandler);
            }
            else if (focusNodeAdjacencyOn === 'mouseover') {
                mesh.on('mousemove', this._mousemoveHandler, this);
                mesh.on('mouseout', this._mouseOutHandler, this);

                this._pointsBuilder.highlightOnMouseover = false;
            }
            else {
                if (true) {
                    console.warn('Unkown focusNodeAdjacencyOn value \s' + focusNodeAdjacencyOn);
                }
            }
        }

        // Reset
        this._lastMouseOverDataIndex = -1;
    },

    _clickHandler: function (e) {
        if (this._layouting) {
            return;
        }
        var dataIndex = this._pointsBuilder.getPointsMesh().dataIndex;
        if (dataIndex >= 0) {
            this._api.dispatchAction({
                type: 'graphGLFocusNodeAdjacency',
                seriesId: this._model.id,
                dataIndex: dataIndex
            });
        }
        else {
            this._api.dispatchAction({
                type: 'graphGLUnfocusNodeAdjacency',
                seriesId: this._model.id
            });
        }
    },

    _mousemoveHandler: function (e) {
        if (this._layouting) {
            return;
        }
        var dataIndex = this._pointsBuilder.getPointsMesh().dataIndex;
        if (dataIndex >= 0) {
            if (dataIndex !== this._lastMouseOverDataIndex) {
                this._api.dispatchAction({
                    type: 'graphGLFocusNodeAdjacency',
                    seriesId: this._model.id,
                    dataIndex: dataIndex
                });
            }
        }
        else {
            this._mouseOutHandler(e);
        }

        this._lastMouseOverDataIndex = dataIndex;
    },

    _mouseOutHandler: function (e) {
        if (this._layouting) {
            return;
        }

        this._api.dispatchAction({
            type: 'graphGLUnfocusNodeAdjacency',
            seriesId: this._model.id
        });

        this._lastMouseOverDataIndex = -1;
    },

    _updateForceEdgesGeometry: function (edges, seriesModel) {
        var geometry = this._forceEdgesMesh.geometry;

        var edgeData = seriesModel.getEdgeData();
        var offset = 0;
        var layoutInstance = this._forceLayoutInstance;
        var vertexCount = edgeData.count() * 2;
        geometry.attributes.node.init(vertexCount);
        geometry.attributes.color.init(vertexCount);
        edgeData.each(function (idx) {
            var edge = edges[idx];
            geometry.attributes.node.set(offset, layoutInstance.getNodeUV(edge.node1));
            geometry.attributes.node.set(offset + 1, layoutInstance.getNodeUV(edge.node2));

            var color = edgeData.getItemVisual(edge.dataIndex, 'color');
            var colorArr = __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].parseColor(color);
            colorArr[3] *= __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(
                edgeData.getItemVisual(edge.dataIndex, 'opacity'), 1
            );
            geometry.attributes.color.set(offset, colorArr);
            geometry.attributes.color.set(offset + 1, colorArr);

            offset += 2;
        });
        geometry.dirty();
    },

    _updateMeshLinesGeometry: function () {
        var edgeData = this._model.getEdgeData();
        var geometry = this._edgesMesh.geometry;
        var edgeData = this._model.getEdgeData();
        var points = this._model.getData().getLayout('points');

        geometry.resetOffset();
        geometry.setVertexCount(edgeData.count() * geometry.getLineVertexCount());
        geometry.setTriangleCount(edgeData.count() * geometry.getLineTriangleCount());

        var p0 = [];
        var p1 = [];

        var lineWidthQuery = ['lineStyle', 'width'];

        this._originalEdgeColors = new Float32Array(edgeData.count() * 4);
        this._edgeIndicesMap = new Float32Array(edgeData.count());
        edgeData.each(function (idx) {
            var edge = edgeData.graph.getEdgeByIndex(idx);
            var idx1 = edge.node1.dataIndex * 2;
            var idx2 = edge.node2.dataIndex * 2;
            p0[0] = points[idx1];
            p0[1] = points[idx1 + 1];
            p1[0] = points[idx2];
            p1[1] = points[idx2 + 1];

            var color = edgeData.getItemVisual(edge.dataIndex, 'color');
            var colorArr = __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].parseColor(color);
            colorArr[3] *= __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(edgeData.getItemVisual(edge.dataIndex, 'opacity'), 1);
            var itemModel = edgeData.getItemModel(edge.dataIndex);
            var lineWidth = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(itemModel.get(lineWidthQuery), 1) * this._api.getDevicePixelRatio();

            geometry.addLine(p0, p1, colorArr, lineWidth);

            for (var k = 0; k < 4; k++) {
                this._originalEdgeColors[edge.dataIndex * 4 + k] = colorArr[k];
            }
            this._edgeIndicesMap[edge.dataIndex] = idx;
        }, this);

        geometry.dirty();
    },

    _updateForceNodesGeometry: function (nodeData) {
        var pointsMesh = this._pointsBuilder.getPointsMesh();
        var pos = [];
        for (var i = 0; i < nodeData.count(); i++) {
            this._forceLayoutInstance.getNodeUV(i, pos);
            pointsMesh.geometry.attributes.position.set(i, pos);
        }
        pointsMesh.geometry.dirty('position');
    },

    _initLayout: function (seriesModel, ecModel, api) {
        var layout = seriesModel.get('layout');
        var graph = seriesModel.getGraph();

        var boxLayoutOption = seriesModel.getBoxLayoutParams();
        var viewport = __WEBPACK_IMPORTED_MODULE_1_echarts_lib_util_layout___default.a.getLayoutRect(boxLayoutOption, {
            width: api.getWidth(),
            height: api.getHeight()
        });

        if (layout === 'force') {
            if (true) {
                console.warn('Currently only forceAtlas2 layout supported.');
            }
            layout = 'forceAtlas2';
        }
        // Stop previous layout
        this.stopLayout(seriesModel, ecModel, api, {
            beforeLayout: true
        });

        var nodeData = seriesModel.getData();
        var edgeData = seriesModel.getData();
        if (layout === 'forceAtlas2') {
            var layoutModel = seriesModel.getModel('forceAtlas2');
            var layoutInstance = this._forceLayoutInstance;
            var nodes = [];
            var edges = [];

            var nodeDataExtent = nodeData.getDataExtent('value');
            var edgeDataExtent = edgeData.getDataExtent('value');

            var edgeWeightRange = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(layoutModel.get('edgeWeight'), 1.0);
            var nodeWeightRange = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(layoutModel.get('nodeWeight'), 1.0);
            if (typeof edgeWeightRange === 'number') {
                edgeWeightRange = [edgeWeightRange, edgeWeightRange];
            }
            if (typeof nodeWeightRange === 'number') {
                nodeWeightRange = [nodeWeightRange, nodeWeightRange];
            }

            var offset = 0;
            var nodesIndicesMap = {};

            var layoutPoints = new Float32Array(nodeData.count() * 2);
            graph.eachNode(function (node) {
                var dataIndex = node.dataIndex;
                var value = nodeData.get('value', dataIndex);
                var x;
                var y;
                if (nodeData.hasItemOption) {
                    var itemModel = nodeData.getItemModel(dataIndex);
                    x = itemModel.get('x');
                    y = itemModel.get('y');
                }
                if (x == null) {
                    // Random in rectangle
                    x = viewport.x + Math.random() * viewport.width;
                    y = viewport.y + Math.random() * viewport.height;
                }
                layoutPoints[offset * 2] = x;
                layoutPoints[offset * 2 + 1] = y;

                nodesIndicesMap[node.id] = offset++;
                var mass = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.linearMap(value, nodeDataExtent, nodeWeightRange);
                if (isNaN(mass)) {
                    if (!isNaN(nodeWeightRange[0])) {
                        mass = nodeWeightRange[0];
                    }
                    else {
                        mass = 1;
                    }
                }
                nodes.push({
                    x: x, y: y, mass: mass, size: nodeData.getItemVisual(dataIndex, 'symbolSize')
                });
            });
            nodeData.setLayout('points', layoutPoints);

            graph.eachEdge(function (edge) {
                var dataIndex = edge.dataIndex;
                var value = nodeData.get('value', dataIndex);
                var weight = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.linearMap(value, edgeDataExtent, edgeWeightRange);
                if (isNaN(weight)) {
                    if (!isNaN(edgeWeightRange[0])) {
                        weight = edgeWeightRange[0];
                    }
                    else {
                        weight = 1;
                    }
                }
                edges.push({
                    node1: nodesIndicesMap[edge.node1.id],
                    node2: nodesIndicesMap[edge.node2.id],
                    weight: weight,
                    dataIndex: dataIndex
                });
            });
            if (!layoutInstance) {
                var isGPU = layoutModel.get('GPU');
                if (this._forceLayoutInstance) {
                    if ((isGPU && !(this._forceLayoutInstance instanceof __WEBPACK_IMPORTED_MODULE_6__ForceAtlas2GPU__["a" /* default */]))
                        || (!isGPU && !(this._forceLayoutInstance instanceof __WEBPACK_IMPORTED_MODULE_7__ForceAtlas2__["a" /* default */]))
                    ) {
                        // Mark to dispose
                        this._forceLayoutInstanceToDispose = this._forceLayoutInstance;
                    }
                }
                layoutInstance = this._forceLayoutInstance = isGPU
                    ? new __WEBPACK_IMPORTED_MODULE_6__ForceAtlas2GPU__["a" /* default */]()
                    : new __WEBPACK_IMPORTED_MODULE_7__ForceAtlas2__["a" /* default */]();
            }
            layoutInstance.initData(nodes, edges);
            layoutInstance.updateOption(layoutModel.option);

            // Update lines geometry after first layout;
            this._updateForceEdgesGeometry(layoutInstance.getEdges(), seriesModel);
            this._updatePositionTexture();

            api.dispatchAction({
                type: 'graphGLStartLayout',
                from: this.uid
            });
        }
        else {
            var layoutPoints = new Float32Array(nodeData.count() * 2);
            var offset = 0;
            graph.eachNode(function (node) {
                var dataIndex = node.dataIndex;
                var x;
                var y;
                if (nodeData.hasItemOption) {
                    var itemModel = nodeData.getItemModel(dataIndex);
                    x = itemModel.get('x');
                    y = itemModel.get('y');
                }
                layoutPoints[offset++] = x;
                layoutPoints[offset++] = y;
            });
            nodeData.setLayout('points', layoutPoints);

            this._updateAfterLayout(seriesModel, ecModel, api);
        }
    },

    _updatePositionTexture: function () {
        var positionTex = this._forceLayoutInstance.getNodePositionTexture();
        this._pointsBuilder.setPositionTexture(positionTex);
        this._forceEdgesMesh.material.set('positionTex', positionTex);
    },

    startLayout: function (seriesModel, ecModel, api, payload) {
        if (payload && payload.from != null && payload.from !== this.uid) {
            return;
        }

        var viewGL = this.viewGL;
        var api = this._api;
        var layoutInstance = this._forceLayoutInstance;
        var data = this._model.getData();
        var layoutModel = this._model.getModel('forceAtlas2');

        if (!layoutInstance) {
            if (true) {
                console.error('None layout don\'t have startLayout action');
            }
            return;
        }

        this.groupGL.remove(this._edgesMesh);
        this.groupGL.add(this._forceEdgesMesh);

        if (!this._forceLayoutInstance) {
            return;
        }

        this._updateForceNodesGeometry(seriesModel.getData());
        this._pointsBuilder.hideLabels();

        var self = this;
        var layoutId = this._layoutId = globalLayoutId++;
        var maxSteps = layoutModel.getShallow('maxSteps');
        var steps = layoutModel.getShallow('steps');
        var stepsCount = 0;
        var syncStepCount = Math.max(steps * 2, 20);
        var doLayout = function (layoutId) {
            if (layoutId !== self._layoutId) {
                return;
            }
            if (layoutInstance.isFinished(maxSteps)) {
                api.dispatchAction({
                    type: 'graphGLStopLayout',
                    from: self.uid
                });
                api.dispatchAction({
                    type: 'graphGLFinishLayout',
                    points: data.getLayout('points'),
                    from: self.uid
                });
                return;
            }

            layoutInstance.update(viewGL.layer.renderer, steps, function () {
                self._updatePositionTexture();
                // PENDING Performance.
                stepsCount += steps;
                // Sync posiiton every 20 steps.
                if (stepsCount >= syncStepCount) {
                    self._syncNodePosition(seriesModel);
                    stepsCount = 0;
                }
                // Position texture will been swapped. set every time.
                api.getZr().refresh();

                __WEBPACK_IMPORTED_MODULE_8_zrender_lib_animation_requestAnimationFrame___default()(function () {
                    doLayout(layoutId);
                });
            });
        };

        __WEBPACK_IMPORTED_MODULE_8_zrender_lib_animation_requestAnimationFrame___default()(function () {
            if (self._forceLayoutInstanceToDispose) {
                self._forceLayoutInstanceToDispose.dispose(viewGL.layer.renderer);
                self._forceLayoutInstanceToDispose = null;
            }
            doLayout(layoutId);
        });

        this._layouting = true;
    },

    stopLayout: function (seriesModel, ecModel, api, payload) {
        if (payload && payload.from != null && payload.from !== this.uid) {
            return;
        }

        this._layoutId = 0;
        this.groupGL.remove(this._forceEdgesMesh);
        this.groupGL.add(this._edgesMesh);

        if (!this._forceLayoutInstance) {
            return;
        }

        if (!this.viewGL.layer) {
            return;
        }

        if (!(payload && payload.beforeLayout)) {
            this._syncNodePosition(seriesModel);
            this._updateAfterLayout(seriesModel, ecModel, api);
        }

        this._api.getZr().refresh();

        this._layouting = false;
    },

    _syncNodePosition: function (seriesModel) {
        var points = this._forceLayoutInstance.getNodePosition(this.viewGL.layer.renderer);
        seriesModel.getData().setLayout('points', points);

        seriesModel.setNodePosition(points);
    },

    _updateAfterLayout: function (seriesModel, ecModel, api) {
        this._updateMeshLinesGeometry();

        this._pointsBuilder.removePositionTexture();

        this._pointsBuilder.updateLayout(seriesModel, ecModel, api);

        this._pointsBuilder.updateView(this.viewGL.camera);

        this._pointsBuilder.updateLabels();

        this._pointsBuilder.showLabels();

    },

    focusNodeAdjacency: function (seriesModel, ecModel, api, payload) {

        var data = this._model.getData();

        this._downplayAll();

        var dataIndex = payload.dataIndex;

        var graph = data.graph;

        var focusNodes = [];
        var node = graph.getNodeByIndex(dataIndex);
        focusNodes.push(node);
        node.edges.forEach(function (edge) {
            if (edge.dataIndex < 0) {
                return;
            }
            edge.node1 !== node && focusNodes.push(edge.node1);
            edge.node2 !== node && focusNodes.push(edge.node2);
        }, this);

        this._pointsBuilder.fadeOutAll(0.05);
        this._fadeOutEdgesAll(0.05);

        focusNodes.forEach(function (node) {
            this._pointsBuilder.highlight(data, node.dataIndex);
        }, this);

        this._pointsBuilder.updateLabels(focusNodes.map(function (node) {
            return node.dataIndex;
        }));

        var focusEdges = [];
        node.edges.forEach(function (edge) {
            if (edge.dataIndex >= 0) {
                this._highlightEdge(edge.dataIndex);
                focusEdges.push(edge);
            }
        }, this);

        this._focusNodes = focusNodes;
        this._focusEdges = focusEdges;
    },

    unfocusNodeAdjacency: function (seriesModel, ecModel, api, payload) {

        this._downplayAll();

        this._pointsBuilder.fadeInAll();
        this._fadeInEdgesAll();

        this._pointsBuilder.updateLabels();
    },

    _highlightEdge: function (dataIndex) {
        var itemModel = this._model.getEdgeData().getItemModel(dataIndex);
        var emphasisColor =  __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].parseColor(itemModel.get('emphasis.lineStyle.color') || itemModel.get('lineStyle.color'));
        var emphasisOpacity = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(itemModel.get('emphasis.lineStyle.opacity'), itemModel.get('lineStyle.opacity'), 1);
        emphasisColor[3] *= emphasisOpacity;

        this._edgesMesh.geometry.setItemColor(this._edgeIndicesMap[dataIndex], emphasisColor);
    },

    _downplayAll: function () {
        if (this._focusNodes) {
            this._focusNodes.forEach(function (node) {
                this._pointsBuilder.downplay(this._model.getData(), node.dataIndex);
            }, this);
        }
        if (this._focusEdges) {
            this._focusEdges.forEach(function (edge) {
                this._downplayEdge(edge.dataIndex);
            }, this);
        }
    },

    _downplayEdge: function (dataIndex) {
        var color = this._getColor(dataIndex, []);
        this._edgesMesh.geometry.setItemColor(this._edgeIndicesMap[dataIndex], color);
    },

    _setEdgeFade: (function () {
        var color = [];
        return function (dataIndex, percent) {
            this._getColor(dataIndex, color);
            color[3] *= percent;
            this._edgesMesh.geometry.setItemColor(this._edgeIndicesMap[dataIndex], color);
        };
    })(),

    _getColor: function (dataIndex, out) {
        for (var i = 0; i < 4; i++) {
            out[i] = this._originalEdgeColors[dataIndex * 4 + i];
        }
        return out;
    },

    _fadeOutEdgesAll: function (percent) {
        var graph = this._model.getData().graph;

        graph.eachEdge(function (edge) {
            this._setEdgeFade(edge.dataIndex, percent);
        }, this);
    },

    _fadeInEdgesAll: function () {
        this._fadeOutEdgesAll(1);
    },

    _updateCamera: function (seriesModel, api) {
        this.viewGL.setViewport(0, 0, api.getWidth(), api.getHeight(), api.getDevicePixelRatio());
        var camera = this.viewGL.camera;
        var nodeData = seriesModel.getData();
        var points = nodeData.getLayout('points');
        var min = vec2.create(Infinity, Infinity);
        var max = vec2.create(-Infinity, -Infinity);
        var pt = [];
        for (var i = 0; i < points.length;) {
            pt[0] = points[i++];
            pt[1] = points[i++];
            vec2.min(min, min, pt);
            vec2.max(max, max, pt);
        }
        var cy = (max[1] + min[1]) / 2;
        var cx = (max[0] + min[0]) / 2;
        // Only fit the camera when graph is not in the center.
        // PENDING
        if (cx > camera.left && cx < camera.right
            && cy < camera.bottom && cy > camera.top
        ) {
            return;
        }

        // Scale a bit
        var width = Math.max(max[0] - min[0], 10);
        // Keep aspect
        var height = width / api.getWidth() * api.getHeight();
        width *= 1.4;
        height *= 1.4;
        min[0] -= width * 0.2;

        camera.left = min[0];
        camera.top = cy - height / 2;
        camera.bottom = cy + height / 2;
        camera.right = width + min[0];
        camera.near = 0;
        camera.far = 100;
    },

    dispose: function () {
        var renderer = this.viewGL.layer.renderer;
        if (this._forceLayoutInstance) {
            this._forceLayoutInstance.dispose(renderer);
        }
        this.groupGL.removeAll();

        // Stop layout.
        this._layoutId = -1;
    },

    remove: function () {
        this.groupGL.removeAll();
        this._control.dispose();
    }
});

/***/ }),
/* 269 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_compositor_Pass__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__forceAtlas2_glsl_js__ = __webpack_require__(270);






__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_4__forceAtlas2_glsl_js__["a" /* default */]);

var defaultConfigs = {
    repulsionByDegree: true,
    linLogMode: false,

    strongGravityMode: false,
    gravity: 1.0,

    scaling: 1.0,

    edgeWeightInfluence: 1.0,

    jitterTolerence: 0.1,

    preventOverlap: false,

    dissuadeHubs: false,

    gravityCenter: null
};

function ForceAtlas2GPU(options) {

    var textureOpt = {
        type: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture.FLOAT,
        minFilter: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture.NEAREST,
        magFilter: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture.NEAREST
    };

    this._positionSourceTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
    this._positionSourceTex.flipY = false;

    this._positionTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
    this._positionPrevTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
    this._forceTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
    this._forcePrevTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);

    this._weightedSumTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
    this._weightedSumTex.width = this._weightedSumTex.height = 1;

    this._globalSpeedTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
    this._globalSpeedPrevTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
    this._globalSpeedTex.width = this._globalSpeedTex.height = 1;
    this._globalSpeedPrevTex.width = this._globalSpeedPrevTex.height = 1;

    this._nodeRepulsionPass = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.forceAtlas2.updateNodeRepulsion')
    });
    this._positionPass = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.forceAtlas2.updatePosition')
    });
    this._globalSpeedPass = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.forceAtlas2.calcGlobalSpeed')
    });
    this._copyPass = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_compositor_Pass__["a" /* default */]({
        fragment: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('clay.compositor.output')
    });

    var additiveBlend = function (gl) {
        gl.blendEquation(gl.FUNC_ADD);
        gl.blendFunc(gl.ONE, gl.ONE);
    };
    this._edgeForceMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
        geometry: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry({
            attributes: {
                node1: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry.Attribute('node1', 'float', 2),
                node2: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry.Attribute('node2', 'float', 2),
                weight: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry.Attribute('weight', 'float', 1)
            },
            dynamic: true,
            mainAttribute: 'node1'
        }),
        material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
            transparent: true,
            shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.forceAtlas2.updateEdgeAttraction'),
            blend: additiveBlend,
            depthMask: false,
            depthText: false
        }),
        mode: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.POINTS
    });
    this._weightedSumMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
        geometry: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry({
            attributes: {
                node: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry.Attribute('node', 'float', 2)
            },
            dynamic: true,
            mainAttribute: 'node'
        }),
        material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
            transparent: true,
            shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.forceAtlas2.calcWeightedSum'),
            blend: additiveBlend,
            depthMask: false,
            depthText: false
        }),
        mode: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.POINTS
    });

    this._framebuffer = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__["a" /* default */]({
        depthBuffer: false
    });

    this._dummyCamera = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].OrthographicCamera({
        left: -1, right: 1,
        top: 1, bottom: -1,
        near: 0, far: 100
    });

    this._globalSpeed = 0;
}

ForceAtlas2GPU.prototype.updateOption = function (options) {

    // Default config
    for (var name in defaultConfigs) {
        this[name] = defaultConfigs[name];
    }

    // Config according to data scale
    var nNodes = this._nodes.length;
    if (nNodes > 50000) {
        this.jitterTolerence = 10;
    }
    else if (nNodes > 5000) {
        this.jitterTolerence = 1;
    }
    else {
        this.jitterTolerence = 0.1;
    }

    if (nNodes > 100) {
        this.scaling = 2.0;
    }
    else {
        this.scaling = 10.0;
    }

    // this.edgeWeightInfluence = 1;
    // this.gravity = 1;
    // this.strongGravityMode = false;
    if (options) {
        for (var name in defaultConfigs) {
            if (options[name] != null) {
                this[name] = options[name];
            }
        }
    }

    if (this.repulsionByDegree) {
        var positionBuffer = this._positionSourceTex.pixels;

        for (var i = 0; i < this._nodes.length; i++) {
            positionBuffer[i * 4 + 2] = (this._nodes[i].degree || 0) + 1;
        }
    }
};

ForceAtlas2GPU.prototype._updateGravityCenter = function (options) {
    var nodes = this._nodes;
    var edges = this._edges;

    if (!this.gravityCenter) {
        var min = [Infinity, Infinity];
        var max = [-Infinity, -Infinity];
        for (var i = 0; i < nodes.length; i++) {
            min[0] = Math.min(nodes[i].x, min[0]);
            min[1] = Math.min(nodes[i].y, min[1]);
            max[0] = Math.max(nodes[i].x, max[0]);
            max[1] = Math.max(nodes[i].y, max[1]);
        }

        this._gravityCenter = [(min[0] + max[0]) * 0.5, (min[1] + max[1]) * 0.5];
    }
    else {
        this._gravityCenter = this.gravityCenter;
    }
    // Update inDegree, outDegree
    for (var i = 0; i < edges.length; i++) {
        var node1 = edges[i].node1;
        var node2 = edges[i].node2;

        nodes[node1].degree = (nodes[node1].degree || 0) + 1;
        nodes[node2].degree = (nodes[node2].degree || 0) + 1;
    }
};
/**
 * @param {Array.<Object>} [{ x, y, mass }] nodes
 * @param {Array.<Object>} [{ node1, node2, weight }] edges
 */
ForceAtlas2GPU.prototype.initData = function (nodes, edges) {

    this._nodes = nodes;
    this._edges = edges;

    this._updateGravityCenter();

    var textureWidth = Math.ceil(Math.sqrt(nodes.length));
    var textureHeight = textureWidth;
    var positionBuffer = new Float32Array(textureWidth * textureHeight * 4);

    this._resize(textureWidth, textureHeight);

    var offset = 0;
    for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        positionBuffer[offset++] = node.x || 0;
        positionBuffer[offset++] = node.y || 0;
        positionBuffer[offset++] = node.mass || 1;
        positionBuffer[offset++] = node.size || 1;
    }
    this._positionSourceTex.pixels = positionBuffer;

    var edgeGeometry = this._edgeForceMesh.geometry;
    var edgeLen = edges.length;
    edgeGeometry.attributes.node1.init(edgeLen * 2);
    edgeGeometry.attributes.node2.init(edgeLen * 2);
    edgeGeometry.attributes.weight.init(edgeLen * 2);

    var uv = [];

    for (var i = 0; i < edges.length; i++) {
        var attributes = edgeGeometry.attributes;
        var weight = edges[i].weight;
        if (weight == null) {
            weight = 1;
        }
        // Two way.
        attributes.node1.set(i, this.getNodeUV(edges[i].node1, uv));
        attributes.node2.set(i, this.getNodeUV(edges[i].node2, uv));
        attributes.weight.set(i, weight);

        attributes.node1.set(i + edgeLen, this.getNodeUV(edges[i].node2, uv));
        attributes.node2.set(i + edgeLen, this.getNodeUV(edges[i].node1, uv));
        attributes.weight.set(i + edgeLen, weight);
    }

    var weigtedSumGeo = this._weightedSumMesh.geometry;
    weigtedSumGeo.attributes.node.init(nodes.length);
    for (var i = 0; i < nodes.length; i++) {
        weigtedSumGeo.attributes.node.set(i, this.getNodeUV(i, uv));
    }

    edgeGeometry.dirty();
    weigtedSumGeo.dirty();

    this._nodeRepulsionPass.material.define('fragment', 'NODE_COUNT', nodes.length);
    this._nodeRepulsionPass.material.setUniform('textureSize', [textureWidth, textureHeight]);

    this._inited = false;

    this._frame = 0;
};

ForceAtlas2GPU.prototype.getNodes = function () {
    return this._nodes;
};
ForceAtlas2GPU.prototype.getEdges = function () {
    return this._edges;
};

ForceAtlas2GPU.prototype.step = function (renderer) {
    if (!this._inited) {
        this._initFromSource(renderer);
        this._inited = true;
    }

    this._frame++;

    this._framebuffer.attach(this._forceTex);
    this._framebuffer.bind(renderer);
    var nodeRepulsionPass = this._nodeRepulsionPass;
    // Calc node repulsion, gravity
    nodeRepulsionPass.setUniform('strongGravityMode', this.strongGravityMode);
    nodeRepulsionPass.setUniform('gravity', this.gravity);
    nodeRepulsionPass.setUniform('gravityCenter', this._gravityCenter);
    nodeRepulsionPass.setUniform('scaling', this.scaling);
    nodeRepulsionPass.setUniform('preventOverlap', this.preventOverlap);
    nodeRepulsionPass.setUniform('positionTex', this._positionPrevTex);
    nodeRepulsionPass.render(renderer);

    // Calc edge attraction force
    var edgeForceMesh = this._edgeForceMesh;
    edgeForceMesh.material.set('linLogMode', this.linLogMode);
    edgeForceMesh.material.set('edgeWeightInfluence', this.edgeWeightInfluence);
    edgeForceMesh.material.set('preventOverlap', this.preventOverlap);
    edgeForceMesh.material.set('positionTex', this._positionPrevTex);
    renderer.gl.enable(renderer.gl.BLEND);
    renderer.renderPass([edgeForceMesh], this._dummyCamera);

    // Calc weighted sum.
    this._framebuffer.attach(this._weightedSumTex);
    renderer.gl.clearColor(0, 0, 0, 0);
    renderer.gl.clear(renderer.gl.COLOR_BUFFER_BIT);
    renderer.gl.enable(renderer.gl.BLEND);
    var weightedSumMesh = this._weightedSumMesh;
    weightedSumMesh.material.set('positionTex', this._positionPrevTex);
    weightedSumMesh.material.set('forceTex', this._forceTex);
    weightedSumMesh.material.set('forcePrevTex', this._forcePrevTex);
    renderer.renderPass([weightedSumMesh], this._dummyCamera);

    // Calc global speed.
    this._framebuffer.attach(this._globalSpeedTex);
    var globalSpeedPass = this._globalSpeedPass;
    globalSpeedPass.setUniform('globalSpeedPrevTex', this._globalSpeedPrevTex);
    globalSpeedPass.setUniform('weightedSumTex', this._weightedSumTex);
    globalSpeedPass.setUniform('jitterTolerence', this.jitterTolerence);
    renderer.gl.disable(renderer.gl.BLEND);
    globalSpeedPass.render(renderer);

    // Update position.
    var positionPass = this._positionPass;
    this._framebuffer.attach(this._positionTex);
    positionPass.setUniform('globalSpeedTex', this._globalSpeedTex);
    positionPass.setUniform('positionTex', this._positionPrevTex);
    positionPass.setUniform('forceTex', this._forceTex);
    positionPass.setUniform('forcePrevTex', this._forcePrevTex);
    positionPass.render(renderer);

    this._framebuffer.unbind(renderer);

    this._swapTexture();
};

ForceAtlas2GPU.prototype.update = function (renderer, steps, cb) {
    if (steps == null) {
        steps = 1;
    }
    steps = Math.max(steps, 1);

    for (var i = 0; i < steps; i++) {
        this.step(renderer);
    }

    cb && cb();
};

ForceAtlas2GPU.prototype.getNodePositionTexture = function () {
    return this._inited
        // Texture already been swapped.
        ? this._positionPrevTex
        : this._positionSourceTex;
};

ForceAtlas2GPU.prototype.getNodeUV = function (nodeIndex, uv) {
    uv = uv || [];
    var textureWidth = this._positionTex.width;
    var textureHeight = this._positionTex.height;
    uv[0] = (nodeIndex % textureWidth) / (textureWidth - 1);
    uv[1] = Math.floor(nodeIndex / textureWidth) / (textureHeight - 1) || 0;
    return uv;
};

ForceAtlas2GPU.prototype.getNodePosition = function (renderer, out) {
    var positionArr = this._positionArr;
    var width = this._positionTex.width;
    var height = this._positionTex.height;
    var size = width * height;
    if (!positionArr || positionArr.length !== size * 4) {
        positionArr = this._positionArr = new Float32Array(size * 4);
    }
    this._framebuffer.bind(renderer);
    this._framebuffer.attach(this._positionPrevTex);
    renderer.gl.readPixels(
        0, 0, width, height,
        renderer.gl.RGBA, renderer.gl.FLOAT,
        positionArr
    );
    this._framebuffer.unbind(renderer);
    if (!out) {
        out = new Float32Array(this._nodes.length * 2);
    }
    for (var i = 0; i < this._nodes.length; i++) {
        out[i * 2] = positionArr[i * 4];
        out[i * 2 + 1] = positionArr[i * 4 + 1];
    }
    return out;
};

ForceAtlas2GPU.prototype.getTextureData = function (renderer, textureName) {
    var tex = this['_' + textureName + 'Tex'];
    var width = tex.width;
    var height = tex.height;
    this._framebuffer.bind(renderer);
    this._framebuffer.attach(tex);
    var arr = new Float32Array(width * height * 4);
    renderer.gl.readPixels(0, 0, width, height, renderer.gl.RGBA, renderer.gl.FLOAT, arr);
    this._framebuffer.unbind(renderer);
    return arr;
};

ForceAtlas2GPU.prototype.getTextureSize = function () {
    return {
        width: this._positionTex.width,
        height: this._positionTex.height
    };
};

ForceAtlas2GPU.prototype.isFinished = function (maxSteps) {
    return this._frame > maxSteps;
};

ForceAtlas2GPU.prototype._swapTexture = function () {
    var tmp = this._positionPrevTex;
    this._positionPrevTex = this._positionTex;
    this._positionTex = tmp;

    var tmp = this._forcePrevTex;
    this._forcePrevTex = this._forceTex;
    this._forceTex = tmp;

    var tmp = this._globalSpeedPrevTex;
    this._globalSpeedPrevTex = this._globalSpeedTex;
    this._globalSpeedTex = tmp;
};

ForceAtlas2GPU.prototype._initFromSource = function (renderer) {
    this._framebuffer.attach(this._positionPrevTex);
    this._framebuffer.bind(renderer);
    this._copyPass.setUniform('texture', this._positionSourceTex);
    this._copyPass.render(renderer);

    renderer.gl.clearColor(0, 0, 0, 0);
    this._framebuffer.attach(this._forcePrevTex);
    renderer.gl.clear(renderer.gl.COLOR_BUFFER_BIT);
    this._framebuffer.attach(this._globalSpeedPrevTex);
    renderer.gl.clear(renderer.gl.COLOR_BUFFER_BIT);

    this._framebuffer.unbind(renderer);
};

ForceAtlas2GPU.prototype._resize = function (width, height) {
    ['_positionSourceTex', '_positionTex', '_positionPrevTex', '_forceTex', '_forcePrevTex'].forEach(function (texName) {
        this[texName].width = width;
        this[texName].height = height;
        this[texName].dirty();
    }, this);
};

ForceAtlas2GPU.prototype.dispose = function (renderer) {
    this._framebuffer.dispose(renderer);

    this._copyPass.dispose(renderer);
    this._nodeRepulsionPass.dispose(renderer);
    this._positionPass.dispose(renderer);
    this._globalSpeedPass.dispose(renderer);

    this._edgeForceMesh.geometry.dispose(renderer);
    this._weightedSumMesh.geometry.dispose(renderer);

    this._positionSourceTex.dispose(renderer);
    this._positionTex.dispose(renderer);
    this._positionPrevTex.dispose(renderer);
    this._forceTex.dispose(renderer);
    this._forcePrevTex.dispose(renderer);
    this._weightedSumTex.dispose(renderer);
    this._globalSpeedTex.dispose(renderer);
    this._globalSpeedPrevTex.dispose(renderer);
};

__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.ForceAtlas2GPU = ForceAtlas2GPU;

/* harmony default export */ __webpack_exports__["a"] = (ForceAtlas2GPU);

/***/ }),
/* 270 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.forceAtlas2.updateNodeRepulsion\n\n#define NODE_COUNT 0\n\nuniform sampler2D positionTex;\n\nuniform vec2 textureSize;\nuniform float gravity;\nuniform float scaling;\nuniform vec2 gravityCenter;\n\nuniform bool strongGravityMode;\nuniform bool preventOverlap;\n\nvarying vec2 v_Texcoord;\n\nvoid main() {\n\n vec4 n0 = texture2D(positionTex, v_Texcoord);\n\n vec2 force = vec2(0.0);\n for (int i = 0; i < NODE_COUNT; i++) {\n vec2 uv = vec2(\n mod(float(i), textureSize.x) / (textureSize.x - 1.0),\n floor(float(i) / textureSize.x) / (textureSize.y - 1.0)\n );\n vec4 n1 = texture2D(positionTex, uv);\n\n vec2 dir = n0.xy - n1.xy;\n float d2 = dot(dir, dir);\n\n if (d2 > 0.0) {\n float factor = 0.0;\n if (preventOverlap) {\n float d = sqrt(d2);\n d = d - n0.w - n1.w;\n if (d > 0.0) {\n factor = scaling * n0.z * n1.z / (d * d);\n }\n else if (d < 0.0) {\n factor = scaling * 100.0 * n0.z * n1.z;\n }\n }\n else {\n factor = scaling * n0.z * n1.z / d2;\n }\n force += dir * factor;\n }\n }\n\n vec2 dir = gravityCenter - n0.xy;\n float d = 1.0;\n if (!strongGravityMode) {\n d = length(dir);\n }\n\n force += dir * n0.z * gravity / (d + 1.0);\n\n gl_FragColor = vec4(force, 0.0, 1.0);\n}\n@end\n\n@export ecgl.forceAtlas2.updateEdgeAttraction.vertex\n\nattribute vec2 node1;\nattribute vec2 node2;\nattribute float weight;\n\nuniform sampler2D positionTex;\nuniform float edgeWeightInfluence;\nuniform bool preventOverlap;\nuniform bool linLogMode;\n\nuniform vec2 windowSize: WINDOW_SIZE;\n\nvarying vec2 v_Force;\n\nvoid main() {\n\n vec4 n0 = texture2D(positionTex, node1);\n vec4 n1 = texture2D(positionTex, node2);\n\n vec2 dir = n1.xy - n0.xy;\n float d = length(dir);\n float w;\n if (edgeWeightInfluence == 0.0) {\n w = 1.0;\n }\n else if (edgeWeightInfluence == 1.0) {\n w = weight;\n }\n else {\n w = pow(weight, edgeWeightInfluence);\n }\n vec2 offset = vec2(1.0 / windowSize.x, 1.0 / windowSize.y);\n vec2 scale = vec2((windowSize.x - 1.0) / windowSize.x, (windowSize.y - 1.0) / windowSize.y);\n vec2 pos = node1 * scale * 2.0 - 1.0;\n gl_Position = vec4(pos + offset, 0.0, 1.0);\n gl_PointSize = 1.0;\n\n float factor;\n if (preventOverlap) {\n d = d - n1.w - n0.w;\n }\n if (d <= 0.0) {\n v_Force = vec2(0.0);\n return;\n }\n\n if (linLogMode) {\n factor = w * log(d) / d;\n }\n else {\n factor = w;\n }\n v_Force = dir * factor;\n}\n@end\n\n@export ecgl.forceAtlas2.updateEdgeAttraction.fragment\n\nvarying vec2 v_Force;\n\nvoid main() {\n gl_FragColor = vec4(v_Force, 0.0, 0.0);\n}\n@end\n\n@export ecgl.forceAtlas2.calcWeightedSum.vertex\n\nattribute vec2 node;\n\nvarying vec2 v_NodeUv;\n\nvoid main() {\n\n v_NodeUv = node;\n gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n gl_PointSize = 1.0;\n}\n@end\n\n@export ecgl.forceAtlas2.calcWeightedSum.fragment\n\nvarying vec2 v_NodeUv;\n\nuniform sampler2D positionTex;\nuniform sampler2D forceTex;\nuniform sampler2D forcePrevTex;\n\nvoid main() {\n vec2 force = texture2D(forceTex, v_NodeUv).rg;\n vec2 forcePrev = texture2D(forcePrevTex, v_NodeUv).rg;\n\n float mass = texture2D(positionTex, v_NodeUv).z;\n float swing = length(force - forcePrev) * mass;\n float traction = length(force + forcePrev) * 0.5 * mass;\n\n gl_FragColor = vec4(swing, traction, 0.0, 0.0);\n}\n@end\n\n@export ecgl.forceAtlas2.calcGlobalSpeed\n\nuniform sampler2D globalSpeedPrevTex;\nuniform sampler2D weightedSumTex;\nuniform float jitterTolerence;\n\nvoid main() {\n vec2 weightedSum = texture2D(weightedSumTex, vec2(0.5)).xy;\n float prevGlobalSpeed = texture2D(globalSpeedPrevTex, vec2(0.5)).x;\n float globalSpeed = jitterTolerence * jitterTolerence\n * weightedSum.y / weightedSum.x;\n if (prevGlobalSpeed > 0.0) {\n globalSpeed = min(globalSpeed / prevGlobalSpeed, 1.5) * prevGlobalSpeed;\n }\n gl_FragColor = vec4(globalSpeed, 0.0, 0.0, 1.0);\n}\n@end\n\n@export ecgl.forceAtlas2.updatePosition\n\nuniform sampler2D forceTex;\nuniform sampler2D forcePrevTex;\nuniform sampler2D positionTex;\nuniform sampler2D globalSpeedTex;\n\nvarying vec2 v_Texcoord;\n\nvoid main() {\n vec2 force = texture2D(forceTex, v_Texcoord).xy;\n vec2 forcePrev = texture2D(forcePrevTex, v_Texcoord).xy;\n vec4 node = texture2D(positionTex, v_Texcoord);\n\n float globalSpeed = texture2D(globalSpeedTex, vec2(0.5)).r;\n float swing = length(force - forcePrev);\n float speed = 0.1 * globalSpeed / (0.1 + globalSpeed * sqrt(swing));\n\n float df = length(force);\n if (df > 0.0) {\n speed = min(df * speed, 10.0) / df;\n\n gl_FragColor = vec4(node.xy + speed * force, node.zw);\n }\n else {\n gl_FragColor = node;\n }\n}\n@end\n\n@export ecgl.forceAtlas2.edges.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nattribute vec2 node;\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n\nuniform sampler2D positionTex;\n\nvoid main()\n{\n gl_Position = worldViewProjection * vec4(\n texture2D(positionTex, node).xy, -10.0, 1.0\n );\n v_Color = a_Color;\n}\n@end\n\n@export ecgl.forceAtlas2.edges.fragment\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\nvarying vec4 v_Color;\nvoid main() {\n gl_FragColor = color * v_Color;\n}\n@end");


/***/ }),
/* 271 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__forceAtlas2Worker_js__ = __webpack_require__(272);



var workerUrl = __WEBPACK_IMPORTED_MODULE_2__forceAtlas2Worker_js__["a" /* default */].toString();
workerUrl = workerUrl.slice(workerUrl.indexOf('{') + 1, workerUrl.lastIndexOf('}'));

var defaultConfigs = {

    barnesHutOptimize: true,
    barnesHutTheta: 1.5,

    repulsionByDegree: true,
    linLogMode: false,

    strongGravityMode: false,
    gravity: 1.0,

    scaling: 1.0,

    edgeWeightInfluence: 1.0,

    jitterTolerence: 0.1,

    preventOverlap: false,

    dissuadeHubs: false,

    gravityCenter: null
};

var ForceAtlas2 = function (options) {

    for (var name in defaultConfigs) {
        this[name] = defaultConfigs[name];
    }

    if (options) {
        for (var name in options) {
            this[name] = options[name];
        }
    }

    this._nodes = [];
    this._edges = [];

    this._disposed = false;

    this._positionTex = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__["a" /* default */]({
        type: __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__["a" /* default */].FLOAT,
        flipY: false,
        minFilter: __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__["a" /* default */].NEAREST,
        magFilter: __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__["a" /* default */].NEAREST
    });
};

ForceAtlas2.prototype.initData = function (nodes, edges) {

    var bb = new Blob([workerUrl]);
    var blobURL = window.URL.createObjectURL(bb);

    this._worker = new Worker(blobURL);

    this._worker.onmessage = this._$onupdate.bind(this);

    this._nodes = nodes;
    this._edges = edges;
    this._frame = 0;

    var nNodes = nodes.length;
    var nEdges = edges.length;

    var positionArr = new Float32Array(nNodes * 2);
    var massArr = new Float32Array(nNodes);
    var sizeArr = new Float32Array(nNodes);

    var edgeArr = new Float32Array(nEdges * 2);
    var edgeWeightArr = new Float32Array(nEdges);

    for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];

        positionArr[i * 2] = node.x;
        positionArr[i * 2 + 1] = node.y;

        massArr[i] = node.mass == null ? 1 : node.mass;
        sizeArr[i] = node.size == null ? 1 : node.size;
    }

    for (var i = 0; i < edges.length; i++) {
        var edge = edges[i];

        var source = edge.node1;
        var target = edge.node2;

        edgeArr[i * 2] = source;
        edgeArr[i * 2 + 1] = target;

        edgeWeightArr[i] = edge.weight == null ? 1 : edge.weight;
    }


    var textureWidth = Math.ceil(Math.sqrt(nodes.length));
    var textureHeight = textureWidth;
    var pixels = new Float32Array(textureWidth * textureHeight * 4);
    var positionTex = this._positionTex;
    positionTex.width = textureWidth;
    positionTex.height = textureHeight;
    positionTex.pixels = pixels;

    this._worker.postMessage({
        cmd: 'init',
        nodesPosition: positionArr,
        nodesMass: massArr,
        nodesSize: sizeArr,
        edges: edgeArr,
        edgesWeight: edgeWeightArr
    });

    this._globalSpeed = Infinity;
};

ForceAtlas2.prototype.updateOption = function (options) {
    var config = {};
    // Default config
    for (var name in defaultConfigs) {
        config[name] = defaultConfigs[name];
    }

    var nodes = this._nodes;
    var edges = this._edges;

    // Config according to data scale
    var nNodes = nodes.length;
    if (nNodes > 50000) {
        config.jitterTolerence = 10;
    }
    else if (nNodes > 5000) {
        config.jitterTolerence = 1;
    }
    else {
        config.jitterTolerence = 0.1;
    }

    if (nNodes > 100) {
        config.scaling = 2.0;
    }
    else {
        config.scaling = 10.0;
    }
    if (nNodes > 1000) {
        config.barnesHutOptimize = true;
    }
    else {
        config.barnesHutOptimize = false;
    }

    if (options) {
        for (var name in defaultConfigs) {
            if (options[name] != null) {
                config[name] = options[name];
            }
        }
    }

    if (!config.gravityCenter) {
        var min = [Infinity, Infinity];
        var max = [-Infinity, -Infinity];
        for (var i = 0; i < nodes.length; i++) {
            min[0] = Math.min(nodes[i].x, min[0]);
            min[1] = Math.min(nodes[i].y, min[1]);
            max[0] = Math.max(nodes[i].x, max[0]);
            max[1] = Math.max(nodes[i].y, max[1]);
        }

        config.gravityCenter = [(min[0] + max[0]) * 0.5, (min[1] + max[1]) * 0.5];
    }

    // Update inDegree, outDegree
    for (var i = 0; i < edges.length; i++) {
        var node1 = edges[i].node1;
        var node2 = edges[i].node2;

        nodes[node1].degree = (nodes[node1].degree || 0) + 1;
        nodes[node2].degree = (nodes[node2].degree || 0) + 1;
    }

    if (this._worker) {
        this._worker.postMessage({
            cmd: 'updateConfig',
            config: config
        });
    }
};

// Steps per call, to keep sync with rendering
ForceAtlas2.prototype.update = function (renderer, steps, cb) {
    if (steps == null) {
        steps = 1;
    }
    steps = Math.max(steps, 1);

    this._frame += steps;
    this._onupdate = cb;

    if (this._worker) {
        this._worker.postMessage({
            cmd: 'update',
            steps: Math.round(steps)
        });
    }
};

ForceAtlas2.prototype._$onupdate = function (e) {
    // Incase the worker keep postMessage of last frame after it is disposed
    if (this._disposed) {
        return;
    }

    var positionArr = new Float32Array(e.data.buffer);
    this._globalSpeed = e.data.globalSpeed;

    this._positionArr = positionArr;

    this._updateTexture(positionArr);

    this._onupdate && this._onupdate();
};

ForceAtlas2.prototype.getNodePositionTexture = function () {
    return this._positionTex;
};

ForceAtlas2.prototype.getNodeUV = function (nodeIndex, uv) {
    uv = uv || [];
    var textureWidth = this._positionTex.width;
    var textureHeight = this._positionTex.height;
    uv[0] = (nodeIndex % textureWidth) / (textureWidth - 1);
    uv[1] = Math.floor(nodeIndex / textureWidth) / (textureHeight - 1);
    return uv;
};

ForceAtlas2.prototype.getNodes = function () {
    return this._nodes;
};
ForceAtlas2.prototype.getEdges = function () {
    return this._edges;
};
ForceAtlas2.prototype.isFinished = function (maxSteps) {
    return this._frame > maxSteps;
};

ForceAtlas2.prototype.getNodePosition = function (renderer, out) {
    if (!out) {
        out = new Float32Array(this._nodes.length * 2);
    }
    if (this._positionArr) {
        for (var i = 0; i < this._positionArr.length; i++) {
            out[i] = this._positionArr[i];
        }
    }
    return out;
};

ForceAtlas2.prototype._updateTexture = function (positionArr) {
    var pixels = this._positionTex.pixels;
    var offset = 0;
    for (var i = 0; i < positionArr.length;){
        pixels[offset++] = positionArr[i++];
        pixels[offset++] = positionArr[i++];
        pixels[offset++] = 1;
        pixels[offset++] = 1;
    }
    this._positionTex.dirty();
};

ForceAtlas2.prototype.dispose = function (renderer) {
    this._disposed = true;
    this._worker = null;
};

/* harmony default export */ __webpack_exports__["a"] = (ForceAtlas2);

/***/ }),
/* 272 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/****************************
 * Vector2 math functions
 ***************************/

function forceAtlas2Worker() {
    var vec2 = {
        create: function() {
            return new Float32Array(2);
        },
        dist: function(a, b) {
            var x = b[0] - a[0];
            var y = b[1] - a[1];
            return Math.sqrt(x*x + y*y);
        },
        len: function(a) {
            var x = a[0];
            var y = a[1];
            return Math.sqrt(x*x + y*y);
        },
        scaleAndAdd: function(out, a, b, scale) {
            out[0] = a[0] + b[0] * scale;
            out[1] = a[1] + b[1] * scale;
            return out;
        },
        scale: function(out, a, b) {
            out[0] = a[0] * b;
            out[1] = a[1] * b;
            return out;
        },
        add: function(out, a, b) {
            out[0] = a[0] + b[0];
            out[1] = a[1] + b[1];
            return out;
        },
        sub: function(out, a, b) {
            out[0] = a[0] - b[0];
            out[1] = a[1] - b[1];
            return out;
        },
        normalize: function(out, a) {
            var x = a[0];
            var y = a[1];
            var len = x*x + y*y;
            if (len > 0) {
                //TODO: evaluate use of glm_invsqrt here?
                len = 1 / Math.sqrt(len);
                out[0] = a[0] * len;
                out[1] = a[1] * len;
            }
            return out;
        },
        negate: function(out, a) {
            out[0] = -a[0];
            out[1] = -a[1];
            return out;
        },
        copy: function(out, a) {
            out[0] = a[0];
            out[1] = a[1];
            return out;
        },
        set: function(out, x, y) {
            out[0] = x;
            out[1] = y;
            return out;
        }
    }

    /****************************
     * Class: Region
     ***************************/

    function Region() {

        this.subRegions = [];

        this.nSubRegions = 0;

        this.node = null;

        this.mass = 0;

        this.centerOfMass = null;

        this.bbox = new Float32Array(4);

        this.size = 0;
    }

    var regionProto = Region.prototype;

    // Reset before update
    regionProto.beforeUpdate = function() {
        for (var i = 0; i < this.nSubRegions; i++) {
            this.subRegions[i].beforeUpdate();
        }
        this.mass = 0;
        if (this.centerOfMass) {
            this.centerOfMass[0] = 0;
            this.centerOfMass[1] = 0;
        }
        this.nSubRegions = 0;
        this.node = null;
    };
    // Clear after update
    regionProto.afterUpdate = function() {
        this.subRegions.length = this.nSubRegions;
        for (var i = 0; i < this.nSubRegions; i++) {
            this.subRegions[i].afterUpdate();
        }
    };

    regionProto.addNode = function(node) {
        if (this.nSubRegions === 0) {
            if (this.node == null) {
                this.node = node;
                return;
            }
            // Already have node, subdivide self.
            else {
                this._addNodeToSubRegion(this.node);
                this.node = null;
            }
        }
        this._addNodeToSubRegion(node);

        this._updateCenterOfMass(node);
    };

    regionProto.findSubRegion = function(x, y) {
        for (var i = 0; i < this.nSubRegions; i++) {
            var region = this.subRegions[i];
            if (region.contain(x, y)) {
                return region;
            }
        }
    };

    regionProto.contain = function(x, y) {
        return this.bbox[0] <= x
            && this.bbox[2] >= x
            && this.bbox[1] <= y
            && this.bbox[3] >= y;
    };

    regionProto.setBBox = function(minX, minY, maxX, maxY) {
        // Min
        this.bbox[0] = minX;
        this.bbox[1] = minY;
        // Max
        this.bbox[2] = maxX;
        this.bbox[3] = maxY;

        this.size = (maxX - minX + maxY - minY) / 2;
    };

    regionProto._newSubRegion = function() {
        var subRegion = this.subRegions[this.nSubRegions];
        if (!subRegion) {
            subRegion = new Region();
            this.subRegions[this.nSubRegions] = subRegion;
        }
        this.nSubRegions++;
        return subRegion;
    };

    regionProto._addNodeToSubRegion = function(node) {
        var subRegion = this.findSubRegion(node.position[0], node.position[1]);
        var bbox = this.bbox;
        if (!subRegion) {
            var cx = (bbox[0] + bbox[2]) / 2;
            var cy = (bbox[1] + bbox[3]) / 2;
            var w = (bbox[2] - bbox[0]) / 2;
            var h = (bbox[3] - bbox[1]) / 2;

            var xi = node.position[0] >= cx ? 1 : 0;
            var yi = node.position[1] >= cy ? 1 : 0;

            var subRegion = this._newSubRegion();
            // Min
            subRegion.setBBox(
                // Min
                xi * w + bbox[0],
                yi * h + bbox[1],
                // Max
                (xi + 1) * w + bbox[0],
                (yi + 1) * h + bbox[1]
            );
        }

        subRegion.addNode(node);
    };

    regionProto._updateCenterOfMass = function(node) {
        // Incrementally update
        if (this.centerOfMass == null) {
            this.centerOfMass = new Float32Array(2);
        }
        var x = this.centerOfMass[0] * this.mass;
        var y = this.centerOfMass[1] * this.mass;
        x += node.position[0] * node.mass;
        y += node.position[1] * node.mass;
        this.mass += node.mass;
        this.centerOfMass[0] = x / this.mass;
        this.centerOfMass[1] = y / this.mass;
    };

    /****************************
     * Class: Graph Node
     ***************************/
    function GraphNode() {
        this.position = new Float32Array(2);

        this.force = vec2.create();
        this.forcePrev = vec2.create();

        // If repulsionByDegree is true
        //  mass = inDegree + outDegree + 1
        // Else
        //  mass is manually set
        this.mass = 1;

        this.inDegree = 0;
        this.outDegree = 0;

        // Optional
        // this.size = 1;
    }

    /****************************
     * Class: Graph Edge
     ***************************/
    function GraphEdge(source, target) {
        this.source = source;
        this.target = target;

        this.weight = 1;
    }

    /****************************
     * Class: ForceStlas2
     ***************************/
    function ForceAtlas2() {
        //-------------
        // Configs

        // If auto settings is true
        //  barnesHutOptimize,
        //  barnesHutTheta,
        //  scaling,
        //  jitterTolerence
        // Will be set by the system automatically
        //  preventOverlap will be set false
        //  if node size is not given
        this.autoSettings = true;

        // Barnes Hut
        // http://arborjs.org/docs/barnes-hut
        this.barnesHutOptimize = true;
        this.barnesHutTheta = 1.5;

        // Force Atlas2 Configs
        this.repulsionByDegree = true;

        this.linLogMode = false;

        this.strongGravityMode = false;
        this.gravity = 1.0;

        this.scaling = 1.0;

        this.edgeWeightInfluence = 1.0;
        this.jitterTolerence = 0.1;

        // TODO
        this.preventOverlap = false;
        this.dissuadeHubs = false;

        //
        this.rootRegion = new Region();
        this.rootRegion.centerOfMass = vec2.create();

        this.nodes = [];

        this.edges = [];

        this.bbox = new Float32Array(4);

        this.gravityCenter = null;

        this._massArr = null;

        this._swingingArr = null;

        this._sizeArr = null;

        this._globalSpeed = 0;
    }

    var forceAtlas2Proto = ForceAtlas2.prototype;

    forceAtlas2Proto.initNodes = function(positionArr, massArr, sizeArr) {
        var nNodes = massArr.length;
        this.nodes.length = 0;
        var haveSize = typeof(sizeArr) != 'undefined';
        for (var i = 0; i < nNodes; i++) {
            var node = new GraphNode();
            node.position[0] = positionArr[i * 2];
            node.position[1] = positionArr[i * 2 + 1];
            node.mass = massArr[i];
            if (haveSize) {
                node.size = sizeArr[i];
            }
            this.nodes.push(node);
        }

        this._massArr = massArr;
        this._swingingArr = new Float32Array(nNodes);

        if (haveSize) {
            this._sizeArr = sizeArr;
        }
    };

    forceAtlas2Proto.initEdges = function(edgeArr, edgeWeightArr) {
        var nEdges = edgeArr.length / 2;
        this.edges.length = 0;
        for (var i = 0; i < nEdges; i++) {
            var sIdx = edgeArr[i * 2];
            var tIdx = edgeArr[i * 2 + 1];
            var sNode = this.nodes[sIdx];
            var tNode = this.nodes[tIdx];

            if (!sNode || !tNode) {
                console.error('Node not exists, try initNodes before initEdges');
                return;
            }
            sNode.outDegree++;
            tNode.inDegree++;
            var edge = new GraphEdge(sNode, tNode);

            if (edgeWeightArr) {
                edge.weight = edgeWeightArr[i];
            }

            this.edges.push(edge);
        }
    }

    forceAtlas2Proto.updateSettings = function() {
        if (this.repulsionByDegree) {
            for (var i = 0; i < this.nodes.length; i++) {
                var node = this.nodes[i];
                node.mass = node.inDegree + node.outDegree + 1;
            }
        }
        else {
            for (var i = 0; i < this.nodes.length; i++) {
                var node = this.nodes[i];
                node.mass = this._massArr[i];
            }
        }
    };

    forceAtlas2Proto.update = function() {
        var nNodes = this.nodes.length;

        this.updateSettings();

        this.updateBBox();

        // Update region
        if (this.barnesHutOptimize) {
            this.rootRegion.setBBox(
                this.bbox[0], this.bbox[1],
                this.bbox[2], this.bbox[3]
            );

            this.rootRegion.beforeUpdate();
            for (var i = 0; i < nNodes; i++) {
                this.rootRegion.addNode(this.nodes[i]);
            }
            this.rootRegion.afterUpdate();
        }

        // Reset forces
        for (var i = 0; i < nNodes; i++) {
            var node = this.nodes[i];
            vec2.copy(node.forcePrev, node.force);
            vec2.set(node.force, 0, 0);
        }

        // Compute forces
        // Repulsion
        for (var i = 0; i < nNodes; i++) {
            var na = this.nodes[i];
            if (this.barnesHutOptimize) {
                this.applyRegionToNodeRepulsion(this.rootRegion, na);
            }
            else {
                for (var j = i + 1; j < nNodes; j++) {
                    var nb = this.nodes[j];
                    this.applyNodeToNodeRepulsion(na, nb, false);
                }
            }

            // Gravity
            if (this.gravity > 0) {
                if (this.strongGravityMode) {
                    this.applyNodeStrongGravity(na);
                }
                else {
                    this.applyNodeGravity(na);
                }
            }
        }

        // Attraction
        for (var i = 0; i < this.edges.length; i++) {
            this.applyEdgeAttraction(this.edges[i]);
        }

        // Handle swinging
        var swingWeightedSum = 0;
        var tractionWeightedSum = 0;
        var tmp = vec2.create();
        for (var i = 0; i < nNodes; i++) {
            var node = this.nodes[i];
            var swing = vec2.dist(node.force, node.forcePrev);
            swingWeightedSum += swing * node.mass;

            vec2.add(tmp, node.force, node.forcePrev);
            var traction = vec2.len(tmp) * 0.5;
            tractionWeightedSum += traction * node.mass;

            // Save the value for using later
            this._swingingArr[i] = swing;
        }
        var globalSpeed = this.jitterTolerence * this.jitterTolerence
                        * tractionWeightedSum / swingWeightedSum;
        // NB: During our tests we observed that an excessive rise of the global speed could have a negative impact.
        // That’s why we limited the increase of global speed s(t)(G) to 50% of the previous step s(t−1)(G).
        if (this._globalSpeed > 0) {
            globalSpeed = Math.min(globalSpeed / this._globalSpeed, 1.5) * this._globalSpeed;
        }
        this._globalSpeed = globalSpeed;

        // Apply forces
        for (var i = 0; i < nNodes; i++) {
            var node = this.nodes[i];
            var swing = this._swingingArr[i];

            var speed = 0.1 * globalSpeed / (1 + globalSpeed * Math.sqrt(swing));

            // Additional constraint to prevent local speed gets too high
            var df = vec2.len(node.force);
            if (df > 0) {
                speed = Math.min(df * speed, 10) / df;
                vec2.scaleAndAdd(node.position, node.position, node.force, speed);
            }
        }
    };

    forceAtlas2Proto.applyRegionToNodeRepulsion = (function() {
        var v = vec2.create();
        return function applyRegionToNodeRepulsion(region, node) {
            if (region.node) { // Region is a leaf
                this.applyNodeToNodeRepulsion(region.node, node, true);
            }
            else {
                vec2.sub(v, node.position, region.centerOfMass);
                var d2 = v[0] * v[0] + v[1] * v[1];
                if (d2 > this.barnesHutTheta * region.size * region.size) {
                    var factor = this.scaling * node.mass * region.mass / d2;
                    vec2.scaleAndAdd(node.force, node.force, v, factor);
                }
                else {
                    for (var i = 0; i < region.nSubRegions; i++) {
                        this.applyRegionToNodeRepulsion(region.subRegions[i], node);
                    }
                }
            }
        }
    })();

    forceAtlas2Proto.applyNodeToNodeRepulsion = (function() {
        var v = vec2.create();
        return function applyNodeToNodeRepulsion(na, nb, oneWay) {
            if (na == nb) {
                return;
            }
            vec2.sub(v, na.position, nb.position);
            var d2 = v[0] * v[0] + v[1] * v[1];

            // PENDING
            if (d2 === 0) {
                return;
            }

            var factor;
            if (this.preventOverlap) {
                var d = Math.sqrt(d2);
                d = d - na.size - nb.size;
                if (d > 0) {
                    factor = this.scaling * na.mass * nb.mass / (d * d);
                }
                else if (d < 0) {
                    // A stronger repulsion if overlap
                    factor = this.scaling * 100 * na.mass * nb.mass;
                }
                else {
                    // No repulsion
                    return;
                }
            }
            else {
                // Divide factor by an extra `d` to normalize the `v`
                factor = this.scaling * na.mass * nb.mass / d2;
            }

            vec2.scaleAndAdd(na.force, na.force, v, factor);
            vec2.scaleAndAdd(nb.force, nb.force, v, -factor);
        }
    })();

    forceAtlas2Proto.applyEdgeAttraction = (function() {
        var v = vec2.create();
        return function applyEdgeAttraction(edge) {
            var na = edge.source;
            var nb = edge.target;

            vec2.sub(v, na.position, nb.position);
            var d = vec2.len(v);

            var w;
            if (this.edgeWeightInfluence === 0) {
                w = 1;
            }
            else if (this.edgeWeightInfluence === 1) {
                w = edge.weight;
            }
            else {
                w = Math.pow(edge.weight, this.edgeWeightInfluence);
            }

            var factor;

            if (this.preventOverlap) {
                d = d - na.size - nb.size;
                if (d <= 0) {
                    // No attraction
                    return;
                }
            }

            if (this.linLogMode) {
                // Divide factor by an extra `d` to normalize the `v`
                factor = - w * Math.log(d + 1) / (d + 1);
            }
            else {
                factor = - w;
            }
            vec2.scaleAndAdd(na.force, na.force, v, factor);
            vec2.scaleAndAdd(nb.force, nb.force, v, -factor);
        }
    })();

    forceAtlas2Proto.applyNodeGravity = (function() {
        var v = vec2.create();
        return function(node) {
            vec2.sub(v, this.gravityCenter, node.position);
            var d = vec2.len(v);
            vec2.scaleAndAdd(node.force, node.force, v, this.gravity * node.mass / (d + 1));
        }
    })();

    forceAtlas2Proto.applyNodeStrongGravity = (function() {
        var v = vec2.create();
        return function(node) {
            vec2.sub(v, this.gravityCenter, node.position);
            vec2.scaleAndAdd(node.force, node.force, v, this.gravity * node.mass);
        }
    })();

    forceAtlas2Proto.updateBBox = function() {
        var minX = Infinity;
        var minY = Infinity;
        var maxX = -Infinity;
        var maxY = -Infinity;
        for (var i = 0; i < this.nodes.length; i++) {
            var pos = this.nodes[i].position;
            minX = Math.min(minX, pos[0]);
            minY = Math.min(minY, pos[1]);
            maxX = Math.max(maxX, pos[0]);
            maxY = Math.max(maxY, pos[1]);
        }
        this.bbox[0] = minX;
        this.bbox[1] = minY;
        this.bbox[2] = maxX;
        this.bbox[3] = maxY;
    };

    forceAtlas2Proto.getGlobalSpeed = function () {
        return this._globalSpeed;
    }

    /****************************
     * Main process
     ***************************/

    var forceAtlas2 = null;

    self.onmessage = function(e) {
        switch(e.data.cmd) {
            case 'init':
                forceAtlas2 = new ForceAtlas2();
                forceAtlas2.initNodes(e.data.nodesPosition, e.data.nodesMass, e.data.nodesSize);
                forceAtlas2.initEdges(e.data.edges, e.data.edgesWeight);
                break;
            case 'updateConfig':
                if (forceAtlas2) {
                    for (var name in e.data.config) {
                        forceAtlas2[name] = e.data.config[name];
                    }
                }
                break;
            case 'update':
                var steps = e.data.steps;
                if (forceAtlas2) {
                    for (var i = 0; i < steps; i++) {
                        forceAtlas2.update();
                    }

                    var nNodes = forceAtlas2.nodes.length;
                    var positionArr = new Float32Array(nNodes * 2);
                    // Callback
                    for (var i = 0; i < nNodes; i++) {
                        var node = forceAtlas2.nodes[i];
                        positionArr[i * 2] = node.position[0];
                        positionArr[i * 2 + 1] = node.position[1];
                    }
                    self.postMessage({
                        buffer: positionArr.buffer,
                        globalSpeed: forceAtlas2.getGlobalSpeed()
                    }, [positionArr.buffer]);
                }
                else {
                    // Not initialzied yet
                    var emptyArr = new Float32Array();
                    // Post transfer object
                    self.postMessage({
                        buffer: emptyArr.buffer,
                        globalSpeed: forceAtlas2.getGlobalSpeed()
                    }, [emptyArr.buffer]);
                }
                break;
        }
    }
}

/* harmony default export */ __webpack_exports__["a"] = (forceAtlas2Worker);

/***/ }),
/* 273 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_core_Base__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__retrieve__ = __webpack_require__(2);




/**
 * @alias module:echarts-gl/util/Roam2DControl
 */
var Roam2DControl = __WEBPACK_IMPORTED_MODULE_0_claygl_src_core_Base__["a" /* default */].extend(function () {

    return {
        /**
         * @type {module:zrender~ZRender}
         */
        zr: null,

        /**
         * @type {module:echarts-gl/core/ViewGL}
         */
        viewGL: null,

        minZoom: 0.2,

        maxZoom: 5,

        _needsUpdate: false,

        _dx: 0,
        _dy: 0,

        _zoom: 1
    };
}, function () {
    // Each Roam2DControl has it's own handler
    this._mouseDownHandler = this._mouseDownHandler.bind(this);
    this._mouseWheelHandler = this._mouseWheelHandler.bind(this);
    this._mouseMoveHandler = this._mouseMoveHandler.bind(this);
    this._mouseUpHandler = this._mouseUpHandler.bind(this);
    this._update = this._update.bind(this);
}, {

    init: function () {
        var zr = this.zr;

        zr.on('mousedown', this._mouseDownHandler);
        zr.on('mousewheel', this._mouseWheelHandler);
        zr.on('globalout', this._mouseUpHandler);

        zr.animation.on('frame', this._update);
    },

    setTarget: function (target) {
        this._target = target;
    },

    setZoom: function (zoom) {
        this._zoom = Math.max(Math.min(
            zoom, this.maxZoom
        ), this.minZoom);
        this._needsUpdate = true;
    },

    setOffset: function (offset) {
        this._dx = offset[0];
        this._dy = offset[1];

        this._needsUpdate = true;
    },

    getZoom: function () {
        return this._zoom;
    },

    getOffset: function () {
        return [this._dx, this._dy];
    },

    _update: function () {
        if (!this._target) {
            return;
        }
        if (!this._needsUpdate) {
            return;
        }

        var target = this._target;

        var scale = this._zoom;

        target.position.x = this._dx;
        target.position.y = this._dy;

        target.scale.set(scale, scale, scale);

        this.zr.refresh();

        this._needsUpdate = false;

        this.trigger('update');
    },

    _mouseDownHandler: function (e) {
        if (e.target) {
            return;
        }

        var x = e.offsetX;
        var y = e.offsetY;
        if (this.viewGL && !this.viewGL.containPoint(x, y)) {
            return;
        }

        this.zr.on('mousemove', this._mouseMoveHandler);
        this.zr.on('mouseup', this._mouseUpHandler);

        var pos = this._convertPos(x, y);

        this._x = pos.x;
        this._y = pos.y;
    },

    // Convert pos from screen space to viewspace.
    _convertPos: function (x, y) {

        var camera = this.viewGL.camera;
        var viewport = this.viewGL.viewport;
        // PENDING
        return {
            x: (x - viewport.x) / viewport.width * (camera.right - camera.left) + camera.left,
            y: (y - viewport.y) / viewport.height * (camera.bottom - camera.top) + camera.top
        };
    },

    _mouseMoveHandler: function (e) {

        var pos = this._convertPos(e.offsetX, e.offsetY);

        this._dx += pos.x - this._x;
        this._dy += pos.y - this._y;

        this._x = pos.x;
        this._y = pos.y;

        this._needsUpdate = true;
    },

    _mouseUpHandler: function (e) {
        this.zr.off('mousemove', this._mouseMoveHandler);
        this.zr.off('mouseup', this._mouseUpHandler);
    },

    _mouseWheelHandler: function (e) {
        e = e.event;
        var delta = e.wheelDelta // Webkit
                || -e.detail; // Firefox
        if (delta === 0) {
            return;
        }

        var x = e.offsetX;
        var y = e.offsetY;
        if (this.viewGL && !this.viewGL.containPoint(x, y)) {
            return;
        }

        var zoomScale = delta > 0 ? 1.1 : 0.9;
        var newZoom = Math.max(Math.min(
            this._zoom * zoomScale, this.maxZoom
        ), this.minZoom);
        zoomScale = newZoom / this._zoom;

        var pos = this._convertPos(x, y);

        var fixX = (pos.x - this._dx) * (zoomScale - 1);
        var fixY = (pos.y - this._dy) * (zoomScale - 1);

        this._dx -= fixX;
        this._dy -= fixY;

        this._zoom = newZoom;

        this._needsUpdate = true;
    },

    dispose: function () {

        var zr = this.zr;
        zr.off('mousedown', this._mouseDownHandler);
        zr.off('mousemove', this._mouseMoveHandler);
        zr.off('mouseup', this._mouseUpHandler);
        zr.off('mousewheel', this._mouseWheelHandler);
        zr.off('globalout', this._mouseUpHandler);

        zr.animation.off('frame', this._update);
    }
});

/* harmony default export */ __webpack_exports__["a"] = (Roam2DControl);

/***/ }),
/* 274 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.lines2D.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nattribute vec2 position: POSITION;\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n\n#ifdef POSITIONTEXTURE_ENABLED\nuniform sampler2D positionTexture;\n#endif\n\nvoid main()\n{\n gl_Position = worldViewProjection * vec4(position, -10.0, 1.0);\n\n v_Color = a_Color;\n}\n\n@end\n\n@export ecgl.lines2D.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nvarying vec4 v_Color;\n\nvoid main()\n{\n gl_FragColor = color * v_Color;\n}\n@end\n\n\n@export ecgl.meshLines2D.vertex\n\nattribute vec2 position: POSITION;\nattribute vec2 normal;\nattribute float offset;\nattribute vec4 a_Color : COLOR;\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec4 viewport : VIEWPORT;\n\nvarying vec4 v_Color;\nvarying float v_Miter;\n\nvoid main()\n{\n vec4 p2 = worldViewProjection * vec4(position + normal, -10.0, 1.0);\n gl_Position = worldViewProjection * vec4(position, -10.0, 1.0);\n\n p2.xy /= p2.w;\n gl_Position.xy /= gl_Position.w;\n\n vec2 N = normalize(p2.xy - gl_Position.xy);\n gl_Position.xy += N * offset / viewport.zw * 2.0;\n\n gl_Position.xy *= gl_Position.w;\n\n v_Color = a_Color;\n}\n@end\n\n\n@export ecgl.meshLines2D.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nvarying vec4 v_Color;\nvarying float v_Miter;\n\nvoid main()\n{\n gl_FragColor = color * v_Color;\n}\n\n@end");


/***/ }),
/* 275 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__flowGL_FlowGLView__ = __webpack_require__(276);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__flowGL_FlowGLSeries__ = __webpack_require__(280);






/***/ }),
/* 276 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_retrieve__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__VectorFieldParticleSurface__ = __webpack_require__(277);








// TODO 百度地图不是 linear 的
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({

    type: 'flowGL',

    __ecgl__: true,

    init: function (ecModel, api) {
        this.viewGL = new __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__["a" /* default */]('orthographic');
        this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
        this.viewGL.add(this.groupGL);

        this._particleSurface = new __WEBPACK_IMPORTED_MODULE_4__VectorFieldParticleSurface__["a" /* default */]();

        var planeMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
            geometry: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].PlaneGeometry(),
            material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
                shader: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader({
                    vertex: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.color.vertex'),
                    fragment: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.color.fragment')
                }),
                // Must enable blending and multiply alpha.
                // Or premultipliedAlpha will let the alpha useless.
                transparent: true
            })
        });
        planeMesh.material.enableTexture('diffuseMap');

        this.groupGL.add(planeMesh);

        this._planeMesh = planeMesh;

    },

    render: function (seriesModel, ecModel, api) {
        var particleSurface = this._particleSurface;
        // Set particleType before set others.
        particleSurface.setParticleType(seriesModel.get('particleType'));
        particleSurface.setSupersampling(seriesModel.get('supersampling'));

        this._updateData(seriesModel, api);
        this._updateCamera(api.getWidth(), api.getHeight(), api.getDevicePixelRatio());

        var particleDensity = __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].firstNotNull(seriesModel.get('particleDensity'), 128);
        particleSurface.setParticleDensity(particleDensity, particleDensity);

        var planeMesh = this._planeMesh;

        var time = +(new Date());
        var self = this;
        var firstFrame = true;
        planeMesh.__percent = 0;
        planeMesh.stopAnimation();
        planeMesh.animate('', { loop: true })
            .when(100000, {
                __percent: 1
            })
            .during(function () {
                var timeNow = + (new Date());
                var dTime = Math.min(timeNow - time, 20);
                time = time + dTime;
                if (self._renderer) {
                    particleSurface.update(self._renderer, api, dTime / 1000, firstFrame);
                    planeMesh.material.set('diffuseMap', particleSurface.getSurfaceTexture());
                    // planeMesh.material.set('diffuseMap', self._particleSurface.vectorFieldTexture);
                }
                firstFrame = false;
            })
            .start();

        var itemStyleModel = seriesModel.getModel('itemStyle');
        var color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(itemStyleModel.get('color'));
        color[3] *= __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].firstNotNull(itemStyleModel.get('opacity'), 1);
        planeMesh.material.set('color', color);

        particleSurface.setColorTextureImage(seriesModel.get('colorTexture'), api);
        particleSurface.setParticleSize(seriesModel.get('particleSize'));
        particleSurface.particleSpeedScaling = seriesModel.get('particleSpeed');
        particleSurface.motionBlurFactor = 1.0 - Math.pow(0.1, seriesModel.get('particleTrail'));
    },

    updateTransform: function (seriesModel, ecModel, api) {
        this._updateData(seriesModel, api);
    },

    afterRender: function (globeModel, ecModel, api, layerGL) {
        var renderer = layerGL.renderer;
        this._renderer = renderer;
    },

    _updateData: function (seriesModel, api) {
        var coordSys = seriesModel.coordinateSystem;
        var dims = coordSys.dimensions.map(function (coordDim) {
            return seriesModel.coordDimToDataDim(coordDim)[0];
        });

        var data = seriesModel.getData();
        var xExtent = data.getDataExtent(dims[0]);
        var yExtent = data.getDataExtent(dims[1]);

        var gridWidth = seriesModel.get('gridWidth');
        var gridHeight = seriesModel.get('gridHeight');

        if (gridWidth == null || gridWidth === 'auto') {
            // TODO not accurate.
            var aspect = (xExtent[1] - xExtent[0]) / (yExtent[1] - yExtent[0]);
            gridWidth = Math.round(Math.sqrt(aspect * data.count()));
        }
        if (gridHeight == null || gridHeight === 'auto') {
            gridHeight = Math.ceil(data.count() / gridWidth);
        }

        var vectorFieldTexture = this._particleSurface.vectorFieldTexture;

        // Half Float needs Uint16Array
        var pixels = vectorFieldTexture.pixels;
        if (!pixels || pixels.length !== gridHeight * gridWidth * 4) {
            pixels = vectorFieldTexture.pixels = new Float32Array(gridWidth * gridHeight * 4);
        }
        else {
            for (var i = 0; i < pixels.length; i++) {
                pixels[i] = 0;
            }
        }

        var maxMag = 0;
        var minMag = Infinity;

        var points = new Float32Array(data.count() * 2);
        var offset = 0;
        var bbox = [[Infinity, Infinity], [-Infinity, -Infinity]];

        data.each([dims[0], dims[1], 'vx', 'vy'], function (x, y, vx, vy) {
            var pt = coordSys.dataToPoint([x, y]);
            points[offset++] = pt[0];
            points[offset++] = pt[1];
            bbox[0][0] = Math.min(pt[0], bbox[0][0]);
            bbox[0][1] = Math.min(pt[1], bbox[0][1]);
            bbox[1][0] = Math.max(pt[0], bbox[1][0]);
            bbox[1][1] = Math.max(pt[1], bbox[1][1]);

            var mag = Math.sqrt(vx * vx + vy * vy);
            maxMag = Math.max(maxMag, mag);
            minMag = Math.min(minMag, mag);
        });

        data.each(['vx', 'vy'], function (vx, vy, i) {
            var xPix = Math.round((points[i * 2] - bbox[0][0]) / (bbox[1][0] - bbox[0][0]) * (gridWidth - 1));
            var yPix = gridHeight - 1 - Math.round((points[i * 2 + 1] - bbox[0][1]) / (bbox[1][1] - bbox[0][1]) * (gridHeight - 1));

            var idx = (yPix * gridWidth + xPix) * 4;

            pixels[idx] = (vx / maxMag * 0.5 + 0.5);
            pixels[idx + 1] = (vy / maxMag * 0.5 + 0.5);
            pixels[idx + 3] = 1;
        });

        vectorFieldTexture.width = gridWidth;
        vectorFieldTexture.height = gridHeight;

        if (seriesModel.get('coordinateSystem') === 'bmap') {
            this._fillEmptyPixels(vectorFieldTexture);
        }

        vectorFieldTexture.dirty();

        this._updatePlanePosition(bbox[0], bbox[1], seriesModel,api);
        this._updateGradientTexture(data.getVisual('visualMeta'), [minMag, maxMag]);

    },
    // PENDING Use grid mesh ? or delaunay triangulation?
    _fillEmptyPixels: function (texture) {
        var pixels = texture.pixels;
        var width = texture.width;
        var height = texture.height;

        function fetchPixel(x, y, rg) {
            x = Math.max(Math.min(x, width - 1), 0);
            y = Math.max(Math.min(y, height - 1), 0);
            var idx = (y * (width - 1) + x) * 4;
            if (pixels[idx + 3] === 0) {
                return false;
            }
            rg[0] = pixels[idx];
            rg[1] = pixels[idx + 1];
            return true;
        }

        function addPixel(a, b, out) {
            out[0] = a[0] + b[0];
            out[1] = a[1] + b[1];
        }

        var center = [], left = [], right = [], top = [], bottom = [];
        var weight = 0;
        for (var y = 0; y < height; y++) {
            for (var x = 0; x < width; x++) {
                var idx = (y * (width - 1) + x) * 4;
                if (pixels[idx + 3] === 0) {
                    weight = center[0] = center[1] = 0;
                    if (fetchPixel(x - 1, y, left)) {
                        weight++; addPixel(left, center, center);
                    }
                    if (fetchPixel(x + 1, y, right)) {
                        weight++; addPixel(right, center, center);
                    }
                    if (fetchPixel(x, y - 1, top)) {
                        weight++; addPixel(top, center, center);
                    }
                    if (fetchPixel(x, y + 1, bottom)) {
                        weight++; addPixel(bottom, center, center);
                    }
                    center[0] /= weight;
                    center[1] /= weight;
                    // PENDING If overwrite. bilinear interpolation.
                    pixels[idx] = center[0];
                    pixels[idx + 1] = center[1];
                }
                pixels[idx + 3] = 1;
            }
        }
    },

    _updateGradientTexture: function (visualMeta, magExtent) {
        if (!visualMeta || !visualMeta.length) {
            this._particleSurface.setGradientTexture(null);
            return;
        }
        // TODO Different dimensions
        this._gradientTexture = this._gradientTexture || new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D({
            image: document.createElement('canvas')
        });
        var gradientTexture = this._gradientTexture;
        var canvas = gradientTexture.image;
        canvas.width = 200;
        canvas.height = 1;
        var ctx = canvas.getContext('2d');
        var gradient = ctx.createLinearGradient(0, 0.5, canvas.width, 0.5);
        visualMeta[0].stops.forEach(function (stop) {
            var offset;
            if (magExtent[1] === magExtent[0]) {
                offset = 0;
            }
            else {
                offset = stop.value / magExtent[1];
                offset = Math.min(Math.max(offset, 0), 1);
            }

            gradient.addColorStop(offset, stop.color);
        });
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        gradientTexture.dirty();

        this._particleSurface.setGradientTexture(this._gradientTexture);
    },

    _updatePlanePosition: function (leftTop, rightBottom, seriesModel, api) {
        var limitedResult = this._limitInViewportAndFullFill(leftTop, rightBottom, seriesModel, api);
        leftTop = limitedResult.leftTop;
        rightBottom = limitedResult.rightBottom;
        this._particleSurface.setRegion(limitedResult.region);

        this._planeMesh.position.set(
            (leftTop[0] + rightBottom[0]) / 2,
            api.getHeight() - (leftTop[1] + rightBottom[1]) / 2,
            0
        );

        var width = rightBottom[0] - leftTop[0];
        var height = rightBottom[1] - leftTop[1];
        this._planeMesh.scale.set(width / 2, height / 2, 1);

        this._particleSurface.resize(
            Math.max(Math.min(width, 2048), 1),
            Math.max(Math.min(height, 2048), 1)
        );

        if (this._renderer) {
            this._particleSurface.clearFrame(this._renderer);
        }
    },

    _limitInViewportAndFullFill: function (leftTop, rightBottom, seriesModel, api) {
        var newLeftTop = [
            Math.max(leftTop[0], 0),
            Math.max(leftTop[1], 0)
        ];
        var newRightBottom = [
            Math.min(rightBottom[0], api.getWidth()),
            Math.min(rightBottom[1], api.getHeight())
        ];
        // Tiliing in lng orientation.
        if (seriesModel.get('coordinateSystem') === 'bmap') {
            var lngRange = seriesModel.getData().getDataExtent(seriesModel.coordDimToDataDim('lng')[0]);
            // PENDING, consider grid density
            var isContinuous = Math.floor(lngRange[1] - lngRange[0]) >= 359;
            if (isContinuous) {
                if (newLeftTop[0] > 0) {
                    newLeftTop[0] = 0;
                }
                if (newRightBottom[0] < api.getWidth()) {
                    newRightBottom[0] = api.getWidth();
                }
            }
        }

        var width = rightBottom[0] - leftTop[0];
        var height = rightBottom[1] - leftTop[1];
        var newWidth = newRightBottom[0] - newLeftTop[0];
        var newHeight = newRightBottom[1] - newLeftTop[1];

        var region = [
            (newLeftTop[0] - leftTop[0]) / width,
            1.0 - newHeight / height - (newLeftTop[1] - leftTop[1]) / height,
            newWidth / width,
            newHeight / height
        ];

        return {
            leftTop: newLeftTop,
            rightBottom: newRightBottom,
            region: region
        };
    },

    _updateCamera: function (width, height, dpr) {
        this.viewGL.setViewport(0, 0, width, height, dpr);
        var camera = this.viewGL.camera;
        // FIXME  bottom can't be larger than top
        camera.left = camera.bottom = 0;
        camera.top = height;
        camera.right = width;
        camera.near = 0;
        camera.far = 100;
        camera.position.z = 10;
    },

    remove: function () {
        this._planeMesh.stopAnimation();
        this.groupGL.removeAll();
    },

    dispose: function () {
        if (this._renderer) {
            this._particleSurface.dispose(this._renderer);
        }
        this.groupGL.removeAll();
    }
});


/***/ }),
/* 277 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_compositor_Pass__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Mesh__ = __webpack_require__(40);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Material__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_Texture__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_claygl_src_camera_Orthographic__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_claygl_src_geometry_Plane__ = __webpack_require__(43);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__Line2D__ = __webpack_require__(278);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__vectorFieldParticle_glsl_js__ = __webpack_require__(279);












// import TemporalSS from '../../effect/TemporalSuperSampling';



__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_11__vectorFieldParticle_glsl_js__["a" /* default */]);

function createSpriteCanvas(size) {
    var canvas = document.createElement('canvas');
    canvas.width = canvas.height = size;
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = '#fff';
    ctx.arc(size / 2, size / 2, size / 2, 0, Math.PI * 2);
    ctx.fill();
    return canvas;
}

// import spriteUtil from '../../util/sprite';

var VectorFieldParticleSurface = function () {

    /**
     * @type {number}
     */
    this.motionBlurFactor = 0.99;
    /**
     * Vector field lookup image
     * @type {clay.Texture2D}
     */
    this.vectorFieldTexture = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */]({
        type: __WEBPACK_IMPORTED_MODULE_6_claygl_src_Texture__["a" /* default */].FLOAT,
        // minFilter: Texture.NEAREST,
        // magFilter: Texture.NEAREST,
        flipY: false
    });

    /**
     * Particle life range
     * @type {Array.<number>}
     */
    this.particleLife = [5, 20];

    this._particleType = 'point';

    /**
     * @type {number}
     */
    this._particleSize = 1;

    /**
     * @type {Array.<number>}
     */
    this.particleColor = [1, 1, 1, 1];

    /**
     * @type {number}
     */
    this.particleSpeedScaling = 1.0;

    /**
     * @type {clay.Texture2D}
     */
    this._thisFrameTexture = null;

    this._particlePass = null;
    this._spawnTexture = null;
    this._particleTexture0 = null;
    this._particleTexture1 = null;

    this._particlePointsMesh = null;

    this._surfaceFrameBuffer = null;

    this._elapsedTime = 0.0;

    this._scene = null;
    this._camera = null;

    this._lastFrameTexture = null;

    // this._temporalSS = new TemporalSS(50);

    // this._antialising = false;

    this._supersampling = 1;

    this._downsampleTextures = [];

    this._width = 512;
    this._height = 512;

    this.init();
};

VectorFieldParticleSurface.prototype = {

    constructor: VectorFieldParticleSurface,

    init: function () {
        var parameters = {
            type: __WEBPACK_IMPORTED_MODULE_6_claygl_src_Texture__["a" /* default */].FLOAT,
            minFilter: __WEBPACK_IMPORTED_MODULE_6_claygl_src_Texture__["a" /* default */].NEAREST,
            magFilter: __WEBPACK_IMPORTED_MODULE_6_claygl_src_Texture__["a" /* default */].NEAREST,
            useMipmap: false
        };
        this._spawnTexture = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */](parameters);

        this._particleTexture0 = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */](parameters);
        this._particleTexture1 = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */](parameters);

        this._frameBuffer = new __WEBPACK_IMPORTED_MODULE_9_claygl_src_FrameBuffer__["a" /* default */]({
            depthBuffer: false
        });
        this._particlePass = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_compositor_Pass__["a" /* default */]({
            fragment: __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.vfParticle.particle.fragment')
        });
        this._particlePass.setUniform('velocityTexture', this.vectorFieldTexture);
        this._particlePass.setUniform('spawnTexture', this._spawnTexture);

        this._downsamplePass = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_compositor_Pass__["a" /* default */]({
            fragment: __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('clay.compositor.downsample')
        });

        var particlePointsMesh = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Mesh__["a" /* default */]({
            // Render after last frame full quad
            renderOrder: 10,
            material: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Material__["a" /* default */]({
                shader: new __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */](
                    __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.vfParticle.renderPoints.vertex'),
                    __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.vfParticle.renderPoints.fragment')
                )
            }),
            mode: __WEBPACK_IMPORTED_MODULE_2_claygl_src_Mesh__["a" /* default */].POINTS,
            geometry: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__["a" /* default */]({
                dynamic: true,
                mainAttribute: 'texcoord0'
            })
        });
        var particleLinesMesh = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Mesh__["a" /* default */]({
            // Render after last frame full quad
            renderOrder: 10,
            material: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Material__["a" /* default */]({
                shader: new __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */](
                    __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.vfParticle.renderLines.vertex'),
                    __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.vfParticle.renderLines.fragment')
                )
            }),
            geometry: new __WEBPACK_IMPORTED_MODULE_10__Line2D__["a" /* default */](),
            culling: false
        });
        var lastFrameFullQuad = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Mesh__["a" /* default */]({
            material: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Material__["a" /* default */]({
                shader: new __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */](
                    __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.color.vertex'),
                    __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.color.fragment')
                )
                // DO NOT BLEND Blend will multiply alpha
                // transparent: true
            }),
            geometry: new __WEBPACK_IMPORTED_MODULE_8_claygl_src_geometry_Plane__["a" /* default */]()
        });
        lastFrameFullQuad.material.enableTexture('diffuseMap');

        this._particlePointsMesh = particlePointsMesh;
        this._particleLinesMesh = particleLinesMesh;
        this._lastFrameFullQuadMesh = lastFrameFullQuad;

        this._camera = new __WEBPACK_IMPORTED_MODULE_7_claygl_src_camera_Orthographic__["a" /* default */]();
        this._thisFrameTexture = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */]();
        this._lastFrameTexture = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */]();
    },

    setParticleDensity: function (width, height) {
        var nVertex = width * height;

        var spawnTextureData = new Float32Array(nVertex * 4);
        var off = 0;
        var lifeRange = this.particleLife;
        for (var i = 0; i < width; i++) {
            for (var j = 0; j < height; j++, off++) {
                // x position, range [0 - 1]
                spawnTextureData[off * 4] = Math.random();
                // y position, range [0 - 1]
                spawnTextureData[off * 4 + 1] = Math.random();
                // Some property
                spawnTextureData[off * 4 + 2] = Math.random();
                var life = (lifeRange[1] - lifeRange[0]) * Math.random() + lifeRange[0];
                // Particle life
                spawnTextureData[off * 4 + 3] = life;
            }
        }

        if (this._particleType === 'line') {
            this._setLineGeometry(width, height);
        }
        else {
            this._setPointsGeometry(width, height);
        }

        this._spawnTexture.width = width;
        this._spawnTexture.height = height;
        this._spawnTexture.pixels = spawnTextureData;

        this._particleTexture0.width = this._particleTexture1.width = width;
        this._particleTexture0.height = this._particleTexture1.height = height;

        this._particlePass.setUniform('textureSize', [width, height]);
    },

    _setPointsGeometry: function (width, height) {
        var nVertex = width * height;
        var geometry = this._particlePointsMesh.geometry;
        var attributes = geometry.attributes;
        attributes.texcoord0.init(nVertex);

        var off = 0;
        for (var i = 0; i < width; i++) {
            for (var j = 0; j < height; j++, off++) {
                attributes.texcoord0.value[off * 2] = i / width;
                attributes.texcoord0.value[off * 2 + 1] = j / height;
            }
        }
        geometry.dirty();
    },

    _setLineGeometry: function (width, height) {
        var nLine = width * height;
        var geometry = this._getParticleMesh().geometry;
        geometry.setLineCount(nLine);
        geometry.resetOffset();
        for (var i = 0; i < width; i++) {
            for (var j = 0; j < height; j++) {
                geometry.addLine([i / width, j / height]);
            }
        }
        geometry.dirty();
    },

    _getParticleMesh: function () {
        return this._particleType === 'line' ? this._particleLinesMesh : this._particlePointsMesh;
    },

    update: function (renderer, api, deltaTime, firstFrame) {
        var particleMesh = this._getParticleMesh();
        var frameBuffer = this._frameBuffer;
        var particlePass = this._particlePass;

        if (firstFrame) {
            this._updateDownsampleTextures(renderer, api);
        }

        particleMesh.material.set('size', this._particleSize * this._supersampling);
        particleMesh.material.set('color', this.particleColor);
        particlePass.setUniform('speedScaling', this.particleSpeedScaling);

        frameBuffer.attach(this._particleTexture1);
        particlePass.setUniform('firstFrameTime', firstFrame ? (this.particleLife[1] + this.particleLife[0]) / 2 : 0);
        particlePass.setUniform('particleTexture', this._particleTexture0);
        particlePass.setUniform('deltaTime', deltaTime);
        particlePass.setUniform('elapsedTime', this._elapsedTime);
        particlePass.render(renderer, frameBuffer);

        particleMesh.material.set('particleTexture', this._particleTexture1);
        particleMesh.material.set('prevParticleTexture', this._particleTexture0);

        frameBuffer.attach(this._thisFrameTexture);
        frameBuffer.bind(renderer);
        renderer.gl.clear(renderer.gl.DEPTH_BUFFER_BIT | renderer.gl.COLOR_BUFFER_BIT);
        var lastFrameFullQuad = this._lastFrameFullQuadMesh;
        lastFrameFullQuad.material.set('diffuseMap', this._lastFrameTexture);
        lastFrameFullQuad.material.set('color', [1, 1, 1, this.motionBlurFactor]);

        this._camera.update(true);
        renderer.renderPass([lastFrameFullQuad, particleMesh], this._camera);
        frameBuffer.unbind(renderer);

        this._downsample(renderer);

        this._swapTexture();

        this._elapsedTime += deltaTime;
    },

    _downsample: function (renderer) {
        var downsampleTextures = this._downsampleTextures;
        if (downsampleTextures.length === 0) {
            return;
        }
        var current = 0;
        var sourceTexture = this._thisFrameTexture;
        var targetTexture = downsampleTextures[current];

        while (targetTexture) {
            this._frameBuffer.attach(targetTexture);
            this._downsamplePass.setUniform('texture', sourceTexture);
            this._downsamplePass.setUniform('textureSize', [sourceTexture.width, sourceTexture.height]);
            this._downsamplePass.render(renderer, this._frameBuffer);

            sourceTexture = targetTexture;
            targetTexture = downsampleTextures[++current];
        }
    },

    getSurfaceTexture: function () {
        var downsampleTextures = this._downsampleTextures;
        return downsampleTextures.length > 0
            ? downsampleTextures[downsampleTextures.length - 1]
            : this._lastFrameTexture;
    },

    setRegion: function (region) {
        this._particlePass.setUniform('region', region);
    },

    resize: function (width, height) {
        this._lastFrameTexture.width = width * this._supersampling;
        this._lastFrameTexture.height = height * this._supersampling;
        this._thisFrameTexture.width = width * this._supersampling;
        this._thisFrameTexture.height = height * this._supersampling;

        this._width = width;
        this._height = height;
    },

    setParticleSize: function (size) {
        var particleMesh = this._getParticleMesh();
        if (size <= 2) {
            particleMesh.material.disableTexture('spriteTexture');
            particleMesh.material.transparent = false;
            return;
        }
        if (!this._spriteTexture) {
            this._spriteTexture = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */]();
        }
        if (!this._spriteTexture.image || this._spriteTexture.image.width !== size) {
            this._spriteTexture.image = createSpriteCanvas(size);
            this._spriteTexture.dirty();
        }
        particleMesh.material.transparent = true;
        particleMesh.material.enableTexture('spriteTexture');
        particleMesh.material.set('spriteTexture', this._spriteTexture);

        this._particleSize = size;
    },

    setGradientTexture: function (gradientTexture) {
        var material = this._getParticleMesh().material;
        material[gradientTexture ? 'enableTexture' : 'disableTexture']('gradientTexture');
        material.setUniform('gradientTexture', gradientTexture);
    },

    setColorTextureImage: function (colorTextureImg, api) {
        var material = this._getParticleMesh().material;
        material.setTextureImage('colorTexture', colorTextureImg, api, {
            flipY: true
        });
    },

    setParticleType: function (type) {
        this._particleType = type;
    },

    clearFrame: function (renderer) {
        var frameBuffer = this._frameBuffer;
        frameBuffer.attach(this._lastFrameTexture);
        frameBuffer.bind(renderer);
        renderer.gl.clear(renderer.gl.DEPTH_BUFFER_BIT | renderer.gl.COLOR_BUFFER_BIT);
        frameBuffer.unbind(renderer);
    },

    setSupersampling: function (supersampling) {
        this._supersampling = supersampling;
        this.resize(this._width, this._height);
    },

    _updateDownsampleTextures: function (renderer, api) {
        var downsampleTextures = this._downsampleTextures;
        var upScale = Math.max(Math.floor(Math.log(this._supersampling / api.getDevicePixelRatio()) / Math.log(2)), 0);
        var scale = 2;
        var width = this._width * this._supersampling;
        var height = this._height * this._supersampling;
        for (var i = 0; i < upScale; i++) {
            downsampleTextures[i] = downsampleTextures[i] || new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */]();
            downsampleTextures[i].width = width / scale;
            downsampleTextures[i].height = height / scale;
            scale *= 2;
        }
        for (;i < downsampleTextures.length; i++) {
            downsampleTextures[i].dispose(renderer);
        }
        downsampleTextures.length = upScale;
    },

    _swapTexture: function () {
        var tmp = this._particleTexture0;
        this._particleTexture0 = this._particleTexture1;
        this._particleTexture1 = tmp;

        var tmp = this._thisFrameTexture;
        this._thisFrameTexture = this._lastFrameTexture;
        this._lastFrameTexture = tmp;
    },

    dispose: function (renderer) {
        renderer.disposeFrameBuffer(this._frameBuffer);
        // Dispose textures
        renderer.disposeTexture(this.vectorFieldTexture);
        renderer.disposeTexture(this._spawnTexture);
        renderer.disposeTexture(this._particleTexture0);
        renderer.disposeTexture(this._particleTexture1);
        renderer.disposeTexture(this._thisFrameTexture);
        renderer.disposeTexture(this._lastFrameTexture);

        renderer.disposeGeometry(this._particleLinesMesh.geometry);
        renderer.disposeGeometry(this._particlePointsMesh.geometry);
        renderer.disposeGeometry(this._lastFrameFullQuadMesh.geometry);

        if (this._spriteTexture) {
            renderer.disposeTexture(this._spriteTexture);
        }

        this._particlePass.dispose(renderer);
        this._downsamplePass.dispose(renderer);

        this._downsampleTextures.forEach(function (texture) {
            texture.dispose(renderer);
        });
    }
};

/* harmony default export */ __webpack_exports__["a"] = (VectorFieldParticleSurface);

/***/ }),
/* 278 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/**
 * Lines geometry
 * Use screen space projected lines lineWidth > MAX_LINE_WIDTH
 * https://mattdesl.svbtle.com/drawing-lines-is-hard
 * @module echarts-gl/util/geometry/LinesGeometry
 * @author Yi Shen(http://github.com/pissang)
 */




/**
 * @constructor
 * @alias module:echarts-gl/chart/flowGL/Line2D
 * @extends clay.Geometry
 */

var LinesGeometry = __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].extend(function () {
    return {

        dynamic: true,

        attributes: {
            position: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('position', 'float', 3, 'POSITION')
        }
    };
},
/** @lends module: echarts-gl/util/geometry/LinesGeometry.prototype */
{

    /**
     * Reset offset
     */
    resetOffset: function () {
        this._vertexOffset = 0;
        this._faceOffset = 0;
    },

    /**
     * @param {number} nVertex
     */
    setLineCount: function (nLine) {
        var attributes = this.attributes;
        var nVertex = 4 * nLine;
        var nTriangle = 2 * nLine;
        if (this.vertexCount !== nVertex) {
            attributes.position.init(nVertex);
        }
        if (this.triangleCount !== nTriangle) {
            if (nTriangle === 0) {
                this.indices = null;
            }
            else {
                this.indices = this.vertexCount > 0xffff ? new Uint32Array(nTriangle * 3) : new Uint16Array(nTriangle * 3);
            }
        }
    },

    addLine: function (p) {
        var vertexOffset = this._vertexOffset;
        this.attributes.position.set(vertexOffset, [p[0], p[1], 1]);
        this.attributes.position.set(vertexOffset + 1, [p[0], p[1], -1]);
        this.attributes.position.set(vertexOffset + 2, [p[0], p[1], 2]);
        this.attributes.position.set(vertexOffset + 3, [p[0], p[1], -2]);

        this.setTriangleIndices(
            this._faceOffset++, [
                vertexOffset, vertexOffset + 1, vertexOffset + 2
            ]
        );
        this.setTriangleIndices(
            this._faceOffset++, [
                vertexOffset + 1, vertexOffset + 2, vertexOffset + 3
            ]
        );

        this._vertexOffset += 4;
    }
});

/* harmony default export */ __webpack_exports__["a"] = (LinesGeometry);

/***/ }),
/* 279 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.vfParticle.particle.fragment\n\nuniform sampler2D particleTexture;\nuniform sampler2D spawnTexture;\nuniform sampler2D velocityTexture;\n\nuniform float deltaTime;\nuniform float elapsedTime;\n\nuniform float speedScaling : 1.0;\n\nuniform vec2 textureSize;\nuniform vec4 region : [0, 0, 1, 1];\nuniform float firstFrameTime;\n\nvarying vec2 v_Texcoord;\n\n\nvoid main()\n{\n vec4 p = texture2D(particleTexture, v_Texcoord);\n bool spawn = false;\n if (p.w <= 0.0) {\n p = texture2D(spawnTexture, fract(v_Texcoord + elapsedTime / 10.0));\n p.w -= firstFrameTime;\n spawn = true;\n }\n vec2 v = texture2D(velocityTexture, fract(p.xy * region.zw + region.xy)).xy;\n v = (v - 0.5) * 2.0;\n p.z = length(v);\n p.xy += v * deltaTime / 10.0 * speedScaling;\n p.w -= deltaTime;\n\n if (spawn || p.xy != fract(p.xy)) {\n p.z = 0.0;\n }\n p.xy = fract(p.xy);\n\n gl_FragColor = p;\n}\n@end\n\n@export ecgl.vfParticle.renderPoints.vertex\n\n#define PI 3.1415926\n\nattribute vec2 texcoord : TEXCOORD_0;\n\nuniform sampler2D particleTexture;\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nuniform float size : 1.0;\n\nvarying float v_Mag;\nvarying vec2 v_Uv;\n\nvoid main()\n{\n vec4 p = texture2D(particleTexture, texcoord);\n\n if (p.w > 0.0 && p.z > 1e-5) {\n gl_Position = worldViewProjection * vec4(p.xy * 2.0 - 1.0, 0.0, 1.0);\n }\n else {\n gl_Position = vec4(100000.0, 100000.0, 100000.0, 1.0);\n }\n\n v_Mag = p.z;\n v_Uv = p.xy;\n\n gl_PointSize = size;\n}\n\n@end\n\n@export ecgl.vfParticle.renderPoints.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\nuniform sampler2D gradientTexture;\nuniform sampler2D colorTexture;\nuniform sampler2D spriteTexture;\n\nvarying float v_Mag;\nvarying vec2 v_Uv;\n\nvoid main()\n{\n gl_FragColor = color;\n#ifdef SPRITETEXTURE_ENABLED\n gl_FragColor *= texture2D(spriteTexture, gl_PointCoord);\n if (color.a == 0.0) {\n discard;\n }\n#endif\n#ifdef GRADIENTTEXTURE_ENABLED\n gl_FragColor *= texture2D(gradientTexture, vec2(v_Mag, 0.5));\n#endif\n#ifdef COLORTEXTURE_ENABLED\n gl_FragColor *= texture2D(colorTexture, v_Uv);\n#endif\n}\n\n@end\n\n@export ecgl.vfParticle.renderLines.vertex\n\n#define PI 3.1415926\n\nattribute vec3 position : POSITION;\n\nuniform sampler2D particleTexture;\nuniform sampler2D prevParticleTexture;\n\nuniform float size : 1.0;\nuniform vec4 vp: VIEWPORT;\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nvarying float v_Mag;\nvarying vec2 v_Uv;\n\n@import clay.util.rand\n\nvoid main()\n{\n vec4 p = texture2D(particleTexture, position.xy);\n vec4 p2 = texture2D(prevParticleTexture, position.xy);\n\n p.xy = p.xy * 2.0 - 1.0;\n p2.xy = p2.xy * 2.0 - 1.0;\n\n if (p.w > 0.0 && p.z > 1e-5) {\n vec2 dir = normalize(p.xy - p2.xy);\n vec2 norm = vec2(dir.y / vp.z, -dir.x / vp.w) * sign(position.z) * size;\n if (abs(position.z) == 2.0) {\n gl_Position = vec4(p.xy + norm, 0.0, 1.0);\n v_Uv = p.xy;\n v_Mag = p.z;\n }\n else {\n gl_Position = vec4(p2.xy + norm, 0.0, 1.0);\n v_Mag = p2.z;\n v_Uv = p2.xy;\n }\n gl_Position = worldViewProjection * gl_Position;\n }\n else {\n gl_Position = vec4(100000.0, 100000.0, 100000.0, 1.0);\n }\n}\n\n@end\n\n@export ecgl.vfParticle.renderLines.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\nuniform sampler2D gradientTexture;\nuniform sampler2D colorTexture;\n\nvarying float v_Mag;\nvarying vec2 v_Uv;\n\nvoid main()\n{\n gl_FragColor = color;\n #ifdef GRADIENTTEXTURE_ENABLED\n gl_FragColor *= texture2D(gradientTexture, vec2(v_Mag, 0.5));\n#endif\n#ifdef COLORTEXTURE_ENABLED\n gl_FragColor *= texture2D(colorTexture, v_Uv);\n#endif\n}\n\n@end\n");


/***/ }),
/* 280 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);


__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({

    type: 'series.flowGL',

    dependencies: ['geo', 'grid', 'bmap'],

    visualColorAccessPath: 'itemStyle.color',

    getInitialData: function (option, ecModel) {
        var coordSysDimensions = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.getCoordinateSystemDimensions(this.get('coordinateSystem')) || ['x', 'y'];
        if (true) {
            if (coordSysDimensions.length > 2) {
                throw new Error('flowGL can only be used on 2d coordinate systems.')
            }
        }
        coordSysDimensions.push('vx', 'vy');
        var dimensions = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.completeDimensions(coordSysDimensions, this.getSource(), {
            encodeDef: this.get('encode'),
            dimsDef: this.get('dimensions')
        });
        var data = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(dimensions, this);
        data.initData(this.getSource());
        return data;
    },

    defaultOption: {
        coordinateSystem: 'cartesian2d',
        zlevel: 10,

        supersampling: 1,
        // 128x128 particles
        particleType: 'point',

        particleDensity: 128,
        particleSize: 1,
        particleSpeed: 1,

        particleTrail: 2,

        colorTexture: null,

        gridWidth: 'auto',
        gridHeight: 'auto',

        itemStyle: {
            color: '#fff',
            opacity: 0.8
        }
    }
});

/***/ }),
/* 281 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__linesGL_LinesGLSeries__ = __webpack_require__(282);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__linesGL_LinesGLView__ = __webpack_require__(283);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_opacityVisual__ = __webpack_require__(17);







__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_3__common_opacityVisual__["a" /* default */])('linesGL'));

/***/ }),
/* 282 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_util__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_util___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_util__);



var LinesSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({

    type: 'series.linesGL',

    dependencies: ['grid', 'geo'],

    visualColorAccessPath: 'lineStyle.color',

    streamEnabled: true,

    init: function (option) {
        var result = this._processFlatCoordsArray(option.data);
        this._flatCoords = result.flatCoords;
        this._flatCoordsOffset = result.flatCoordsOffset;
        if (result.flatCoords) {
            option.data = new Float32Array(result.count);
        }

        LinesSeries.superApply(this, 'init', arguments);
    },

    mergeOption: function (option) {
        var result = this._processFlatCoordsArray(option.data);
        this._flatCoords = result.flatCoords;
        this._flatCoordsOffset = result.flatCoordsOffset;
        if (result.flatCoords) {
            option.data = new Float32Array(result.count);
        }

        LinesSeries.superApply(this, 'mergeOption', arguments);
    },

    appendData: function (params) {
        var result = this._processFlatCoordsArray(params.data);
        if (result.flatCoords) {
            if (!this._flatCoords) {
                this._flatCoords = result.flatCoords;
                this._flatCoordsOffset = result.flatCoordsOffset;
            }
            else {
                this._flatCoords = Object(__WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_util__["concatArray"])(this._flatCoords, result.flatCoords);
                this._flatCoordsOffset = Object(__WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_util__["concatArray"])(this._flatCoordsOffset, result.flatCoordsOffset);
            }
            params.data = new Float32Array(result.count);
        }

        this.getRawData().appendData(params.data);
    },

    _getCoordsFromItemModel: function (idx) {
        var itemModel = this.getData().getItemModel(idx);
        var coords = (itemModel.option instanceof Array)
            ? itemModel.option : itemModel.getShallow('coords');

        if (true) {
            if (!(coords instanceof Array && coords.length > 0 && coords[0] instanceof Array)) {
                throw new Error('Invalid coords ' + JSON.stringify(coords) + '. Lines must have 2d coords array in data item.');
            }
        }
        return coords;
    },

    getLineCoordsCount: function (idx) {
        if (this._flatCoordsOffset) {
            return this._flatCoordsOffset[idx * 2 + 1];
        }
        else {
            return this._getCoordsFromItemModel(idx).length;
        }
    },

    getLineCoords: function (idx, out) {
        if (this._flatCoordsOffset) {
            var offset = this._flatCoordsOffset[idx * 2];
            var len = this._flatCoordsOffset[idx * 2 + 1];
            for (var i = 0; i < len; i++) {
                out[i] = out[i] || [];
                out[i][0] = this._flatCoords[offset + i * 2];
                out[i][1] = this._flatCoords[offset + i * 2 + 1];
            }
            return len;
        }
        else {
            var coords = this._getCoordsFromItemModel(idx);
            for (var i = 0; i < coords.length; i++) {
                out[i] = out[i] || [];
                out[i][0] = coords[i][0];
                out[i][1] = coords[i][1];
            }
            return coords.length;
        }
    },

    _processFlatCoordsArray: function (data) {
        var startOffset = 0;
        if (this._flatCoords) {
            startOffset = this._flatCoords.length;
        }
        // Stored as a typed array. In format
        // Points Count(2) | x | y | x | y | Points Count(3) | x |  y | x | y | x | y |
        if (typeof data[0] === 'number') {
            var len = data.length;
            // Store offset and len of each segment
            var coordsOffsetAndLenStorage = new Uint32Array(len);
            var coordsStorage = new Float64Array(len);
            var coordsCursor = 0;
            var offsetCursor = 0;
            var dataCount = 0;
            for (var i = 0; i < len;) {
                dataCount++;
                var count = data[i++];
                // Offset
                coordsOffsetAndLenStorage[offsetCursor++] = coordsCursor + startOffset;
                // Len
                coordsOffsetAndLenStorage[offsetCursor++] = count;
                for (var k = 0; k < count; k++) {
                    var x = data[i++];
                    var y = data[i++];
                    coordsStorage[coordsCursor++] = x;
                    coordsStorage[coordsCursor++] = y;

                    if (i > len) {
                        if (true) {
                            throw new Error('Invalid data format.');
                        }
                    }
                }
            }

            return {
                flatCoordsOffset: new Uint32Array(coordsOffsetAndLenStorage.buffer, 0, offsetCursor),
                flatCoords: coordsStorage,
                count: dataCount
            };
        }

        return {
            flatCoordsOffset: null,
            flatCoords: null,
            count: data.length
        };
    },

    getInitialData: function (option, ecModel) {
        var lineData = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(['value'], this);
        lineData.hasItemOption = false;

        lineData.initData(option.data, [], function (dataItem, dimName, dataIndex, dimIndex) {
            // dataItem is simply coords
            if (dataItem instanceof Array) {
                return NaN;
            }
            else {
                lineData.hasItemOption = true;
                var value = dataItem.value;
                if (value != null) {
                    return value instanceof Array ? value[dimIndex] : value;
                }
            }
        });

        return lineData;
    },

    defaultOption: {
        coordinateSystem: 'geo',
        zlevel: 10,

        progressive: 1e4,
        progressiveThreshold: 5e4,

        // Cartesian coordinate system
        // xAxisIndex: 0,
        // yAxisIndex: 0,

        // Geo coordinate system
        // geoIndex: 0,

        // Support source-over, lighter
        blendMode: 'source-over',

        lineStyle: {
            opacity: 0.8
        },

        postEffect: {
            enable: false,
            colorCorrection: {
                exposure: 0,
                brightness: 0,
                contrast: 1,
                saturation: 1,
                enable: true
            }
        }
    }
});

/***/ }),
/* 283 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_ViewGL__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines2D__ = __webpack_require__(105);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_GLViewHelper__ = __webpack_require__(103);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_retrieve__ = __webpack_require__(2);








__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({

    type: 'linesGL',

    __ecgl__: true,

    init: function (ecModel, api) {
        this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
        this.viewGL = new __WEBPACK_IMPORTED_MODULE_2__core_ViewGL__["a" /* default */]('orthographic');
        this.viewGL.add(this.groupGL);

        this._glViewHelper = new __WEBPACK_IMPORTED_MODULE_4__common_GLViewHelper__["a" /* default */](this.viewGL);

        this._nativeLinesShader = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.lines3D');
        this._meshLinesShader = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.meshLines3D');

        this._linesMeshes = [];
        this._currentStep = 0;
    },

    render: function (seriesModel, ecModel, api) {
        this.groupGL.removeAll();
        this._glViewHelper.reset(seriesModel, api);

        var linesMesh = this._linesMeshes[0];
        if (!linesMesh) {
            linesMesh = this._linesMeshes[0] = this._createLinesMesh(seriesModel);
        }
        this._linesMeshes.length = 1;

        this.groupGL.add(linesMesh);
        this._updateLinesMesh(seriesModel, linesMesh, 0, seriesModel.getData().count());

        this.viewGL.setPostEffect(seriesModel.getModel('postEffect'), api);
    },

    incrementalPrepareRender: function (seriesModel, ecModel, api) {
        this.groupGL.removeAll();
        this._glViewHelper.reset(seriesModel, api);

        this._currentStep = 0;

        this.viewGL.setPostEffect(seriesModel.getModel('postEffect'), api);
    },

    incrementalRender: function (params, seriesModel, ecModel, api) {
        var linesMesh = this._linesMeshes[this._currentStep];
        if (!linesMesh) {
            linesMesh = this._createLinesMesh(seriesModel);
            this._linesMeshes[this._currentStep] = linesMesh;
        }
        this._updateLinesMesh(seriesModel, linesMesh, params.start, params.end);
        this.groupGL.add(linesMesh);
        api.getZr().refresh();

        this._currentStep++;
    },

    updateTransform: function (seriesModel, ecModel, api) {
        if (seriesModel.coordinateSystem.getRoamTransform) {
            this._glViewHelper.updateTransform(seriesModel, api);
        }
    },

    _createLinesMesh: function (seriesModel) {
        var linesMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
            $ignorePicking: true,
            material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
                shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.lines3D'),
                transparent: true,
                depthMask: false,
                depthTest: false
            }),
            geometry: new __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines2D__["a" /* default */]({
                segmentScale: 10,
                useNativeLine: true,
                dynamic: false
            }),
            mode: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.LINES,
            culling: false
        });

        return linesMesh;
    },

    _updateLinesMesh: function (seriesModel, linesMesh, start, end) {
        var data = seriesModel.getData();
        linesMesh.material.blend = seriesModel.get('blendMode') === 'lighter'
            ? __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].additiveBlend : null;
        var curveness = seriesModel.get('lineStyle.curveness') || 0;
        var isPolyline = seriesModel.get('polyline');
        var geometry = linesMesh.geometry;
        var coordSys = seriesModel.coordinateSystem;

        var lineWidth = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(seriesModel.get('lineStyle.width'), 1);

        if (lineWidth > 1) {
            if (linesMesh.material.shader !== this._meshLinesShader) {
                linesMesh.material.attachShader(this._meshLinesShader);
            }
            linesMesh.mode = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.TRIANGLES;
        }
        else {
            if (linesMesh.material.shader !== this._nativeLinesShader) {
                linesMesh.material.attachShader(this._nativeLinesShader);
            }
            linesMesh.mode = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.LINES;
        }

        start = start || 0;
        end = end || data.count();

        geometry.resetOffset();
        var vertexCount = 0;
        var triangleCount = 0;
        var p0 = [];
        var p1 = [];
        var p2 = [];
        var p3 = [];

        var lineCoords = [];

        var t = 0.3;
        var t2 = 0.7;

        function updateBezierControlPoints() {
            p1[0] = (p0[0] * t2 + p3[0] * t) - (p0[1] - p3[1]) * curveness;
            p1[1] = (p0[1] * t2 + p3[1] * t) - (p3[0] - p0[0]) * curveness;
            p2[0] = (p0[0] * t + p3[0] * t2) - (p0[1] - p3[1]) * curveness;
            p2[1] = (p0[1] * t + p3[1] * t2) - (p3[0] - p0[0]) * curveness;
        }
        if (isPolyline || curveness !== 0) {
            for (var idx = start; idx < end; idx++) {
                if (isPolyline) {
                    var count = seriesModel.getLineCoordsCount(idx);
                    vertexCount += geometry.getPolylineVertexCount(count);
                    triangleCount += geometry.getPolylineTriangleCount(count);
                }
                else {
                    seriesModel.getLineCoords(idx, lineCoords);
                    this._glViewHelper.dataToPoint(coordSys, lineCoords[0], p0);
                    this._glViewHelper.dataToPoint(coordSys, lineCoords[1], p3);
                    updateBezierControlPoints();

                    vertexCount += geometry.getCubicCurveVertexCount(p0, p1, p2, p3);
                    triangleCount += geometry.getCubicCurveTriangleCount(p0, p1, p2, p3);
                }
            }
        }
        else {
            var lineCount = end - start;
            vertexCount += lineCount * geometry.getLineVertexCount();
            triangleCount += lineCount * geometry.getLineVertexCount();
        }
        geometry.setVertexCount(vertexCount);
        geometry.setTriangleCount(triangleCount);

        var dataIndex = start;
        var colorArr = [];
        for (var idx = start; idx < end; idx++) {
            __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(data.getItemVisual(dataIndex, 'color'), colorArr);
            var opacity = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(data.getItemVisual(dataIndex, 'opacity'), 1);
            colorArr[3] *= opacity;

            var count = seriesModel.getLineCoords(idx, lineCoords);
            for (var k = 0; k < count; k++) {
                this._glViewHelper.dataToPoint(coordSys, lineCoords[k], lineCoords[k]);
            }

            if (isPolyline) {
                geometry.addPolyline(lineCoords, colorArr, lineWidth, 0, count);
            }
            else if (curveness !== 0) {
                p0 = lineCoords[0];
                p3 = lineCoords[1];
                updateBezierControlPoints();
                geometry.addCubicCurve(p0, p1, p2, p3, colorArr, lineWidth);
            }
            else {
                geometry.addPolyline(lineCoords, colorArr, lineWidth, 0, 2);
            }
            dataIndex++;
        }
    },

    dispose: function () {
        this.groupGL.removeAll();
    },

    remove: function () {
        this.groupGL.removeAll();
    }
});

/***/ })
/******/ ]);
});