| import { adjustTextY, getIdURL, getMatrixStr, getPathPrecision, getShadowKey, getSRTTransformString, hasShadow, isAroundZero, isGradient, isImagePattern, isLinearGradient, isPattern, isRadialGradient, normalizeColor, round4, TEXT_ALIGN_TO_ANCHOR } from './helper.js'; | 
| import Path from '../graphic/Path.js'; | 
| import ZRImage from '../graphic/Image.js'; | 
| import { getLineHeight } from '../contain/text.js'; | 
| import TSpan from '../graphic/TSpan.js'; | 
| import SVGPathRebuilder from './SVGPathRebuilder.js'; | 
| import mapStyleToAttrs from './mapStyleToAttrs.js'; | 
| import { createVNode, vNodeToString } from './core.js'; | 
| import { assert, clone, isFunction, isString, logError, map, retrieve2 } from '../core/util.js'; | 
| import { createOrUpdateImage } from '../graphic/helper/image.js'; | 
| import { createCSSAnimation } from './cssAnimation.js'; | 
| import { hasSeparateFont, parseFontSize } from '../graphic/Text.js'; | 
| import { DEFAULT_FONT, DEFAULT_FONT_FAMILY } from '../core/platform.js'; | 
| var round = Math.round; | 
| function isImageLike(val) { | 
|     return val && isString(val.src); | 
| } | 
| function isCanvasLike(val) { | 
|     return val && isFunction(val.toDataURL); | 
| } | 
| function setStyleAttrs(attrs, style, el, scope) { | 
|     mapStyleToAttrs(function (key, val) { | 
|         var isFillStroke = key === 'fill' || key === 'stroke'; | 
|         if (isFillStroke && isGradient(val)) { | 
|             setGradient(style, attrs, key, scope); | 
|         } | 
|         else if (isFillStroke && isPattern(val)) { | 
|             setPattern(el, attrs, key, scope); | 
|         } | 
|         else { | 
|             attrs[key] = val; | 
|         } | 
|     }, style, el, false); | 
|     setShadow(el, attrs, scope); | 
| } | 
| function noRotateScale(m) { | 
|     return isAroundZero(m[0] - 1) | 
|         && isAroundZero(m[1]) | 
|         && isAroundZero(m[2]) | 
|         && isAroundZero(m[3] - 1); | 
| } | 
| function noTranslate(m) { | 
|     return isAroundZero(m[4]) && isAroundZero(m[5]); | 
| } | 
| function setTransform(attrs, m, compress) { | 
|     if (m && !(noTranslate(m) && noRotateScale(m))) { | 
|         var mul = compress ? 10 : 1e4; | 
|         attrs.transform = noRotateScale(m) | 
|             ? "translate(" + round(m[4] * mul) / mul + " " + round(m[5] * mul) / mul + ")" : getMatrixStr(m); | 
|     } | 
| } | 
| function convertPolyShape(shape, attrs, mul) { | 
|     var points = shape.points; | 
|     var strArr = []; | 
|     for (var i = 0; i < points.length; i++) { | 
|         strArr.push(round(points[i][0] * mul) / mul); | 
|         strArr.push(round(points[i][1] * mul) / mul); | 
|     } | 
|     attrs.points = strArr.join(' '); | 
| } | 
| function validatePolyShape(shape) { | 
|     return !shape.smooth; | 
| } | 
| function createAttrsConvert(desc) { | 
|     var normalizedDesc = map(desc, function (item) { | 
|         return (typeof item === 'string' ? [item, item] : item); | 
|     }); | 
|     return function (shape, attrs, mul) { | 
|         for (var i = 0; i < normalizedDesc.length; i++) { | 
|             var item = normalizedDesc[i]; | 
|             var val = shape[item[0]]; | 
|             if (val != null) { | 
|                 attrs[item[1]] = round(val * mul) / mul; | 
|             } | 
|         } | 
|     }; | 
| } | 
| var buitinShapesDef = { | 
|     circle: [createAttrsConvert(['cx', 'cy', 'r'])], | 
|     polyline: [convertPolyShape, validatePolyShape], | 
|     polygon: [convertPolyShape, validatePolyShape] | 
| }; | 
| function hasShapeAnimation(el) { | 
|     var animators = el.animators; | 
|     for (var i = 0; i < animators.length; i++) { | 
|         if (animators[i].targetName === 'shape') { | 
|             return true; | 
|         } | 
|     } | 
|     return false; | 
| } | 
| export function brushSVGPath(el, scope) { | 
|     var style = el.style; | 
|     var shape = el.shape; | 
|     var builtinShpDef = buitinShapesDef[el.type]; | 
|     var attrs = {}; | 
|     var needsAnimate = scope.animation; | 
|     var svgElType = 'path'; | 
|     var strokePercent = el.style.strokePercent; | 
|     var precision = (scope.compress && getPathPrecision(el)) || 4; | 
|     if (builtinShpDef | 
|         && !scope.willUpdate | 
|         && !(builtinShpDef[1] && !builtinShpDef[1](shape)) | 
|         && !(needsAnimate && hasShapeAnimation(el)) | 
|         && !(strokePercent < 1)) { | 
|         svgElType = el.type; | 
|         var mul = Math.pow(10, precision); | 
|         builtinShpDef[0](shape, attrs, mul); | 
|     } | 
|     else { | 
|         if (!el.path) { | 
|             el.createPathProxy(); | 
|         } | 
|         var path = el.path; | 
|         if (el.shapeChanged()) { | 
|             path.beginPath(); | 
|             el.buildPath(path, el.shape); | 
|             el.pathUpdated(); | 
|         } | 
|         var pathVersion = path.getVersion(); | 
|         var elExt = el; | 
|         var svgPathBuilder = elExt.__svgPathBuilder; | 
|         if (elExt.__svgPathVersion !== pathVersion | 
|             || !svgPathBuilder | 
|             || strokePercent !== elExt.__svgPathStrokePercent) { | 
|             if (!svgPathBuilder) { | 
|                 svgPathBuilder = elExt.__svgPathBuilder = new SVGPathRebuilder(); | 
|             } | 
|             svgPathBuilder.reset(precision); | 
|             path.rebuildPath(svgPathBuilder, strokePercent); | 
|             svgPathBuilder.generateStr(); | 
|             elExt.__svgPathVersion = pathVersion; | 
|             elExt.__svgPathStrokePercent = strokePercent; | 
|         } | 
|         attrs.d = svgPathBuilder.getStr(); | 
|     } | 
|     setTransform(attrs, el.transform); | 
|     setStyleAttrs(attrs, style, el, scope); | 
|     scope.animation && createCSSAnimation(el, attrs, scope); | 
|     return createVNode(svgElType, el.id + '', attrs); | 
| } | 
| export function brushSVGImage(el, scope) { | 
|     var style = el.style; | 
|     var image = style.image; | 
|     if (image && !isString(image)) { | 
|         if (isImageLike(image)) { | 
|             image = image.src; | 
|         } | 
|         else if (isCanvasLike(image)) { | 
|             image = image.toDataURL(); | 
|         } | 
|     } | 
|     if (!image) { | 
|         return; | 
|     } | 
|     var x = style.x || 0; | 
|     var y = style.y || 0; | 
|     var dw = style.width; | 
|     var dh = style.height; | 
|     var attrs = { | 
|         href: image, | 
|         width: dw, | 
|         height: dh | 
|     }; | 
|     if (x) { | 
|         attrs.x = x; | 
|     } | 
|     if (y) { | 
|         attrs.y = y; | 
|     } | 
|     setTransform(attrs, el.transform); | 
|     setStyleAttrs(attrs, style, el, scope); | 
|     scope.animation && createCSSAnimation(el, attrs, scope); | 
|     return createVNode('image', el.id + '', attrs); | 
| } | 
| ; | 
| export function brushSVGTSpan(el, scope) { | 
|     var style = el.style; | 
|     var text = style.text; | 
|     text != null && (text += ''); | 
|     if (!text || isNaN(style.x) || isNaN(style.y)) { | 
|         return; | 
|     } | 
|     var font = style.font || DEFAULT_FONT; | 
|     var x = style.x || 0; | 
|     var y = adjustTextY(style.y || 0, getLineHeight(font), style.textBaseline); | 
|     var textAlign = TEXT_ALIGN_TO_ANCHOR[style.textAlign] | 
|         || style.textAlign; | 
|     var attrs = { | 
|         'dominant-baseline': 'central', | 
|         'text-anchor': textAlign | 
|     }; | 
|     if (hasSeparateFont(style)) { | 
|         var separatedFontStr = ''; | 
|         var fontStyle = style.fontStyle; | 
|         var fontSize = parseFontSize(style.fontSize); | 
|         if (!parseFloat(fontSize)) { | 
|             return; | 
|         } | 
|         var fontFamily = style.fontFamily || DEFAULT_FONT_FAMILY; | 
|         var fontWeight = style.fontWeight; | 
|         separatedFontStr += "font-size:" + fontSize + ";font-family:" + fontFamily + ";"; | 
|         if (fontStyle && fontStyle !== 'normal') { | 
|             separatedFontStr += "font-style:" + fontStyle + ";"; | 
|         } | 
|         if (fontWeight && fontWeight !== 'normal') { | 
|             separatedFontStr += "font-weight:" + fontWeight + ";"; | 
|         } | 
|         attrs.style = separatedFontStr; | 
|     } | 
|     else { | 
|         attrs.style = "font: " + font; | 
|     } | 
|     if (text.match(/\s/)) { | 
|         attrs['xml:space'] = 'preserve'; | 
|     } | 
|     if (x) { | 
|         attrs.x = x; | 
|     } | 
|     if (y) { | 
|         attrs.y = y; | 
|     } | 
|     setTransform(attrs, el.transform); | 
|     setStyleAttrs(attrs, style, el, scope); | 
|     scope.animation && createCSSAnimation(el, attrs, scope); | 
|     return createVNode('text', el.id + '', attrs, undefined, text); | 
| } | 
| export function brush(el, scope) { | 
|     if (el instanceof Path) { | 
|         return brushSVGPath(el, scope); | 
|     } | 
|     else if (el instanceof ZRImage) { | 
|         return brushSVGImage(el, scope); | 
|     } | 
|     else if (el instanceof TSpan) { | 
|         return brushSVGTSpan(el, scope); | 
|     } | 
| } | 
| function setShadow(el, attrs, scope) { | 
|     var style = el.style; | 
|     if (hasShadow(style)) { | 
|         var shadowKey = getShadowKey(el); | 
|         var shadowCache = scope.shadowCache; | 
|         var shadowId = shadowCache[shadowKey]; | 
|         if (!shadowId) { | 
|             var globalScale = el.getGlobalScale(); | 
|             var scaleX = globalScale[0]; | 
|             var scaleY = globalScale[1]; | 
|             if (!scaleX || !scaleY) { | 
|                 return; | 
|             } | 
|             var offsetX = style.shadowOffsetX || 0; | 
|             var offsetY = style.shadowOffsetY || 0; | 
|             var blur_1 = style.shadowBlur; | 
|             var _a = normalizeColor(style.shadowColor), opacity = _a.opacity, color = _a.color; | 
|             var stdDx = blur_1 / 2 / scaleX; | 
|             var stdDy = blur_1 / 2 / scaleY; | 
|             var stdDeviation = stdDx + ' ' + stdDy; | 
|             shadowId = scope.zrId + '-s' + scope.shadowIdx++; | 
|             scope.defs[shadowId] = createVNode('filter', shadowId, { | 
|                 'id': shadowId, | 
|                 'x': '-100%', | 
|                 'y': '-100%', | 
|                 'width': '300%', | 
|                 'height': '300%' | 
|             }, [ | 
|                 createVNode('feDropShadow', '', { | 
|                     'dx': offsetX / scaleX, | 
|                     'dy': offsetY / scaleY, | 
|                     'stdDeviation': stdDeviation, | 
|                     'flood-color': color, | 
|                     'flood-opacity': opacity | 
|                 }) | 
|             ]); | 
|             shadowCache[shadowKey] = shadowId; | 
|         } | 
|         attrs.filter = getIdURL(shadowId); | 
|     } | 
| } | 
| function setGradient(style, attrs, target, scope) { | 
|     var val = style[target]; | 
|     var gradientTag; | 
|     var gradientAttrs = { | 
|         'gradientUnits': val.global | 
|             ? 'userSpaceOnUse' | 
|             : 'objectBoundingBox' | 
|     }; | 
|     if (isLinearGradient(val)) { | 
|         gradientTag = 'linearGradient'; | 
|         gradientAttrs.x1 = val.x; | 
|         gradientAttrs.y1 = val.y; | 
|         gradientAttrs.x2 = val.x2; | 
|         gradientAttrs.y2 = val.y2; | 
|     } | 
|     else if (isRadialGradient(val)) { | 
|         gradientTag = 'radialGradient'; | 
|         gradientAttrs.cx = retrieve2(val.x, 0.5); | 
|         gradientAttrs.cy = retrieve2(val.y, 0.5); | 
|         gradientAttrs.r = retrieve2(val.r, 0.5); | 
|     } | 
|     else { | 
|         if (process.env.NODE_ENV !== 'production') { | 
|             logError('Illegal gradient type.'); | 
|         } | 
|         return; | 
|     } | 
|     var colors = val.colorStops; | 
|     var colorStops = []; | 
|     for (var i = 0, len = colors.length; i < len; ++i) { | 
|         var offset = round4(colors[i].offset) * 100 + '%'; | 
|         var stopColor = colors[i].color; | 
|         var _a = normalizeColor(stopColor), color = _a.color, opacity = _a.opacity; | 
|         var stopsAttrs = { | 
|             'offset': offset | 
|         }; | 
|         stopsAttrs['stop-color'] = color; | 
|         if (opacity < 1) { | 
|             stopsAttrs['stop-opacity'] = opacity; | 
|         } | 
|         colorStops.push(createVNode('stop', i + '', stopsAttrs)); | 
|     } | 
|     var gradientVNode = createVNode(gradientTag, '', gradientAttrs, colorStops); | 
|     var gradientKey = vNodeToString(gradientVNode); | 
|     var gradientCache = scope.gradientCache; | 
|     var gradientId = gradientCache[gradientKey]; | 
|     if (!gradientId) { | 
|         gradientId = scope.zrId + '-g' + scope.gradientIdx++; | 
|         gradientCache[gradientKey] = gradientId; | 
|         gradientAttrs.id = gradientId; | 
|         scope.defs[gradientId] = createVNode(gradientTag, gradientId, gradientAttrs, colorStops); | 
|     } | 
|     attrs[target] = getIdURL(gradientId); | 
| } | 
| function setPattern(el, attrs, target, scope) { | 
|     var val = el.style[target]; | 
|     var patternAttrs = { | 
|         'patternUnits': 'userSpaceOnUse' | 
|     }; | 
|     var child; | 
|     if (isImagePattern(val)) { | 
|         var imageWidth_1 = val.imageWidth; | 
|         var imageHeight_1 = val.imageHeight; | 
|         var imageSrc = void 0; | 
|         var patternImage = val.image; | 
|         if (isString(patternImage)) { | 
|             imageSrc = patternImage; | 
|         } | 
|         else if (isImageLike(patternImage)) { | 
|             imageSrc = patternImage.src; | 
|         } | 
|         else if (isCanvasLike(patternImage)) { | 
|             imageSrc = patternImage.toDataURL(); | 
|         } | 
|         if (typeof Image === 'undefined') { | 
|             var errMsg = 'Image width/height must been given explictly in svg-ssr renderer.'; | 
|             assert(imageWidth_1, errMsg); | 
|             assert(imageHeight_1, errMsg); | 
|         } | 
|         else if (imageWidth_1 == null || imageHeight_1 == null) { | 
|             var setSizeToVNode_1 = function (vNode, img) { | 
|                 if (vNode) { | 
|                     var svgEl = vNode.elm; | 
|                     var width = (vNode.attrs.width = imageWidth_1 || img.width); | 
|                     var height = (vNode.attrs.height = imageHeight_1 || img.height); | 
|                     if (svgEl) { | 
|                         svgEl.setAttribute('width', width); | 
|                         svgEl.setAttribute('height', height); | 
|                     } | 
|                 } | 
|             }; | 
|             var createdImage = createOrUpdateImage(imageSrc, null, el, function (img) { | 
|                 setSizeToVNode_1(patternVNode, img); | 
|                 setSizeToVNode_1(child, img); | 
|             }); | 
|             if (createdImage && createdImage.width && createdImage.height) { | 
|                 imageWidth_1 = imageWidth_1 || createdImage.width; | 
|                 imageHeight_1 = imageHeight_1 || createdImage.height; | 
|             } | 
|         } | 
|         child = createVNode('image', 'img', { | 
|             href: imageSrc, | 
|             width: imageWidth_1, | 
|             height: imageHeight_1 | 
|         }); | 
|         patternAttrs.width = imageWidth_1; | 
|         patternAttrs.height = imageHeight_1; | 
|     } | 
|     else if (val.svgElement) { | 
|         child = clone(val.svgElement); | 
|         patternAttrs.width = val.svgWidth; | 
|         patternAttrs.height = val.svgHeight; | 
|     } | 
|     if (!child) { | 
|         return; | 
|     } | 
|     patternAttrs.patternTransform = getSRTTransformString(val); | 
|     var patternVNode = createVNode('pattern', '', patternAttrs, [child]); | 
|     var patternKey = vNodeToString(patternVNode); | 
|     var patternCache = scope.patternCache; | 
|     var patternId = patternCache[patternKey]; | 
|     if (!patternId) { | 
|         patternId = scope.zrId + '-p' + scope.patternIdx++; | 
|         patternCache[patternKey] = patternId; | 
|         patternAttrs.id = patternId; | 
|         patternVNode = scope.defs[patternId] = createVNode('pattern', patternId, patternAttrs, [child]); | 
|     } | 
|     attrs[target] = getIdURL(patternId); | 
| } | 
| export function setClipPath(clipPath, attrs, scope) { | 
|     var clipPathCache = scope.clipPathCache, defs = scope.defs; | 
|     var clipPathId = clipPathCache[clipPath.id]; | 
|     if (!clipPathId) { | 
|         clipPathId = scope.zrId + '-c' + scope.clipPathIdx++; | 
|         var clipPathAttrs = { | 
|             id: clipPathId | 
|         }; | 
|         clipPathCache[clipPath.id] = clipPathId; | 
|         defs[clipPathId] = createVNode('clipPath', clipPathId, clipPathAttrs, [brushSVGPath(clipPath, scope)]); | 
|     } | 
|     attrs['clip-path'] = getIdURL(clipPathId); | 
| } |