Вход Регистрация
Файл: wapxl.ru/top/amcharts/plugins/export/export.js
Строк: 2469
<?php
/*
Plugin Name: amCharts Export
Description: Adds export capabilities to amCharts products
Author: Benjamin Maertz, amCharts
Version: 1.4.18
Author URI: http://www.amcharts.com/

Copyright 2015 amCharts

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

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.

Please note that the above license covers only this plugin. It by all means does
not apply to any other amCharts products that are covered by different licenses.
*/

/*
 ** Polyfill translation
 */
if ( !AmCharts.translations"export" ] ) {
    
AmCharts.translations"export" ] = {}
}
if ( !
AmCharts.translations"export" ][ "en" ] ) {
    
AmCharts.translations"export" ][ "en" ] = {
        
"fallback.save.text""CTRL + C to copy the data into the clipboard.",
        
"fallback.save.image""Rightclick -> Save picture as... to save the image.",

        
"capturing.delayed.menu.label""{{duration}}",
        
"capturing.delayed.menu.title""Click to cancel",

        
"menu.label.print""Print",
        
"menu.label.undo""Undo",
        
"menu.label.redo""Redo",
        
"menu.label.cancel""Cancel",

        
"menu.label.save.image""Download as ...",
        
"menu.label.save.data""Save as ...",

        
"menu.label.draw""Annotate ...",
        
"menu.label.draw.change""Change ...",
        
"menu.label.draw.add""Add ...",
        
"menu.label.draw.shapes""Shape ...",
        
"menu.label.draw.colors""Color ...",
        
"menu.label.draw.widths""Size ...",
        
"menu.label.draw.opacities""Opacity ...",
        
"menu.label.draw.text""Text",

        
"menu.label.draw.modes""Mode ...",
        
"menu.label.draw.modes.pencil""Pencil",
        
"menu.label.draw.modes.line""Line",
        
"menu.label.draw.modes.arrow""Arrow"
    
}
}

/*
 ** Polyfill export class
 */
( function() {
    
AmCharts"export" ] = function( chartconfig ) {
        var 
_this = {
            
name"export",
            
version"1.4.18",
            
libs: {
                
asynctrue,
                
autoLoadtrue,
                
reloadfalse,
                
resources: [ {
                    
"pdfmake/pdfmake.js": [ "pdfmake/vfs_fonts.js" ],
                    
"jszip/jszip.js": [ "xlsx/xlsx.js" ]
                }, 
"fabric.js/fabric.js""FileSaver.js/FileSaver.js" ],
                
namespaces: {
                    
"pdfmake.js""pdfMake",
                    
"jszip.js""JSZip",
                    
"xlsx.js""XLSX",
                    
"fabric.js""fabric",
                    
"FileSaver.js""saveAs"
                
}
            },
            
config: {},
            
setup: {
                
chartchart,
                
hasBlobfalse,
                
wrapperfalse
            
},
            
drawing: {
                
enabledfalse,
                
undos: [],
                
redos: [],
                
buffer: {
                    
position: {
                        
x10,
                        
y10,
                        
x20,
                        
y20,
                        
xD0,
                        
yD0
                    
}
                },
                
handler: {
                    
undo: function( optionsskipped ) {
                        var 
item _this.drawing.undos.pop();
                        if ( 
item ) {
                            
item.selectable true;
                            
_this.drawing.redos.pushitem );

                            if ( 
item.action == "added" ) {
                                
_this.setup.fabric.removeitem.target );
                            }

                            var 
state JSON.parseitem.state );
                            
item.target.setstate );

                            if ( 
item.target instanceof fabric.Group ) {
                                
_this.drawing.handler.change( {
                                    
colorstate.cfg.color,
                                    
widthstate.cfg.width,
                                    
opacitystate.cfg.opacity
                                
}, trueitem.target );
                            }

                            
_this.setup.fabric.renderAll();

                            
// RECALL
                            
if ( item.state == item.target.recentState && !skipped ) {
                                
_this.drawing.handler.undoitemtrue );
                            }
                        }
                    },
                    
redo: function( optionsskipped ) {
                        var 
item _this.drawing.redos.pop();
                        if ( 
item ) {
                            
item.selectable true;
                            
_this.drawing.undos.pushitem );

                            if ( 
item.action == "added" ) {
                                
_this.setup.fabric.additem.target );
                            }

                            var 
state JSON.parseitem.state );
                            
item.target.recentState item.state;
                            
item.target.setstate );

                            if ( 
item.target instanceof fabric.Group ) {
                                
_this.drawing.handler.change( {
                                    
colorstate.cfg.color,
                                    
widthstate.cfg.width,
                                    
opacitystate.cfg.opacity
                                
}, trueitem.target );
                            }

                            
_this.setup.fabric.renderAll();

                            
// RECALL
                            
if ( item.action == "addified" ) {
                                
_this.drawing.handler.redo();
                            }
                        }
                    },
                    
done: function( options ) {
                        
_this.drawing.buffer.enabled false;
                        
_this.drawing.undos = [];
                        
_this.drawing.redos = [];
                        
_this.createMenu_this.config.menu );
                        
_this.setup.fabric.deactivateAll();

                        if ( 
_this.setup.wrapper ) {
                            
_this.setup.chart.containerDiv.removeChild_this.setup.wrapper );
                            
_this.setup.wrapper false;
                        }
                    },
                    
add: function( options ) {
                        var 
cfg _this.deepMerge( {
                            
top_this.setup.fabric.height 2,
                            
left_this.setup.fabric.width 2
                        
}, options || {} );
                        var 
method cfg.url.indexOf".svg" ) != -fabric.loadSVGFromURL fabric.Image.fromURL;

                        
methodcfg.url, function( objectsoptions ) {
                            var 
group options !== undefined fabric.util.groupSVGElementsobjectsoptions ) : objects;
                            var 
ratio false;

                            
// RESCALE ONLY IF IT EXCEEDS THE CANVAS
                            
if ( group.height _this.setup.fabric.height || group.width _this.setup.fabric.width ) {
                                
ratio = ( _this.setup.fabric.height ) / group.height;
                            }

                            if ( 
cfg.top _this.setup.fabric.height ) {
                                
cfg.top _this.setup.fabric.height 2;
                            }

                            if ( 
cfg.left _this.setup.fabric.width ) {
                                
cfg.left _this.setup.fabric.width 2;
                            }

                            
group.set( {
                                
originX"center",
                                
originY"center",
                                
topcfg.top,
                                
leftcfg.left,
                                
widthratio group.width ratio group.width,
                                
heightratio group.height ratio group.height,
                                
fill_this.drawing.color
                            
} );
                            
_this.setup.fabric.addgroup );
                        } );
                    },
                    
change: function( optionsskippedtarget ) {
                        var 
cfg _this.deepMerge( {}, options || {} );
                        var 
statei1rgba;
                        var 
current target || _this.drawing.buffer.target;
                        var 
objects current current._objects current._objects : [ current ] : null;

                        
// UPDATE DRAWING OBJECT
                        
if ( cfg.mode ) {
                            
_this.drawing.mode cfg.mode;
                        }
                        if ( 
cfg.width ) {
                            
_this.drawing.width cfg.width;
                            
_this.drawing.fontSize cfg.width 3;
                        }
                        if ( 
cfg.fontSize ) {
                            
_this.drawing.fontSize cfg.fontSize;
                        }
                        if ( 
cfg.color ) {
                            
_this.drawing.color cfg.color;
                        }
                        if ( 
cfg.opacity ) {
                            
_this.drawing.opacity cfg.opacity;
                        }

                        
// APPLY OPACITY ON CURRENT COLOR
                        
rgba = new fabric.Color_this.drawing.color ).getSource();
                        
rgba.pop();
                        
rgba.push_this.drawing.opacity );
                        
_this.drawing.color "rgba(" rgba.join() + ")";
                        
_this.setup.fabric.freeDrawingBrush.color _this.drawing.color;
                        
_this.setup.fabric.freeDrawingBrush.width _this.drawing.width;

                        
// UPDATE CURRENT SELECTION
                        
if ( current ) {
                            
state JSON.parsecurrent.recentState ).cfg;

                            
// UPDATE GIVE OPTIONS ONLY
                            
if ( state ) {
                                
cfg.color cfg.color || state.color;
                                
cfg.width cfg.width || state.width;
                                
cfg.opacity cfg.opacity || state.opacity;
                                
cfg.fontSize cfg.fontSize || cfg.width 3;

                                
rgba = new fabric.Colorcfg.color ).getSource();
                                
rgba.pop();
                                
rgba.pushcfg.opacity );
                                
cfg.color "rgba(" rgba.join() + ")";
                            }

                            
// UPDATE OBJECTS
                            
for ( i1 0i1 objects.lengthi1++ ) {
                                if (
                                    
objectsi1 ] instanceof fabric.Text ||
                                    
objectsi1 ] instanceof fabric.PathGroup ||
                                    
objectsi1 ] instanceof fabric.Triangle
                                
) {
                                    if ( 
cfg.color || cfg.opacity ) {
                                        
objectsi1 ].set( {
                                            
fillcfg.color
                                        
} );
                                    }
                                    if ( 
cfg.fontSize ) {
                                        
objectsi1 ].set( {
                                            
fontSizecfg.fontSize
                                        
} );
                                    }
                                } else if (
                                    
objectsi1 ] instanceof fabric.Path ||
                                    
objectsi1 ] instanceof fabric.Line
                                
) {
                                    if ( 
current instanceof fabric.Group ) {
                                        if ( 
cfg.color || cfg.opacity ) {
                                            
objectsi1 ].set( {
                                                
strokecfg.color
                                            
} );
                                        }
                                    } else {
                                        if ( 
cfg.color || cfg.opacity ) {
                                            
objectsi1 ].set( {
                                                
strokecfg.color
                                            
} );
                                        }
                                        if ( 
cfg.width ) {
                                            
objectsi1 ].set( {
                                                
strokeWidthcfg.width
                                            
} );
                                        }
                                    }
                                }
                            }

                            
// ADD UNDO
                            
if ( !skipped ) {
                                
state JSON.stringify_this.deepMergecurrent.saveState().originalState, {
                                    
cfg: {
                                        
colorcfg.color,
                                        
widthcfg.width,
                                        
opacitycfg.opacity
                                    
}
                                } ) );
                                
current.recentState state;
                                
_this.drawing.redos = [];
                                
_this.drawing.undos.push( {
                                    
action"modified",
                                    
targetcurrent,
                                    
statestate
                                
} );
                            }

                            
_this.setup.fabric.renderAll();
                        }
                    },
                    
text: function( options ) {
                        var 
cfg _this.deepMerge( {
                            
text_this.i18l"menu.label.draw.text" ),
                            
top_this.setup.fabric.height 2,
                            
left_this.setup.fabric.width 2,
                            
fontSize_this.drawing.fontSize,
                            
fontFamily_this.setup.chart.fontFamily || "Verdana",
                            
fill_this.drawing.color
                        
}, options || {} );

                        
cfg.click = function() {};

                        var 
text = new fabric.ITextcfg.textcfg );

                        
_this.setup.fabric.addtext );
                        
_this.setup.fabric.setActiveObjecttext );

                        
text.selectAll();
                        
text.enterEditing();

                        return 
text;
                    },
                    
line: function( options ) {
                        var 
cfg _this.deepMerge( {
                            
x1: ( _this.setup.fabric.width ) - ( _this.setup.fabric.width 10 ),
                            
x2: ( _this.setup.fabric.width ) + ( _this.setup.fabric.width 10 ),
                            
y1: ( _this.setup.fabric.height ),
                            
y2: ( _this.setup.fabric.height ),
                            
angle90,
                            
strokeLineCap_this.drawing.lineCap,
                            
arrow_this.drawing.arrow,
                            
color_this.drawing.color,
                            
width_this.drawing.width,
                            
group: [],
                        }, 
options || {} );
                        var 
i1arrowarrowToparrowLeft;
                        var 
line = new fabric.Line( [ cfg.x1cfg.y1cfg.x2cfg.y2 ], {
                            
strokecfg.color,
                            
strokeWidthcfg.width,
                            
strokeLineCapcfg.strokeLineCap
                        
} );

                        
cfg.group.pushline );

                        if ( 
cfg.arrow ) {
                            
cfg.angle cfg.angle cfg.angle _this.getAnglecfg.x1cfg.y1cfg.x2cfg.y2 );

                            if ( 
cfg.arrow == "start" ) {
                                
arrowTop cfg.y1 + ( cfg.width );
                                
arrowLeft cfg.x1 + ( cfg.width );
                            } else if ( 
cfg.arrow == "middle" ) {
                                
arrowTop cfg.y2 + ( cfg.width ) - ( ( cfg.y2 cfg.y1 ) / );
                                
arrowLeft cfg.x2 + ( cfg.width ) - ( ( cfg.x2 cfg.x1 ) / );
                            } else { 
// arrow: end
                                
arrowTop cfg.y2 + ( cfg.width );
                                
arrowLeft cfg.x2 + ( cfg.width );
                            }

                            
arrow = new fabric.Triangle( {
                                
toparrowTop,
                                
leftarrowLeft,
                                
fillcfg.color,
                                
heightcfg.width 7,
                                
widthcfg.width 7,
                                
anglecfg.angle,
                                
originX"center",
                                
originY"bottom"
                            
} );
                            
cfg.group.pusharrow );
                        }

                        if ( 
cfg.action != "config" ) {
                            if ( 
cfg.arrow ) {
                                var 
group = new fabric.Groupcfg.group );
                                
group.set( {
                                    
cfgcfg,
                                    
fillcfg.color,
                                    
actioncfg.action,
                                    
selectabletrue,
                                    
knowncfg.action == "change"
                                
} );
                                if ( 
cfg.action == "change" ) {
                                    
_this.setup.fabric.setActiveObjectgroup );
                                }
                                
_this.setup.fabric.addgroup );
                                return 
group;
                            } else {
                                
_this.setup.fabric.addline );
                                return 
line;
                            }
                        } else {
                            for ( 
i1 0i1 cfg.group.lengthi1++ ) {
                                
cfg.groupi1 ].noUndo true;
                                
_this.setup.fabric.addcfg.groupi1 ] );
                            }
                        }
                        return 
cfg;
                    }
                }
            },
            
defaults: {
                
position"top-right",
                
fileName"amCharts",
                
action"download",
                
overflowtrue,
                
path: ( ( chart.path || "" ) + "plugins/export/" ),
                
formats: {
                    
JPG: {
                        
mimeType"image/jpg",
                        
extension"jpg",
                        
capturetrue
                    
},
                    
PNG: {
                        
mimeType"image/png",
                        
extension"png",
                        
capturetrue
                    
},
                    
SVG: {
                        
mimeType"text/xml",
                        
extension"svg",
                        
capturetrue
                    
},
                    
PDF: {
                        
mimeType"application/pdf",
                        
extension"pdf",
                        
capturetrue
                    
},
                    
CSV: {
                        
mimeType"text/plain",
                        
extension"csv"
                    
},
                    
JSON: {
                        
mimeType"text/plain",
                        
extension"json"
                    
},
                    
XLSX: {
                        
mimeType"application/octet-stream",
                        
extension"xlsx"
                    
}
                },
                
fabric: {
                    
backgroundColor"#FFFFFF",
                    
removeImagestrue,
                    
selectionfalse,
                    
drawing: {
                        
enabledtrue,
                        
arrow"end",
                        
lineCap"butt",
                        
mode"pencil",
                        
modes: [ "pencil""line""arrow" ],
                        
color"#000000",
                        
colors: [ "#000000""#FFFFFF""#FF0000""#00FF00""#0000FF" ],
                        
shapes: [ "11.svg""14.svg""16.svg""17.svg""20.svg""27.svg" ],
                        
width1,
                        
fontSize11,
                        
widths: [ 151015 ],
                        
opacity1,
                        
opacities: [ 10.80.60.40.2 ],
                        
menuundefined,
                        
autoClosetrue
                    
},
                    
border: {
                        
fill"",
                        
fillOpacity0,
                        
stroke"#000000",
                        
strokeWidth1,
                        
strokeOpacity1
                    
}
                },
                
pdfMake: {
                    
pageSize"A4",
                    
pageOrientation"portrait",
                    
images: {},
                    
content: [ "Saved from:"window.location.href, {
                        
image"reference",
                        
fit: [ 523.28769.89 ]
                    } ]
                },
                
menuundefined,
                
divIdnull,
                
menuRevivernull,
                
menuWalkernull,
                
fallbacktrue,
                
keyListenertrue,
                
fileListenertrue
            
},

            
/**
             * Returns translated message, takes english as default
             */
            
i18l: function( keylanguage ) {
                var 
lang language langugage _this.setup.chart.language _this.setup.chart.language "en";
                var 
catalog AmCharts.translations_this.name ][ lang ] || AmCharts.translations_this.name ][ "en" ];

                return 
catalogkey ] || key;
            },

            
/**
             * Generates download file; if unsupported offers fallback to save manually
             */
            
download: function( datatypefilename ) {
                
// SAVE
                
if ( window.saveAs && _this.setup.hasBlob ) {
                    var 
blob _this.toBlob( {
                        
datadata,
                        
typetype
                    
}, function( data ) {
                        
saveAsdatafilename );
                    } );

                    
// FALLBACK TEXTAREA
                
} else if ( _this.config.fallback && type == "text/plain" ) {
                    var 
div document.createElement"div" );
                    var 
msg document.createElement"div" );
                    var 
textarea document.createElement"textarea" );

                    
msg.innerHTML _this.i18l"fallback.save.text" );

                    
div.appendChildmsg );
                    
div.appendChildtextarea );
                    
msg.setAttribute"class""amcharts-export-fallback-message" );
                    
div.setAttribute"class""amcharts-export-fallback" );
                    
_this.setup.chart.containerDiv.appendChilddiv );

                    
// FULFILL TEXTAREA AND PRESELECT
                    
textarea.setAttribute"readonly""" );
                    
textarea.value data;
                    
textarea.focus();
                    
textarea.select();

                    
// UPDATE MENU
                    
_this.createMenu( [ {
                        
"class""export-main export-close",
                        
label"Done",
                        
click: function() {
                            
_this.createMenu_this.config.menu );
                            
_this.setup.chart.containerDiv.removeChilddiv );
                        }
                    } ] );

                    
// FALLBACK IMAGE
                
} else if ( _this.config.fallback && type.split"/" )[ ] == "image" ) {
                    var 
div document.createElement"div" );
                    var 
msg document.createElement"div" );
                    var 
img _this.toImage( {
                        
datadata
                    
} );

                    
msg.innerHTML _this.i18l"fallback.save.image" );

                    
// FULFILL TEXTAREA AND PRESELECT
                    
div.appendChildmsg );
                    
div.appendChildimg );
                    
msg.setAttribute"class""amcharts-export-fallback-message" );
                    
div.setAttribute"class""amcharts-export-fallback" );
                    
_this.setup.chart.containerDiv.appendChilddiv );

                    
// UPDATE MENU
                    
_this.createMenu( [ {
                        
"class""export-main export-close",
                        
label"Done",
                        
click: function() {
                            
_this.createMenu_this.config.menu );
                            
_this.setup.chart.containerDiv.removeChilddiv );
                        }
                    } ] );

                    
// ERROR
                
} else {
                    throw new 
Error"Unable to create file. Ensure saveAs (FileSaver.js) is supported." );
                }
                return 
data;
            },

            
/**
             * Generates script, links tags and places them into the document's head
             * In case of reload it replaces the node to force the download
             */
            
loadResource: function( srcaddons ) {
                var 
i1existnodeitemchecktype;
                var 
url src.indexOf"//" ) != -src : [ _this.libs.pathsrc ].join"" );

                function 
callback() {
                    if ( 
addons ) {
                        for ( 
i1 0i1 addons.lengthi1++ ) {
                            
_this.loadResourceaddonsi1 ] );
                        }
                    }
                }

                if ( 
src.indexOf".js" ) != -) {
                    
node document.createElement"script" );
                    
node.setAttribute"type""text/javascript" );
                    
node.setAttribute"src"url );
                    if ( 
_this.libs.async ) {
                        
node.setAttribute"async""" );
                    }

                } else if ( 
src.indexOf".css" ) != -) {
                    
node document.createElement"link" );
                    
node.setAttribute"type""text/css" );
                    
node.setAttribute"rel""stylesheet" );
                    
node.setAttribute"href"url );
                }

                
// NODE CHECK
                
for ( i1 0i1 document.head.childNodes.lengthi1++ ) {
                    
item document.head.childNodesi1 ];
                    
check item ? ( item.src || item.href ) : false;
                    
type item item.tagName false;

                    if ( 
item && check && check.indexOfsrc ) != -) {
                        if ( 
_this.libs.reload ) {
                            
document.head.removeChilditem );
                        }
                        
exist true;
                        break;
                    }
                }

                
// NAMESPACE CHECK
                
for ( i1 in _this.libs.namespaces ) {
                    var namespace = 
_this.libs.namespacesi1 ];
                    var 
check src.toLowerCase();
                    var 
item i1.toLowerCase();
                    if ( 
check.indexOfitem ) != -&& window[ namespace ] !== undefined ) {
                        
exist true;
                        break;
                    }
                }

                if ( !
exist || _this.libs.reload ) {
                    
node.addEventListener"load"callback );
                    
document.head.appendChildnode );
                }

            },

            
/**
             * Walker to generate the script,link tags
             */
            
loadDependencies: function() {
                var 
i1i2;
                if ( 
_this.libs.autoLoad ) {
                    for ( 
i1 0i1 _this.libs.resources.lengthi1++ ) {
                        if ( 
_this.libs.resourcesi1 ] instanceof Object ) {
                            for ( 
i2 in _this.libs.resourcesi1 ] ) {
                                
_this.loadResourcei2_this.libs.resourcesi1 ][ i2 ] );
                            }
                        } else {
                            
_this.loadResource_this.libs.resourcesi1 ] );
                        }
                    }
                }
            },

            
/**
             * Converts string to number
             */
            
pxToNumber: function( attrreturnUndefined ) {
                if ( !
attr && returnUndefined ) {
                    return 
undefined;
                }
                return 
NumberStringattr ).replace"px""" ) ) || 0;
            },

            
/**
             * Converts number to string
             */
            
numberToPx: function( attr ) {
                return 
Stringattr ) + "px";
            },

            
/**
             * Recursive method to merge the given objects together
             * Overwrite flag replaces the value instead to crawl through
             */
            
deepMerge: function( aboverwrite ) {
                var 
i1vtype instanceof Array ? "array" "object";

                for ( 
i1 in b ) {
                    
// PREVENT METHODS
                    
if ( type == "array" && isNaNi1 ) ) {
                        continue;
                    }

                    
bi1 ];

                    
// NEW
                    
if ( ai1 ] == undefined || overwrite ) {
                        if ( 
instanceof Array ) {
                            
ai1 ] = new Array();
                        } else if ( 
instanceof Function ) {
                            
ai1 ] = function() {};
                        } else if ( 
instanceof Date ) {
                            
ai1 ] = new Date();
                        } else if ( 
instanceof Object ) {
                            
ai1 ] = new Object();
                        } else if ( 
instanceof Number ) {
                            
ai1 ] = new Number();
                        } else if ( 
instanceof String ) {
                            
ai1 ] = new String();
                        }
                    }

                    if (
                        ( 
instanceof Object || instanceof Array ) &&
                        ( 
instanceof Object || instanceof Array ) &&
                        !( 
instanceof Function || instanceof Date || _this.isElement) ) &&
                        
i1 != "chart"
                    
) {
                        
_this.deepMergeai1 ], voverwrite );
                    } else {
                        if ( 
instanceof Array && !overwrite ) {
                            
a.push);
                        } else {
                            
ai1 ] = v;
                        }
                    }
                }
                return 
a;
            },

            
/**
             * Checks if given argument is a valid node
             */
            
isElement: function( thingy ) {
                return 
thingy instanceof Object && thingy && thingy.nodeType === 1;
            },

            
/**
             * Checks if given argument contains a hashbang and returns it
             */
            
isHashbanged: function( thingy ) {
                var 
str Stringthingy ).replace( /"/g, "" );

                return str.slice( 0, 3 ) == "
url" ? str.slice( str.indexOf( "#" ) + 1, str.length - 1 ) : false;
            
},

            
/**
             * Checks if given event has been thrown with pressed click / touch
             */
            
isPressed: function( event ) {
                
// IE EXCEPTION
                
if ( event.type == "mousemove" && event.which === ) {
                    
// IGNORE

                    // OTHERS
                
} else if (
                    
event.type == "touchmove" ||
                    
event.buttons === ||
                    
event.button === ||
                    
event.which === 1
                
) {
                    
_this.drawing.buffer.isPressed true;
                } else {
                    
_this.drawing.buffer.isPressed false;
                }
                return 
_this.drawing.buffer.isPressed;
            },

            
/**
             * Checks if given source is within the current origin
             */
            
isTainted: function( source ) {
                var 
origin Stringwindow.location.origin || window.location.protocol "//" window.location.hostname + ( window.location.port ':' window.location.port '' ) );

                
// CHECK IF TAINTED
                
if (
                    
source &&
                    
source.indexOf"//" ) != -&&
                    
source.indexOforigin.replace( /.*:/, "" ) ) == -1
                
) {
                    return 
true;
                }
                return 
false;
            },

            
/*
             ** Checks several indicators for acceptance;
             */
            
isSupported: function() {
                
// CHECK CONFIG
                
if ( !_this.config.enabled ) {
                    return 
false;
                }

                
// CHECK IE; ATTEMPT TO ACCESS HEAD ELEMENT
                
if ( AmCharts.isIE && AmCharts.IEversion <= ) {
                    if ( !Array.
prototype.indexOf || !document.head || _this.config.fallback === false ) {
                        return 
false;
                    }
                }
                return 
true;
            },


            
getAngle: function( x1y1x2y2 ) {
                var 
x2 x1;
                var 
y2 y1;
                var 
angle;
                if ( 
== ) {
                    if ( 
== ) {
                        
angle 0;
                    } else if ( 
) {
                        
angle Math.PI 2;
                    } else {
                        
angle Math.PI 2;
                    }
                } else if ( 
== ) {
                    if ( 
) {
                        
angle 0;
                    } else {
                        
angle Math.PI;
                    }
                } else {
                    if ( 
) {
                        
angle Math.atan) + Math.PI;
                    } else if ( 
) {
                        
angle Math.atan) + ( Math.PI );
                    } else {
                        
angle Math.atan);
                    }
                }
                return 
angle 180 Math.PI;
            },

            
/**
             * Recursive method which crawls upwards to gather the requested attribute
             */
            
gatherAttribute: function( elmattrlimitlvl ) {
                var 
valuelvl lvl lvl 0,
                    
limit limit limit 3;
                if ( 
elm ) {
                    
value elm.getAttributeattr );

                    if ( !
value && lvl limit ) {
                        return 
_this.gatherAttributeelm.parentNodeattrlimitlvl );
                    }
                }
                return 
value;
            },

            
/**
             * Recursive method which crawls upwards to gather the requested classname
             */
            
gatherClassName: function( elmclassNamelimitlvl ) {
                var 
valuelvl lvl lvl 0,
                    
limit limit limit 3;

                if ( 
_this.isElementelm ) ) {
                    
value = ( elm.getAttribute"class" ) || "" ).split" " ).indexOfclassName ) != -1;

                    if ( !
value && lvl limit ) {
                        return 
_this.gatherClassNameelm.parentNodeclassNamelimitlvl );
                    } else if ( 
value ) {
                        
value elm;
                    }
                }
                return 
value;
            },

            
/**
             * Collects the clip-paths and patterns
             */
            
gatherElements: function( groupcfgimages ) {
                var 
i1i2;
                for ( 
i1 0i1 group.children.lengthi1++ ) {
                    var 
childNode group.childreni1 ];

                    
// CLIPPATH
                    
if ( childNode.tagName == "clipPath" ) {
                        var 
bbox = {};
                        var 
transform fabric.parseTransformAttribute_this.gatherAttributechildNode"transform" ) );

                        
// HIDE SIBLINGS; GATHER IT'S DIMENSIONS
                        
for ( i2 0i2 childNode.childNodes.lengthi2++ ) {
                            
childNode.childNodesi2 ].setAttribute"fill""transparent" );
                            
bbox = {
                                
x_this.pxToNumberchildNode.childNodesi2 ].getAttribute"x" ) ),
                                
y_this.pxToNumberchildNode.childNodesi2 ].getAttribute"y" ) ),
                                
width_this.pxToNumberchildNode.childNodesi2 ].getAttribute"width" ) ),
                                
height_this.pxToNumberchildNode.childNodesi2 ].getAttribute"height" ) )
                            }
                        }

                        
group.clippingschildNode.id ] = {
                            
svgchildNode,
                            
bboxbbox,
                            
transformtransform
                        
};

                        
// PATTERN
                    
} else if ( childNode.tagName == "pattern" ) {
                        var 
props = {
                            
nodechildNode,
                            
sourcechildNode.getAttribute"xlink:href" ),
                            
widthNumberchildNode.getAttribute"width" ) ),
                            
heightNumberchildNode.getAttribute"height" ) ),
                            
repeat"repeat"
                        
}

                        
// GATHER BACKGROUND COLOR
                        
for ( i2 0i2 childNode.childNodes.lengthi2++ ) {
                            if ( 
childNode.childNodesi2 ].tagName == "rect" ) {
                                
props.fill childNode.childNodesi2 ].getAttribute"fill" );
                            }
                        }

                        
// TAINTED
                        
if ( cfg.removeImages && _this.isTaintedprops.source ) ) {
                            
group.patternschildNode.id ] = props.fill props.fill "transparent";
                        } else {
                            
images.included++;

                            
group.patternsprops.node.id ] = props;
                        }

                        
// IMAGES
                    
} else if ( childNode.tagName == "image" ) {
                        
images.included++;

                        
// LOAD IMAGE MANUALLY; TO RERENDER THE CANVAS
                        
fabric.Image.fromURLchildNode.getAttribute"xlink:href" ), function( img ) {
                            
images.loaded++;
                        } );
                    }
                }
                return 
group;
            },

            
/*
             ** GATHER MOUSE POSITION;
             */
            
gatherPosition: function( eventtype ) {
                var 
ref _this.drawing.buffer.position;
                var 
ivt fabric.util.invertTransform_this.setup.fabric.viewportTransform );
                var 
pos;

                if ( 
event.type == "touchmove" ) {
                    if ( 
"touches" in event ) {
                        
event event.touches];
                    } else if ( 
"changedTouches" in event ) {
                        
event event.changedTouches];
                    }
                }

                
pos fabric.util.transformPoint_this.setup.fabric.getPointereventtrue ), ivt );

                if ( 
type == ) {
                    
ref.x1 pos.x;
                    
ref.y1 pos.y;
                }

                
ref.x2 pos.x;
                
ref.y2 pos.y;
                
ref.xD = ( ref.x1 ref.x2 ) < ? ( ref.x1 ref.x2 ) * -: ( ref.x1 ref.x2 );
                
ref.yD = ( ref.y1 ref.y2 ) < ? ( ref.y1 ref.y2 ) * -: ( ref.y1 ref.y2 );

                return 
ref;
            },

            
/**
             * Method to capture the current state of the chart
             */
            
capture: function( optionscallback ) {
                var 
i1;
                var 
cfg _this.deepMerge_this.deepMerge( {}, _this.config.fabric ), options || {} );
                var 
groups = [];
                var 
offset = {
                    
x0,
                    
y0,
                    
pX0,
                    
pY0,
                    
width_this.setup.chart.divRealWidth,
                    
height_this.setup.chart.divRealHeight
                
};
                var 
images = {
                    
loaded0,
                    
included0
                
}

                
fabric.ElementsParser.prototype.resolveGradient = function( objproperty ) {

                    var 
instanceFillValue obj.getproperty );
                    if ( !( /^
url(/ ).testinstanceFillValue ) ) {
                        return;
                    }
                    var 
gradientId instanceFillValue.sliceinstanceFillValue.indexOf"#" ) + 1instanceFillValue.length );
                    if ( 
fabric.gradientDefsthis.svgUid ][ gradientId ] ) {
                        
obj.setpropertyfabric.Gradient.fromElementfabric.gradientDefsthis.svgUid ][ gradientId ], obj ) );
                    }
                };

                
// BEFORE CAPTURING
                
_this.handleCallbackcfg.beforeCapturecfg );

                
// GATHER SVGS
                
var svgs _this.setup.chart.containerDiv.getElementsByTagName"svg" );
                for ( 
i1 0i1 svgs.lengthi1++ ) {
                    var 
group = {
                        
svgsvgsi1 ],
                        
parentsvgsi1 ].parentNode,
                        
childrensvgsi1 ].getElementsByTagName"*" ),
                        
offset: {
                            
x0,
                            
y0
                        
},
                        
patterns: {},
                        
clippings: {}
                    }

                    
// GATHER ELEMENTS
                    
group _this.gatherElementsgroupcfgimages );

                    
// APPEND GROUP
                    
groups.pushgroup );
                }

                
// GATHER EXTERNAL LEGEND
                
if ( _this.config.legend && _this.setup.chart.legend && _this.setup.chart.legend.position == "outside" ) {
                    var 
group = {
                        
svg_this.setup.chart.legend.container.container,
                        
parent_this.setup.chart.legend.container.container.parentNode,
                        
children_this.setup.chart.legend.container.container.getElementsByTagName"*" ),
                        
offset: {
                            
x0,
                            
y0
                        
},
                        
legend: {
                            
type: [ "top""left" ].indexOf_this.config.legend.position ) != -"unshift" "push",
                            
position_this.config.legend.position,
                            
width_this.config.legend.width _this.config.legend.width _this.setup.chart.legend.container.width,
                            
height_this.config.legend.height _this.config.legend.height _this.setup.chart.legend.container.height
                        
},
                        
patterns: {},
                        
clippings: {}
                    }

                    
// ADAPT CANVAS DIMENSIONS
                    
if ( [ "left""right" ].indexOfgroup.legend.position ) != -) {
                        
offset.width += group.legend.width;
                        
offset.height group.legend.height offset.height group.legend.height offset.height;
                    } else if ( [ 
"top""bottom" ].indexOfgroup.legend.position ) != -) {
                        
offset.height += group.legend.height;
                    }

                    
// GATHER ELEMENTS
                    
group _this.gatherElementsgroupcfgimages );

                    
// PRE/APPEND SVG
                    
groupsgroup.legend.type ]( group );
                }

                
// CLEAR IF EXIST
                
_this.drawing.buffer.enabled cfg.action == "draw";

                
_this.setup.wrapper document.createElement"div" );
                
_this.setup.wrapper.setAttribute"class"_this.setup.chart.classNamePrefix "-export-canvas" );
                
_this.setup.chart.containerDiv.appendChild_this.setup.wrapper );

                
// STOCK CHART; SELECTOR OFFSET
                
if ( _this.setup.chart.type == "stock" ) {
                    var 
padding = {
                        
top0,
                        
right0,
                        
bottom0,
                        
left0
                    
}
                    if ( 
_this.setup.chart.leftContainer ) {
                        
offset.width -= _this.setup.chart.leftContainer.offsetWidth;
                        
padding.left _this.setup.chart.leftContainer.offsetWidth + ( _this.setup.chart.panelsSettings.panelSpacing );
                    }
                    if ( 
_this.setup.chart.rightContainer ) {
                        
offset.width -= _this.setup.chart.rightContainer.offsetWidth;
                        
padding.right _this.setup.chart.rightContainer.offsetWidth + ( _this.setup.chart.panelsSettings.panelSpacing );
                    }
                    if ( 
_this.setup.chart.periodSelector && [ "top""bottom" ].indexOf_this.setup.chart.periodSelector.position ) != -) {
                        
offset.height -= _this.setup.chart.periodSelector.offsetHeight _this.setup.chart.panelsSettings.panelSpacing;
                        
padding_this.setup.chart.periodSelector.position ] += _this.setup.chart.periodSelector.offsetHeight _this.setup.chart.panelsSettings.panelSpacing;
                    }
                    if ( 
_this.setup.chart.dataSetSelector && [ "top""bottom" ].indexOf_this.setup.chart.dataSetSelector.position ) != -) {
                        
offset.height -= _this.setup.chart.dataSetSelector.offsetHeight;
                        
padding_this.setup.chart.dataSetSelector.position ] += _this.setup.chart.dataSetSelector.offsetHeight;
                    }

                    
// APPLY OFFSET ON WRAPPER
                    
_this.setup.wrapper.style.paddingTop _this.numberToPxpadding.top );
                    
_this.setup.wrapper.style.paddingRight _this.numberToPxpadding.right );
                    
_this.setup.wrapper.style.paddingBottom _this.numberToPxpadding.bottom );
                    
_this.setup.wrapper.style.paddingLeft _this.numberToPxpadding.left );
                }

                
// CREATE CANVAS
                
_this.setup.canvas document.createElement"canvas" );
                
_this.setup.wrapper.appendChild_this.setup.canvas );
                
_this.setup.fabric = new fabric.Canvas_this.setup.canvas_this.deepMerge( {
                    
widthoffset.width,
                    
heightoffset.height,
                    
isDrawingModetrue
                
}, cfg ) );

                
// REAPPLY FOR SOME REASON
                
_this.deepMerge_this.setup.fabriccfg );
                
_this.deepMerge_this.setup.fabric.freeDrawingBrushcfg.drawing );

                
// RELIABLE VARIABLES; UPDATE DRAWING
                
_this.deepMerge_this.drawingcfg.drawing );
                
_this.drawing.handler.changecfg.drawing );

                
// OBSERVE MOUSE EVENTS
                
_this.setup.fabric.on"mouse:down", function( ) {
                    var 
_this.gatherPositione.e);
                    
_this.drawing.buffer.pressedTS Number( new Date() );
                    
_this.isPressede.);
                } );
                
_this.setup.fabric.on"mouse:move", function( ) {
                    var 
_this.gatherPositione.e);
                    
_this.isPressede.);

                    
// CREATE INITIAL LINE / ARROW; JUST ON LEFT CLICK
                    
if ( _this.drawing.buffer.isPressed && !_this.drawing.buffer.line ) {
                        if ( !
_this.drawing.buffer.isSelected && _this.drawing.mode != "pencil" && ( p.xD || p.xD ) ) {
                            
_this.drawing.buffer.hasLine true;
                            
_this.setup.fabric.isDrawingMode false;
                            
_this.setup.fabric._onMouseUpInDrawingMode);
                            
_this.drawing.buffer.line _this.drawing.handler.line( {
                                
x1p.x1,
                                
y1p.y1,
                                
x2p.x2,
                                
y2p.y2,
                                
arrow_this.drawing.mode == "line" false _this.drawing.arrow,
                                
action"config"
                            
} );
                        }
                    }

                    
// UPDATE LINE / ARROW
                    
if ( _this.drawing.buffer.line ) {
                        var 
objtopleft;
                        var 
_this.drawing.buffer.line;

                        
l.x2 p.x2;
                        
l.y2 p.y2;

                        for ( 
i1 0i1 l.group.lengthi1++ ) {
                            
obj l.groupi1 ];

                            if ( 
obj instanceof fabric.Line ) {
                                
obj.set( {
                                    
x2l.x2,
                                    
y2l.y2
                                
} );
                            } else if ( 
obj instanceof fabric.Triangle ) {
                                
l.angle = ( _this.getAnglel.x1l.y1l.x2l.y2 ) + 90 );

                                if ( 
l.arrow == "start" ) {
                                    
top l.y1 + ( l.width );
                                    
left l.x1 + ( l.width );
                                } else if ( 
l.arrow == "middle" ) {
                                    
top l.y2 + ( l.width ) - ( ( l.y2 l.y1 ) / );
                                    
left l.x2 + ( l.width ) - ( ( l.x2 l.x1 ) / );
                                } else { 
// arrow: end
                                    
top l.y2 + ( l.width );
                                    
left l.x2 + ( l.width );
                                }

                                
obj.set( {
                                    
toptop,
                                    
leftleft,
                                    
anglel.angle
                                
} );
                            }
                        }
                        
_this.setup.fabric.renderAll();
                    }
                } );
                
_this.setup.fabric.on"mouse:up", function( ) {
                    
// SELECT TARGET
                    
if ( Number( new Date() ) - _this.drawing.buffer.pressedTS 200 ) {
                        var 
target _this.setup.fabric.findTargete.);
                        if ( 
target && target.selectable ) {
                            
_this.setup.fabric.setActiveObjecttarget );
                        }
                    }

                    
// UPDATE LINE / ARROW
                    
if ( _this.drawing.buffer.line ) {
                        for ( 
i1 0i1 _this.drawing.buffer.line.group.lengthi1++ ) {
                            
_this.drawing.buffer.line.groupi1 ].remove();
                        }
                        
delete _this.drawing.buffer.line.action;
                        
delete _this.drawing.buffer.line.group;
                        
_this.drawing.handler.line_this.drawing.buffer.line );
                    }
                    
_this.drawing.buffer.line false;
                    
_this.drawing.buffer.hasLine false;
                    
_this.drawing.buffer.isPressed false;
                } );

                
// OBSERVE OBJECT SELECTION
                
_this.setup.fabric.on"object:selected", function( ) {
                    
_this.drawing.buffer.isSelected true;
                    
_this.drawing.buffer.target e.target;
                    
_this.setup.fabric.isDrawingMode false;
                } );
                
_this.setup.fabric.on"selection:cleared", function( ) {
                    
_this.drawing.buffer.onMouseDown _this.setup.fabric.freeDrawingBrush.onMouseDown;
                    
_this.drawing.buffer.target false;

                    
// FREEHAND WORKAROUND
                    
if ( _this.drawing.buffer.isSelected ) {
                        
_this.setup.fabric._isCurrentlyDrawing false;
                        
_this.setup.fabric.freeDrawingBrush.onMouseDown = function() {};
                    }

                    
// DELAYED DESELECTION TO PREVENT DRAWING
                    
setTimeout( function() {
                        
_this.drawing.buffer.isSelected false;
                        
_this.setup.fabric.isDrawingMode true;
                        
_this.setup.fabric.freeDrawingBrush.onMouseDown _this.drawing.buffer.onMouseDown;
                    }, 
10 );
                } );
                
_this.setup.fabric.on"path:created", function( ) {
                    var 
item e.path;
                    if ( 
Number( new Date() ) - _this.drawing.buffer.pressedTS 200 || _this.drawing.buffer.hasLine ) {
                        
_this.setup.fabric.removeitem );
                        
_this.setup.fabric.renderAll();
                        return;
                    }
                } );

                
// OBSERVE OBJECT MODIFICATIONS
                
_this.setup.fabric.on"object:added", function( ) {
                    var 
item e.target;
                    var 
state _this.deepMergeitem.saveState().originalState, {
                        
cfg: {
                            
color_this.drawing.color,
                            
width_this.drawing.width,
                            
opacity_this.drawing.opacity,
                            
fontSize_this.drawing.fontSize
                        
}
                    } );

                    if ( 
Number( new Date() ) - _this.drawing.buffer.pressedTS 200 && !item.noUndo ) {
                        
_this.setup.fabric.removeitem );
                        
_this.setup.fabric.renderAll();
                        return;
                    }

                    
state JSON.stringifystate );
                    
item.recentState state;

                    if ( 
item.selectable && !item.known && !item.noUndo ) {
                        
_this.drawing.undos.push( {
                            
action"added",
                            
targetitem,
                            
statestate
                        
} );
                        
_this.drawing.undos.push( {
                            
action"addified",
                            
targetitem,
                            
statestate
                        
} );
                        
_this.drawing.redos = [];
                    }

                    
item.known true;
                    
_this.setup.fabric.isDrawingMode true;
                } );
                
_this.setup.fabric.on"object:modified", function( ) {
                    var 
item e.target;
                    var 
recentState JSON.parseitem.recentState );
                    var 
state _this.deepMergeitem.saveState().originalState, {
                        
cfgrecentState.cfg
                    
} );

                    
state JSON.stringifystate );
                    
item.recentState state;

                    
_this.drawing.undos.push( {
                        
action"modified",
                        
targetitem,
                        
statestate
                    
} );

                    
_this.drawing.redos = [];
                } );
                
_this.setup.fabric.on"text:changed", function( ) {
                    var 
item e.target;
                    
clearTimeoutitem.timer );
                    
item.timer setTimeout( function() {
                        var 
state JSON.stringifyitem.saveState().originalState );

                        
item.recentState state;

                        
_this.drawing.redos = [];
                        
_this.drawing.undos.push( {
                            
action"modified",
                            
targetitem,
                            
statestate
                        
} );
                    }, 
250 );
                } );

                
// DRAWING
                
if ( _this.drawing.buffer.enabled ) {
                    
_this.setup.wrapper.setAttribute"class"_this.setup.chart.classNamePrefix "-export-canvas active" );
                    
_this.setup.wrapper.style.backgroundColor cfg.backgroundColor;
                    
_this.setup.wrapper.style.display "block";

                } else {
                    
_this.setup.wrapper.setAttribute"class"_this.setup.chart.classNamePrefix "-export-canvas" );
                    
_this.setup.wrapper.style.display "none";
                }

                for ( 
i1 0i1 groups.lengthi1++ ) {
                    var 
group groupsi1 ];
                    var 
isLegend _this.gatherClassNamegroup.parent_this.setup.chart.classNamePrefix "-legend-div");
                    var 
isPanel _this.gatherClassNamegroup.parent_this.setup.chart.classNamePrefix "-stock-panel-div" );
                    var 
isScrollbar _this.gatherClassNamegroup.parent_this.setup.chart.classNamePrefix "-scrollbar-chart-div" );

                    
// STOCK CHART; SVG OFFSET;; SVG OFFSET
                    
if ( _this.setup.chart.type == "stock" && _this.setup.chart.legendSettings.position ) {

                        
// TOP / BOTTOM
                        
if ( [ "top""bottom" ].indexOf_this.setup.chart.legendSettings.position ) != -) {

                            
// POSITION; ABSOLUTE
                            
if ( group.parent.style.top && group.parent.style.left ) {
                                
group.offset._this.pxToNumbergroup.parent.style.top );
                                
group.offset._this.pxToNumbergroup.parent.style.left );

                                
// POSITION; RELATIVE
                            
} else {
                                
group.offset.offset.x;
                                
group.offset.offset.y;
                                
offset.+= _this.pxToNumbergroup.parent.style.height );

                                
// LEGEND; OFFSET
                                
if ( isPanel ) {
                                    
offset.pY _this.pxToNumberisPanel.style.marginTop );
                                    
group.offset.+= offset.pY;

                                    
// SCROLLBAR; OFFSET
                                
} else if ( isScrollbar ) {
                                    
group.offset.+= offset.pY;
                                }
                            }

                            
// LEFT / RIGHT
                        
} else if ( [ "left""right" ].indexOf_this.setup.chart.legendSettings.position ) != -) {
                            
group.offset._this.pxToNumbergroup.parent.style.top ) + offset.pY;
                            
group.offset._this.pxToNumbergroup.parent.style.left ) + offset.pX;

                            
// LEGEND; OFFSET
                            
if ( isLegend ) {
                                
offset.pY += _this.pxToNumberisPanel.style.height ) + _this.setup.chart.panelsSettings.panelSpacing;

                                
// SCROLLBAR; OFFSET
                            
} else if ( isScrollbar ) {
                                
group.offset.-= _this.setup.chart.panelsSettings.panelSpacing;
                            }
                        }

                        
// REGULAR CHARTS; SVG OFFSET
                    
} else {
                        
// POSITION; ABSOLUTE
                        
if ( group.parent.style.position == "absolute" ) {
                            
group.offset.absolute true;
                            
group.offset.top _this.pxToNumbergroup.parent.style.top );
                            
group.offset.right _this.pxToNumbergroup.parent.style.righttrue );
                            
group.offset.bottom _this.pxToNumbergroup.parent.style.bottomtrue );
                            
group.offset.left _this.pxToNumbergroup.parent.style.left );
                            
group.offset.width _this.pxToNumbergroup.parent.style.width );
                            
group.offset.height _this.pxToNumbergroup.parent.style.height );

                            
// POSITION; RELATIVE
                        
} else if ( group.parent.style.top && group.parent.style.left ) {
                            
group.offset._this.pxToNumbergroup.parent.style.top );
                            
group.offset._this.pxToNumbergroup.parent.style.left );

                            
// POSITION; GENERIC
                        
} else {

                            
// EXTERNAL LEGEND
                            
if ( group.legend ) {
                                if ( 
group.legend.position == "left" ) {
                                    
offset.+= group.legend.width;
                                } else if ( 
group.legend.position == "right" ) {
                                    
group.offset.+= offset.width group.legend.width;
                                } else if ( 
group.legend.position == "top" ) {
                                    
offset.+= group.legend.height;
                                } else if ( 
group.legend.position == "bottom" ) {
                                    
group.offset.+= offset.height group.legend.height// OFFSET.Y
                                
}

                                
// NORMAL
                            
} else {
                                
group.offset.offset.x;
                                
group.offset.offset.offset.pY;
                                
offset.+= _this.pxToNumbergroup.parent.style.height );
                            }
                        }

                        
// PANEL OFFSET (STOCK CHARTS)
                        
if ( isLegend && isPanel && isPanel.style.marginTop ) {
                            
offset.+= _this.pxToNumberisPanel.style.marginTop );
                            
group.offset.+= _this.pxToNumberisPanel.style.marginTop );    

                        
// GENERAL LEFT / RIGHT POSITION
                        
} else if ( _this.setup.chart.legend && [ "left""right" ].indexOf_this.setup.chart.legend.position ) != -) {
                            
group.offset._this.pxToNumbergroup.parent.style.top );
                            
group.offset._this.pxToNumbergroup.parent.style.left );
                        }
                    }

                    
// ADD TO CANVAS
                    
fabric.parseSVGDocumentgroup.svg, ( function( group ) {
                        return function( 
objectsoptions ) {
                            var 
i1;
                            var 
fabric.util.groupSVGElementsobjectsoptions );
                            var 
paths = [];
                            var 
tmp = {
                                
selectablefalse
                            
};

                            
// GROUP OFFSET; ABSOLUTE
                            
if ( group.offset.absolute ) {
                                if ( 
group.offset.bottom !== undefined ) {
                                    
tmp.top offset.height group.offset.height group.offset.bottom;
                                } else {
                                    
tmp.top group.offset.top;
                                }

                                if ( 
group.offset.right !== undefined ) {
                                    
tmp.left offset.width group.offset.width group.offset.right;
                                } else {
                                    
tmp.left group.offset.left;
                                }

                                
// GROUP OFFSET; REGULAR
                            
} else {
                                
tmp.top group.offset.y;
                                
tmp.left group.offset.x;
                            }

                            
// WALKTHROUGH ELEMENTS
                            
for ( i1 0i1 g.paths.lengthi1++ ) {
                                var 
PID null;

                                
// OPACITY; TODO: DISTINGUISH OPACITY TYPES
                                
if ( g.pathsi1 ] ) {

                                    
// CHECK ORIGIN; REMOVE TAINTED
                                    
if ( cfg.removeImages && _this.isTaintedg.pathsi1 ][ "xlink:href" ] ) ) {
                                        continue;
                                    }

                                    
// SET OPACITY
                                    
if ( g.pathsi1 ].fill instanceof Object ) {

                                        
// MISINTERPRETATION OF FABRIC
                                        
if ( g.pathsi1 ].fill.type == "radial" ) {

                                            
// PIE EXCEPTION
                                            
if ( _this.setup.chart.type == "pie" ) {
                                                var 
tmp_n g.pathsi1 ];
                                                var 
tmp_c tmp_n.getCenterPoint();
                                                var 
tmp_cp tmp_n.group.getCenterPoint();
                                                var 
tmp_cd = {
                                                    
xtmp_n.pathOffset.tmp_cp.x,
                                                    
ytmp_n.pathOffset.tmp_cp.y
                                                
};

                                                
g.pathsi1 ].fill.gradientTransform] = tmp_n.pathOffset.tmp_cd.x;
                                                
g.pathsi1 ].fill.gradientTransform] = tmp_n.pathOffset.tmp_cd.y;

                                                
// OTHERS
                                            
} else {
                                                
g.pathsi1 ].fill.coords.r2 g.pathsi1 ].fill.coords.r1 * -1;
                                                
g.pathsi1 ].fill.coords.r1 0;
                                                
g.pathsi1 ].set( {
                                                    
opacityg.pathsi1 ].fillOpacity
                                                
} );
                                            }
                                        }

                                        
// FILLING; TODO: DISTINGUISH OPACITY TYPES
                                    
} else if ( PID _this.isHashbangedg.pathsi1 ].fill ) ) {

                                        
// PATTERN
                                        
if ( group.patterns && group.patternsPID ] ) {

                                            var 
props group.patternsPID ];

                                            
// LOAD IMAGE MANUALLY; TO RERENDER THE CANVAS
                                            
fabric.Image.fromURLprops.source, ( function( propsi1 ) {
                                                return function( 
img ) {
                                                    
images.loaded++;

                                                    var 
pattern null;
                                                    var 
patternSourceCanvas = new fabric.StaticCanvasundefined, {
                                                        
backgroundColorprops.fill
                                                    
} );
                                                    
patternSourceCanvas.addimg );

                                                    
pattern = new fabric.Pattern( {
                                                        
source: function() {
                                                            
patternSourceCanvas.setDimensions( {
                                                                
widthprops.width,
                                                                
heightprops.height
                                                            
} );
                                                            return 
patternSourceCanvas.getElement();
                                                        },
                                                        
repeat'repeat'
                                                    
} );

                                                    
g.pathsi1 ].set( {
                                                        
fillpattern,
                                                        
opacityg.pathsi1 ].fillOpacity
                                                    
} );
                                                }
                                            } )( 
propsi1 ) );
                                        }
                                    }

                                    
// CLIPPATH;
                                    
if ( PID _this.isHashbangedg.pathsi1 ].clipPath ) ) {

                                        if ( 
group.clippings && group.clippingsPID ] ) {

                                            
// TODO: WAIT UNTIL FABRICJS HANDLES CLIPPATH FOR SVG OUTPUT
                                            
( function( i1PID ) {
                                                var 
toSVG g.pathsi1 ].toSVG;

                                                
g.pathsi1 ].toSVG = function( original_reviver ) {
                                                    return 
toSVG.applythis, [ function( string ) {
                                                        return 
original_reviverstringgroup.clippingsPID ] );
                                                    } ] );
                                                }
                                            } )( 
i1PID );

                                            
g.pathsi1 ].set( {
                                                
clipTo: ( function( i1PID ) {
                                                    return function( 
ctx ) {
                                                        var 
cp group.clippingsPID ];
                                                        var 
tm this.transformMatrix || [ 10010];
                                                        var 
dim = {
                                                            
topcp.bbox.y,
                                                            
leftcp.bbox.x,
                                                            
widthcp.bbox.width,
                                                            
heightcp.bbox.height
                                                        
}

                                                        if ( 
_this.setup.chart.type == "map" ) {
                                                            
dim.top += cp.transform];
                                                            
dim.left += cp.transform];
                                                        }

                                                        if ( 
cp.bbox.&& tm] && cp.bbox.&& tm] ) {
                                                            
dim.top -= tm];
                                                            
dim.left -= tm];
                                                        }

                                                        
ctx.rectdim.leftdim.topdim.widthdim.height );
                                                    }
                                                } )( 
i1PID )
                                            } );
                                        }
                                    }

                                    
// TODO; WAIT FOR TSPAN SUPPORT FROM FABRICJS SIDE
                                    
if ( g.pathsi1 ].TSPANWORKAROUND ) {
                                        var 
parsedAttributes fabric.parseAttributesg.pathsi1 ].svgfabric.Text.ATTRIBUTE_NAMES );
                                        var 
options fabric.util.object.extend( {}, parsedAttributes );

                                        
// CREATE NEW SET
                                        
var tmpBuffer = [];
                                        for ( var 
0g.pathsi1 ].svg.childNodes.lengthi++ ) {
                                            var 
textNode g.pathsi1 ].svg.childNodes];
                                            var 
textElement fabric.Text.fromElementtextNodeoptions );

                                            
textElement.set( {
                                                
left0
                                            
} );

                                            
tmpBuffer.pushtextElement );
                                        }

                                        
// HIDE ORIGINAL ELEMENT
                                        
g.pathsi1 ].set( {
                                            
opacity0
                                        
} );

                                        
// REPLACE BY GROUP AND CANCEL FIRST OFFSET
                                        
var tmpGroup = new fabric.GrouptmpBuffer, {
                                            
topg.pathsi1 ].top * -1
                                        
} );
                                        
g.pathsi1 ] = tmpGroup;
                                    }
                                }
                                
paths.pushg.pathsi1 ] );
                            }

                            
// REPLACE WITH WHITELIST
                            
g.paths paths;

                            
// SET PROPS
                            
g.settmp );

                            
// ADD TO CANVAS
                            
_this.setup.fabric.add);

                            
// ADD BALLOONS
                            
if ( group.svg.parentNode && group.svg.parentNode.getElementsByTagName ) {
                                var 
balloons group.svg.parentNode.getElementsByClassName_this.setup.chart.classNamePrefix "-balloon-div" );
                                for ( 
i1 0i1 balloons.lengthi1++ ) {
                                    if ( 
cfg.balloonFunction instanceof Function ) {
                                        
cfg.balloonFunction.apply_this, [ balloonsi1 ], group ] );
                                    } else {
                                        var 
elm_parent balloonsi1 ];
                                        var 
style_parent fabric.parseStyleAttributeelm_parent );
                                        var 
style_text fabric.parseStyleAttributeelm_parent.childNodes] );
                                        var 
fabric_label = new fabric.Textelm_parent.innerText || elm_parent.textContent || elm_parent.innerHTML, {
                                            
selectablefalse,
                                            
topstyle_parent.top group.offset.y,
                                            
leftstyle_parent.left group.offset.x,
                                            
fillstyle_text"color" ],
                                            
fontSizestyle_text"fontSize" ],
                                            
fontFamilystyle_text"fontFamily" ],
                                            
textAlignstyle_text"text-align" ]
                                        } );

                                        
_this.setup.fabric.addfabric_label );
                                    }
                                }
                            }

                            if ( 
group.svg.nextSibling && group.svg.nextSibling.tagName == "A" ) {
                                var 
elm_parent group.svg.nextSibling;
                                var 
style_parent fabric.parseStyleAttributeelm_parent );
                                var 
fabric_label = new fabric.Textelm_parent.innerText || elm_parent.textContent || elm_parent.innerHTML, {
                                    
selectablefalse,
                                    
topstyle_parent.top group.offset.y,
                                    
leftstyle_parent.left group.offset.x,
                                    
fillstyle_parent"color" ],
                                    
fontSizestyle_parent"fontSize" ],
                                    
fontFamilystyle_parent"fontFamily" ],
                                    
opacitystyle_parent"opacity" ]
                                } );

                                
_this.setup.fabric.addfabric_label );
                            }

                            
groups.pop();

                            
// TRIGGER CALLBACK WITH SAFETY DELAY
                            
if ( !groups.length ) {
                                var 
timer setInterval( function() {
                                    if ( 
images.loaded == images.included ) {
                                        
clearTimeouttimer );
                                        
_this.handleBordercfg );
                                        
_this.handleCallbackcfg.afterCapturecfg );
                                        
_this.setup.fabric.renderAll();
                                        
_this.handleCallbackcallbackcfg );
                                    }
                                }, 
AmCharts.updateRate );
                            }
                        }

                        
// IDENTIFY ELEMENTS THROUGH CLASSNAMES
                    
} )( group ), function( svgobj ) {
                        var 
i1;
                        var 
className _this.gatherAttributesvg"class" );
                        var 
visibility _this.gatherAttributesvg"visibility" );
                        var 
clipPath _this.gatherAttributesvg"clip-path" );

                        
obj.className StringclassName );
                        
obj.classList StringclassName ).split" " );
                        
obj.clipPath clipPath;
                        
obj.svg svg;

                        
// TODO; WAIT FOR TSPAN SUPPORT FROM FABRICJS SIDE
                        
if ( svg.tagName == "text" && svg.childNodes.length ) {
                            
obj.TSPANWORKAROUND true;
                        }

                        
// HIDE HIDDEN ELEMENTS; TODO: FIND A BETTER WAY TO HANDLE THAT
                        
if ( visibility == "hidden" ) {
                            
obj.opacity 0;

                            
// WALKTHROUGH ELEMENTS
                        
} else {

                            
// TRANSPORT FILL/STROKE OPACITY
                            
var attrs = [ "fill""stroke" ];
                            for ( 
i1 0i1 attrs.lengthi1++ ) {
                                var 
attr attrsi1 ]
                                var 
attrVal Stringsvg.getAttributeattr ) || "" );
                                var 
attrOpacity Numbersvg.getAttributeattr "-opacity" ) || "1" );
                                var 
attrRGBA fabric.Color.fromHexattrVal ).getSource();

                                
// EXCEPTION
                                
if ( obj.classList.indexOf_this.setup.chart.classNamePrefix "-guide-fill" ) != -&& !attrVal ) {
                                    
attrOpacity 0;
                                    
attrRGBA fabric.Color.fromHex"#000000" ).getSource();
                                }

                                if ( 
attrRGBA ) {
                                    
attrRGBA.pop();
                                    
attrRGBA.pushattrOpacity )
                                    
objattr ] = "rgba(" attrRGBA.join() + ")";
                                    
objattr _this.capitalize"opacity" ) ] = attrOpacity;
                                }
                            }
                        }

                        
// REVIVER
                        
_this.handleCallbackcfg.reviverobjsvg );
                    } );
                }
            },

            
/**
             * Returns the current canvas
             */
            
toCanvas: function( optionscallback ) {
                var 
cfg _this.deepMerge( {
                    
// NUFFIN
                
}, options || {} );
                var 
data _this.setup.canvas;

                
_this.handleCallbackcallbackdata );

                return 
data;
            },

            
/**
             * Returns an image; by default PNG
             */
            
toImage: function( optionscallback ) {
                var 
cfg _this.deepMerge( {
                    
format"png",
                    
quality1,
                    
multiplierthis.config.multiplier
                
}, options || {} );
                var 
data cfg.data;
                var 
img document.createElement"img" );

                if ( !
cfg.data ) {
                    if ( 
cfg.lossless || cfg.format == "svg" ) {
                        
data _this.toSVG_this.deepMergecfg, {
                            
getBase64true
                        
} ) );
                    } else {
                        
data _this.setup.fabric.toDataURLcfg );
                    }
                }

                
img.setAttribute"src"data );

                
_this.handleCallbackcallbackimg );

                return 
img;
            },

            
/**
             * Generates a blob instance image; returns base64 datastring
             */
            
toBlob: function( optionscallback ) {
                var 
cfg _this.deepMerge( {
                    
data"empty",
                    
type"text/plain"
                
}, options || {} );
                var 
data;
                var 
isBase64 = /^data:.+;base64,(.*)$/.execcfg.data );

                
// GATHER BODY
                
if ( isBase64 ) {
                    
cfg.data isBase64];
                    
cfg.type cfg.data.slice5cfg.data.indexOf"," ) - );
                    
cfg.data _this.toByteArray( {
                        
datacfg.data.slicecfg.data.indexOf"," ) + 1cfg.data.length )
                    } );
                }

                if ( 
cfg.getByteArray ) {
                    
data cfg.data;
                } else {
                    
data = new Blob( [ cfg.data ], {
                        
typecfg.type
                    
} );
                }

                
_this.handleCallbackcallbackdata );

                return 
data;
            },

            
/**
             * Generates JPG image; returns base64 datastring
             */
            
toJPG: function( optionscallback ) {
                var 
cfg _this.deepMerge( {
                    
format"jpeg",
                    
quality1,
                    
multiplierthis.config.multiplier
                
}, options || {} );
                
cfg.format cfg.format.toLowerCase();
                var 
data _this.setup.fabric.toDataURLcfg );

                
_this.handleCallbackcallbackdata );

                return 
data;
            },

            
/**
             * Generates PNG image; returns base64 datastring
             */
            
toPNG: function( optionscallback ) {
                var 
cfg _this.deepMerge( {
                    
format"png",
                    
quality1,
                    
multiplierthis.config.multiplier
                
}, options || {} );
                var 
data _this.setup.fabric.toDataURLcfg );

                
_this.handleCallbackcallbackdata );

                return 
data;
            },

            
/**
             * Generates SVG image; returns base64 datastring
             */
            
toSVG: function( optionscallback ) {
                var 
clipPaths = [];
                var 
cfg _this.deepMerge( {
                    
reviver: function( stringclipPath ) {
                        var 
matcher = new RegExp( /bstyle=(['"])(.*?)1/ );
                        var match = matcher.exec( string )[ 0 ].slice( 7, -1 );
                        var styles = match.split( ";" );
                        var replacement = [];

                        // BEAUTIFY STYLES
                        for ( i1 = 0; i1 < styles.length; i1++ ) {
                            if ( styles[ i1 ] ) {
                                var pair = styles[ i1 ].replace( /s/g, "" ).split( ":" );
                                var key = pair[ 0 ];
                                var value = pair[ 1 ];

                                if ( [ "fill", "stroke" ].indexOf( key ) != -1 ) {
                                    value = fabric.Color.fromRgba( value );
                                    if ( value && value._source ) {
                                        var color = "#" + value.toHex();
                                        var opacity = value._source[ 3 ];

                                        replacement.push( [ key, color ].join( ":" ) );
                                        replacement.push( [ key + "-opacity", opacity ].join( ":" ) );
                                    } else {
                                        replacement.push( styles[ i1 ] );
                                    }
                                } else if ( key != "opactiy" ) {
                                    replacement.push( styles[ i1 ] );
                                }
                            }
                        }
                        string = string.replace( match, replacement.join( ";" ) );

                        // TODO: WAIT UNTIL FABRICJS HANDLES CLIPPATH FOR SVG OUTPUT
                        if ( clipPath ) {
                            var sliceOffset = 2;
                            var end = string.slice( -sliceOffset );

                            if ( end != "/>" ) {
                                sliceOffset = 3;
                                end = string.slice( -sliceOffset );
                            }

                            var start = string.slice( 0, string.length - sliceOffset );
                            var clipPathAttr = " clip-path="url(#" + clipPath.svg.id + ")" ";
                            var clipPathString = new XMLSerializer().serializeToString( clipPath.svg );

                            string = start + clipPathAttr + end;

                            clipPaths.push( clipPathString );
                        }

                        return string;
                    }
                }, options || {} );
                var data = _this.setup.fabric.toSVG( cfg, cfg.reviver );

                // TODO: WAIT UNTIL FABRICJS HANDLES CLIPPATH FOR SVG OUTPUT
                if ( clipPaths.length ) {
                    var start = data.slice( 0, data.length - 6 );
                    var end = data.slice( -6 );
                    data = start + clipPaths.join( "" ) + end;
                }

                if ( cfg.getBase64 ) {
                    data = "data:image/svg+xml;base64," + btoa( data );
                }

                _this.handleCallback( callback, data );

                return data;
            },

            /**
             * Generates PDF; returns base64 datastring
             */
            toPDF: function( options, callback ) {
                var cfg = _this.deepMerge( _this.deepMerge( {
                    multiplier: 2
                }, _this.config.pdfMake ), options || {}, true );
                cfg.images.reference = _this.toPNG( cfg );
                var data = new pdfMake.createPdf( cfg );

                if ( callback ) {
                    data.getDataUrl( ( function( callback ) {
                        return function() {
                            callback.apply( _this, arguments );
                        }
                    } )( callback ) );
                }

                return data;
            },

            /**
             * Generates an image; hides all elements on page to trigger native print method
             */
            toPRINT: function( options, callback ) {
                var i1;
                var cfg = _this.deepMerge( {
                    delay: 1,
                    lossless: false
                }, options || {} );
                var data = _this.toImage( cfg );
                var states = [];
                var items = document.body.childNodes;

                data.setAttribute( "style", "width: 100%; max-height: 100%;" );

                for ( i1 = 0; i1 < items.length; i1++ ) {
                    if ( _this.isElement( items[ i1 ] ) ) {
                        states[ i1 ] = items[ i1 ].style.display;
                        items[ i1 ].style.display = "none";
                    }
                }

                document.body.appendChild( data );
                window.print();

                setTimeout( function() {
                    for ( i1 = 0; i1 < items.length; i1++ ) {
                        if ( _this.isElement( items[ i1 ] ) ) {
                            items[ i1 ].style.display = states[ i1 ];
                        }
                    }
                    document.body.removeChild( data );
                    _this.handleCallback( callback, data );
                }, cfg.delay );

                return data;
            },

            /**
             * Generates JSON string
             */
            toJSON: function( options, callback ) {
                var cfg = _this.deepMerge( {
                    dateFormat: _this.config.dateFormat || "dateObject",
                }, options || {}, true );
                cfg.data = cfg.data ? cfg.data : _this.getChartData( cfg );
                var data = JSON.stringify( cfg.data, undefined, "t" );

                _this.handleCallback( callback, data );

                return data;
            },

            /**
             * Generates CSV string
             */
            toCSV: function( options, callback ) {
                var row, col;
                var cfg = _this.deepMerge( {
                    data: _this.getChartData( options ),
                    delimiter: ",",
                    quotes: true,
                    escape: true,
                    withHeader: true
                }, options || {}, true );
                var data = "";
                var cols = [];
                var buffer = [];

                function enchant( value, column ) {

                    // WRAP IN QUOTES
                    if ( typeof value === "string" ) {
                        if ( cfg.escape ) {
                            value = value.replace( '"', '""' );
                        }
                        if ( cfg.quotes ) {
                            value = [ '"', value, '"' ].join( "" );
                        }
                    }

                    return value;
                }

                // HEADER
                for ( value in cfg.data[ 0 ] ) {
                    buffer.push( enchant( value ) );
                    cols.push( value );
                }
                if ( cfg.withHeader ) {
                    data += buffer.join( cfg.delimiter ) + "
n";
                }

                // BODY
                for ( row in cfg.data ) {
                    buffer = [];
                    if ( !isNaN( row ) ) {
                        for ( col in cols ) {
                            if ( !isNaN( col ) ) {
                                var column = cols[ col ];
                                var value = cfg.data[ row ][ column ];

                                buffer.push( enchant( value, column ) );
                            }
                        }
                        data += buffer.join( cfg.delimiter ) + "
n";
                    }
                }

                _this.handleCallback( callback, data );

                return data;
            },

            /**
             * Generates excel sheet; returns base64 datastring
             */
            toXLSX: function( options, callback ) {
                var cfg = _this.deepMerge( {
                    name: "
amCharts",
                    dateFormat: _this.config.dateFormat || "
dateObject",
                    withHeader: true,
                    stringify: false
                }, options || {}, true );
                var data = "";
                var wb = {
                    SheetNames: [],
                    Sheets: {}
                }

                cfg.data = cfg.data ? cfg.data : _this.getChartData( cfg );

                function datenum( v, date1904 ) {
                    if ( date1904 ) v += 1462;
                    var epoch = Date.parse( v );
                    return ( epoch - new Date( Date.UTC( 1899, 11, 30 ) ) ) / ( 24 * 60 * 60 * 1000 );
                }

                function sheet_from_array_of_arrays( data, opts ) {
                    var ws = {};
                    var range = {
                        s: {
                            c: 10000000,
                            r: 10000000
                        },
                        e: {
                            c: 0,
                            r: 0
                        }
                    };
                    for ( var R = 0; R != data.length; ++R ) {
                        for ( var C = 0; C != data[ R ].length; ++C ) {
                            if ( range.s.r > R ) range.s.r = R;
                            if ( range.s.c > C ) range.s.c = C;
                            if ( range.e.r < R ) range.e.r = R;
                            if ( range.e.c < C ) range.e.c = C;
                            var cell = {
                                v: data[ R ][ C ]
                            };
                            if ( cell.v == null ) continue;
                            var cell_ref = XLSX.utils.encode_cell( {
                                c: C,
                                r: R
                            } );

                            if ( typeof cell.v === "
number" ) cell.t = "n";
                            else if ( typeof cell.v === "
boolean" ) cell.t = "b";
                            else if ( cell.v instanceof Date ) {
                                cell.t = "
n";
                                cell.z = XLSX.SSF._table[ 14 ];
                                cell.v = datenum( cell.v );
                            } else cell.t = "
s";

                            ws[ cell_ref ] = cell;
                        }
                    }
                    if ( range.s.c < 10000000 ) ws[ "
!ref" ] = XLSX.utils.encode_range( range );
                    return ws;
                }

                wb.SheetNames.push( cfg.name );
                wb.Sheets[ cfg.name ] = sheet_from_array_of_arrays( _this.toArray( cfg ) );

                data = XLSX.write( wb, {
                    bookType: "
xlsx",
                    bookSST: true,
                    type: "
base64"
                } );

                data = "
data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64," + data;

                _this.handleCallback( callback, data );

                return data;
            },

            /**
             * Generates an array of arrays
             */
            toArray: function( options, callback ) {
                var row, col;
                var cfg = _this.deepMerge( {
                    data: _this.getChartData( options ),
                    withHeader: false,
                    stringify: true
                }, options || {}, true );
                var data = [];
                var cols = [];

                // HEADER
                for ( col in cfg.data[ 0 ] ) {
                    cols.push( col );
                }
                if ( cfg.withHeader ) {
                    data.push( cols );
                }

                // BODY
                for ( row in cfg.data ) {
                    var buffer = [];
                    if ( !isNaN( row ) ) {
                        for ( col in cols ) {
                            if ( !isNaN( col ) ) {
                                var col = cols[ col ];
                                var value = cfg.data[ row ][ col ];
                                if ( value == null ) {
                                    value = "";
                                } else if ( cfg.stringify ) {
                                    value = String( value );
                                } else {
                                    value = value;
                                }
                                buffer.push( value );
                            }
                        }
                        data.push( buffer );
                    }
                }

                _this.handleCallback( callback, data );

                return data;
            },

            /**
             * Generates byte array with given base64 datastring; returns byte array
             */
            toByteArray: function( options, callback ) {
                var cfg = _this.deepMerge( {
                    // NUFFIN
                }, options || {} );
                var Arr = ( typeof Uint8Array !== 'undefined' ) ? Uint8Array : Array
                var PLUS = '+'.charCodeAt( 0 )
                var SLASH = '/'.charCodeAt( 0 )
                var NUMBER = '0'.charCodeAt( 0 )
                var LOWER = 'a'.charCodeAt( 0 )
                var UPPER = 'A'.charCodeAt( 0 )
                var data = b64ToByteArray( cfg.data );

                function decode( elt ) {
                    var code = elt.charCodeAt( 0 )
                    if ( code === PLUS )
                        return 62 // '+'
                    if ( code === SLASH )
                        return 63 // '/'
                    if ( code < NUMBER )
                        return -1 //no match
                    if ( code < NUMBER + 10 )
                        return code - NUMBER + 26 + 26
                    if ( code < UPPER + 26 )
                        return code - UPPER
                    if ( code < LOWER + 26 )
                        return code - LOWER + 26
                }

                function b64ToByteArray( b64 ) {
                    var i, j, l, tmp, placeHolders, arr

                    if ( b64.length % 4 > 0 ) {
                        throw new Error( 'Invalid string. Length must be a multiple of 4' )
                    }

                    // THE NUMBER OF EQUAL SIGNS (PLACE HOLDERS)
                    // IF THERE ARE TWO PLACEHOLDERS, THAN THE TWO CHARACTERS BEFORE IT
                    // REPRESENT ONE BYTE
                    // IF THERE IS ONLY ONE, THEN THE THREE CHARACTERS BEFORE IT REPRESENT 2 BYTES
                    // THIS IS JUST A CHEAP HACK TO NOT DO INDEXOF TWICE
                    var len = b64.length
                    placeHolders = '=' === b64.charAt( len - 2 ) ? 2 : '=' === b64.charAt( len - 1 ) ? 1 : 0

                    // BASE64 IS 4/3 + UP TO TWO CHARACTERS OF THE ORIGINAL DATA
                    arr = new Arr( b64.length * 3 / 4 - placeHolders )

                    // IF THERE ARE PLACEHOLDERS, ONLY GET UP TO THE LAST COMPLETE 4 CHARS
                    l = placeHolders > 0 ? b64.length - 4 : b64.length

                    var L = 0

                    function push( v ) {
                        arr[ L++ ] = v
                    }

                    for ( i = 0, j = 0; i < l; i += 4, j += 3 ) {
                        tmp = ( decode( b64.charAt( i ) ) << 18 ) | ( decode( b64.charAt( i + 1 ) ) << 12 ) | ( decode( b64.charAt( i + 2 ) ) << 6 ) | decode( b64.charAt( i + 3 ) )
                        push( ( tmp & 0xFF0000 ) >> 16 )
                        push( ( tmp & 0xFF00 ) >> 8 )
                        push( tmp & 0xFF )
                    }

                    if ( placeHolders === 2 ) {
                        tmp = ( decode( b64.charAt( i ) ) << 2 ) | ( decode( b64.charAt( i + 1 ) ) >> 4 )
                        push( tmp & 0xFF )
                    } else if ( placeHolders === 1 ) {
                        tmp = ( decode( b64.charAt( i ) ) << 10 ) | ( decode( b64.charAt( i + 1 ) ) << 4 ) | ( decode( b64.charAt( i + 2 ) ) >> 2 )
                        push( ( tmp >> 8 ) & 0xFF )
                        push( tmp & 0xFF )
                    }

                    return arr
                }

                _this.handleCallback( callback, data );

                return data;
            },

            /**
             * Callback handler; injects additional arguments to callback
             */
            handleCallback: function( callback ) {
                var i1, data = Array();
                if ( callback && callback instanceof Function ) {
                    for ( i1 = 0; i1 < arguments.length; i1++ ) {
                        if ( i1 > 0 ) {
                            data.push( arguments[ i1 ] );
                        }
                    }
                    callback.apply( _this, data );
                }
            },

            /**
             * Border handler; injects additional border to canvas
             */
            handleBorder: function( options ) {
                if ( _this.config.border instanceof Object ) {
                    var cfg = _this.deepMerge( _this.defaults.fabric.border, options.border || {}, true );
                    var border = new fabric.Rect();

                    cfg.width = _this.setup.fabric.width - cfg.strokeWidth;
                    cfg.height = _this.setup.fabric.height - cfg.strokeWidth;

                    border.set( cfg );

                    _this.setup.fabric.add( border );
                }
            },

            /**
             * Handles drag/drop events; loads given imagery
             */
            handleDropbox: function( e ) {
                if ( _this.drawing.buffer.enabled ) {
                    e.preventDefault();
                    e.stopPropagation();

                    // DRAG OVER
                    if ( e.type == "
dragover" ) {
                        _this.setup.wrapper.setAttribute( "
class", _this.setup.chart.classNamePrefix + "-export-canvas active dropbox" );

                        // DRAGLEAVE; DROP
                    } else {
                        _this.setup.wrapper.setAttribute( "
class", _this.setup.chart.classNamePrefix + "-export-canvas active" );

                        if ( e.type == "
drop" && e.dataTransfer.files.length ) {
                            for ( var i1 = 0; i1 < e.dataTransfer.files.length; i1++ ) {
                                var reader = new FileReader();
                                reader.onloadend = ( function( index ) {
                                    return function() {
                                        _this.drawing.handler.add( {
                                            url: reader.result,
                                            top: e.layerY - ( index * 10 ),
                                            left: e.layerX - ( index * 10 )
                                        } );
                                    }
                                } )( i1 );
                                reader.readAsDataURL( e.dataTransfer.files[ i1 ] );
                            }
                        }
                    }
                }
            },

            /**
             * Gathers chart data according to its type
             */
            getChartData: function( options ) {
                var cfg = _this.deepMerge( {
                    data: [],
                    titles: {},
                    dateFields: [],
                    dataFields: [],
                    dataFieldsMap: {},
                    exportTitles: _this.config.exportTitles,
                    exportFields: _this.config.exportFields,
                    exportSelection: _this.config.exportSelection,
                    columnNames: _this.config.columnNames
                }, options || {}, true );
                var uid, i1, i2, i3;
                var lookupFields = [ "
valueField", "openField", "closeField", "highField", "lowField", "xField", "yField" ];

                // HANDLE FIELDS
                function addField( field, title, type ) {

                    function checkExistance( field, type ) {
                        if ( cfg.dataFields.indexOf( field ) != -1 ) {
                            return checkExistance( [ field, "
.", type ].join( "" ) );
                        }
                        return field;
                    }

                    if ( field && cfg.exportTitles && _this.setup.chart.type != "
gantt" ) {
                        uid = checkExistance( field, type );
                        cfg.dataFieldsMap[ uid ] = field;
                        cfg.dataFields.push( uid );
                        cfg.titles[ uid ] = title || uid;
                    }
                }

                if ( cfg.data.length == 0 ) {
                    // STOCK DATA; GATHER COMPARED GRAPHS
                    if ( _this.setup.chart.type == "
stock" ) {
                        cfg.data = _this.setup.chart.mainDataSet.dataProvider;

                        // CATEGORY AXIS
                        addField( _this.setup.chart.mainDataSet.categoryField );
                        cfg.dateFields.push( _this.setup.chart.mainDataSet.categoryField );

                        // WALKTHROUGH GRAPHS
                        for ( i1 = 0; i1 < _this.setup.chart.mainDataSet.fieldMappings.length; i1++ ) {
                            var fieldMap = _this.setup.chart.mainDataSet.fieldMappings[ i1 ];
                            for ( i2 = 0; i2 < _this.setup.chart.panels.length; i2++ ) {
                                var panel = _this.setup.chart.panels[ i2 ]
                                for ( i3 = 0; i3 < panel.stockGraphs.length; i3++ ) {
                                    var graph = panel.stockGraphs[ i3 ];

                                    for ( i4 = 0; i4 < lookupFields.length; i4++ ) {
                                        if ( graph[ lookupFields[ i4 ] ] == fieldMap.toField ) {
                                            addField( fieldMap.fromField, graph.title, lookupFields[ i4 ] );
                                        }
                                    }
                                }
                            }
                        }

                        // WALKTHROUGH COMPARISON AND MERGE IT'S DATA
                        for ( i1 = 0; i1 < _this.setup.chart.comparedGraphs.length; i1++ ) {
                            var graph = _this.setup.chart.comparedGraphs[ i1 ];
                            for ( i2 = 0; i2 < graph.dataSet.dataProvider.length; i2++ ) {
                                for ( i3 = 0; i3 < graph.dataSet.fieldMappings.length; i3++ ) {
                                    var fieldMap = graph.dataSet.fieldMappings[ i3 ];
                                    var uid = graph.dataSet.id + "
_" + fieldMap.toField;

                                    if ( i2 < cfg.data.length ) {
                                        cfg.data[ i2 ][ uid ] = graph.dataSet.dataProvider[ i2 ][ fieldMap.fromField ];

                                        if ( !cfg.titles[ uid ] ) {
                                            addField( uid, graph.dataSet.title )
                                        }
                                    }
                                }
                            }
                        }

                        // GANTT DATA; FLATTEN SEGMENTS
                    } else if ( _this.setup.chart.type == "
gantt" ) {
                        // CATEGORY AXIS
                        addField( _this.setup.chart.categoryField );
                        cfg.dateFields.push( _this.setup.chart.categoryField );

                        var field = _this.setup.chart.segmentsField;
                        for ( i1 = 0; i1 < _this.setup.chart.dataProvider.length; i1++ ) {
                            var dataItem = _this.setup.chart.dataProvider[ i1 ];
                            if ( dataItem[ field ] ) {
                                for ( i2 = 0; i2 < dataItem[ field ].length; i2++ ) {
                                    dataItem[ field ][ i2 ][ _this.setup.chart.categoryField ] = dataItem[ _this.setup.chart.categoryField ];
                                    cfg.data.push( dataItem[ field ][ i2 ] );
                                }
                            }
                        }

                        // GRAPHS
                        for ( i1 = 0; i1 < _this.setup.chart.graphs.length; i1++ ) {
                            var graph = _this.setup.chart.graphs[ i1 ];

                            for ( i2 = 0; i2 < lookupFields.length; i2++ ) {
                                var dataField = lookupFields[ i2 ];
                                var graphField = graph[ dataField ];
                                var title = graph.title;

                                addField( graphField, graph.title, dataField );
                            }
                        }

                        // PIE/FUNNEL DATA;
                    } else if ( [ "
pie", "funnel" ].indexOf( _this.setup.chart.type ) != -1 ) {
                        cfg.data = _this.setup.chart.dataProvider;

                        // CATEGORY AXIS
                        addField( _this.setup.chart.titleField );
                        cfg.dateFields.push( _this.setup.chart.titleField );

                        // VALUE
                        addField( _this.setup.chart.valueField );

                        // DEFAULT DATA;
                    } else if ( _this.setup.chart.type != "
map" ) {
                        cfg.data = _this.setup.chart.dataProvider;

                        // CATEGORY AXIS
                        if ( _this.setup.chart.categoryAxis ) {
                            addField( _this.setup.chart.categoryField, _this.setup.chart.categoryAxis.title );
                            if ( _this.setup.chart.categoryAxis.parseDates !== false ) {
                                cfg.dateFields.push( _this.setup.chart.categoryField );
                            }
                        }

                        // GRAPHS
                        for ( i1 = 0; i1 < _this.setup.chart.graphs.length; i1++ ) {
                            var graph = _this.setup.chart.graphs[ i1 ];

                            for ( i2 = 0; i2 < lookupFields.length; i2++ ) {
                                var dataField = lookupFields[ i2 ];
                                var graphField = graph[ dataField ];

                                addField( graphField, graph.title, dataField );
                            }
                        }
                    }
                }
                return _this.processData( cfg );
            },

            /**
             * Walkthrough data to format dates and titles
             */
            processData: function( options ) {
                var cfg = _this.deepMerge( {
                    data: [],
                    titles: {},
                    dateFields: [],
                    dataFields: [],
                    dataFieldsMap: {},
                    dataDateFormat: _this.setup.chart.dataDateFormat,
                    dateFormat: _this.config.dateFormat || _this.setup.chart.dataDateFormat || "
YYYY-MM-DD",
                    exportTitles: _this.config.exportTitles,
                    exportFields: _this.config.exportFields,
                    exportSelection: _this.config.exportSelection,
                    columnNames: _this.config.columnNames,
                    processData: _this.config.processData
                }, options || {}, true );
                var i1, i2;

                if ( cfg.data.length ) {
                    // GATHER MISSING FIELDS
                    for ( i1 = 0; i1 < cfg.data.length; i1++ ) {
                        for ( i2 in cfg.data[ i1 ] ) {
                            if ( cfg.dataFields.indexOf( i2 ) == -1 ) {
                                cfg.dataFields.push( i2 );
                                cfg.dataFieldsMap[ i2 ] = i2;
                            }
                        }
                    }

                    // REMOVE FIELDS SELECTIVELY
                    if ( cfg.exportFields !== undefined ) {
                        cfg.dataFields = cfg.dataFields.filter( function( n ) {
                            return cfg.exportFields.indexOf( n ) != -1;
                        } );
                    }

                    // REBUILD DATA
                    var buffer = [];
                    for ( i1 = 0; i1 < cfg.data.length; i1++ ) {
                        var tmp = {};
                        var skip = false;
                        for ( i2 = 0; i2 < cfg.dataFields.length; i2++ ) {
                            var uniqueField = cfg.dataFields[ i2 ];
                            var dataField = cfg.dataFieldsMap[ uniqueField ];
                            var title = ( cfg.columnNames && cfg.columnNames[ uniqueField ] ) || cfg.titles[ uniqueField ] || uniqueField;
                            var value = cfg.data[ i1 ][ dataField ];
                            if ( value == null ) {
                                value = undefined;
                            }

                            // TITLEFY
                            if ( cfg.exportTitles && _this.setup.chart.type != "
gantt" ) {
                                if ( title in tmp ) {
                                    title += [ "
", uniqueField, " )" ].join( "" );
                                }
                            }

                            // PROCESS CATEGORY
                            if ( cfg.dateFields.indexOf( dataField ) != -1 ) {

                                // CONVERT DATESTRING TO DATE OBJECT
                                if ( cfg.dataDateFormat && ( value instanceof String || typeof value == "
string" ) ) {
                                    value = AmCharts.stringToDate( value, cfg.dataDateFormat );

                                    // CONVERT TIMESTAMP TO DATE OBJECT
                                } else if ( cfg.dateFormat && ( value instanceof Number || typeof value == "
number" ) ) {
                                    value = new Date( value );
                                }

                                // CATEGORY RANGE
                                if ( cfg.exportSelection ) {
                                    if ( value instanceof Date ) {
                                        if ( value < chart.startDate || value > chart.endDate ) {
                                            skip = true;
                                        }

                                    } else if ( i1 < chart.startIndex || i1 > chart.endIndex ) {
                                        skip = true;
                                    }
                                }

                                // CATEGORY FORMAT
                                if ( cfg.dateFormat && cfg.dateFormat != "
dateObject" && value instanceof Date ) {
                                    value = AmCharts.formatDate( value, cfg.dateFormat );
                                }
                            }

                            tmp[ title ] = value;
                        }
                        if ( !skip ) {
                            buffer.push( tmp );
                        }
                    }
                    cfg.data = buffer;
                }

                if ( cfg.processData !== undefined ) {
                    return cfg.processData( cfg.data );

                } else {
                    return cfg.data;
                }
            },

            /**
             * Prettifies string
             */
            capitalize: function( string ) {
                return string.charAt( 0 ).toUpperCase() + string.slice( 1 ).toLowerCase();
            },

            /**
             * Generates export menu; returns UL node
             */
            createMenu: function( list, container ) {
                var div;

                function buildList( list, container ) {
                    var i1, i2, ul = document.createElement( "
ul" );
                    for ( i1 = 0; i1 < list.length; i1++ ) {
                        var item = typeof list[ i1 ] === "
string" ? {
                            format: list[ i1 ]
                        } : list[ i1 ];
                        var li = document.createElement( "
li" );
                        var a = document.createElement( "
a" );
                        var img = document.createElement( "
img" );
                        var span = document.createElement( "
span" );
                        var action = String( item.action ? item.action : item.format ).toLowerCase();

                        item.format = String( item.format ).toUpperCase();

                        // MERGE WITH GIVEN FORMAT
                        if ( _this.config.formats[ item.format ] ) {
                            item = _this.deepMerge( {
                                label: item.icon ? "" : item.format,
                                format: item.format,
                                mimeType: _this.config.formats[ item.format ].mimeType,
                                extension: _this.config.formats[ item.format ].extension,
                                capture: _this.config.formats[ item.format ].capture,
                                action: _this.config.action,
                                fileName: _this.config.fileName
                            }, item );
                        } else if ( !item.label ) {
                            item.label = item.label ? item.label : _this.i18l( "
menu.label." + action );
                        }

                        // FILTER; TOGGLE FLAG
                        if ( [ "
CSV", "JSON", "XLSX" ].indexOf( item.format ) != -1 && [ "map", "gauge" ].indexOf( _this.setup.chart.type ) != -1 ) {
                            continue;

                            // BLOB EXCEPTION
                        } else if ( !_this.setup.hasBlob && item.format != "
UNDEFINED" ) {
                            if ( item.mimeType && item.mimeType.split( "
/" )[ 0 ] != "image" && item.mimeType != "text/plain" ) {
                                continue;
                            }
                        }

                        // DRAWING
                        if ( item.action == "
draw" ) {
                            if ( _this.config.fabric.drawing.enabled ) {
                                item.menu = item.menu ? item.menu : _this.config.fabric.drawing.menu;
                                item.click = ( function( item ) {
                                    return function() {
                                        this.capture( item, function() {
                                            this.createMenu( item.menu );
                                        } );
                                    }
                                } )( item );
                            } else {
                                item.menu = [];
                            }

                            // DRAWING CHOICES
                        } else if ( !item.populated && item.action && item.action.indexOf( "
draw." ) != -1 ) {
                            var type = item.action.split( "
." )[ 1 ];
                            var items = item[ type ] || _this.config.fabric.drawing[ type ] || [];

                            item.menu = [];
                            item.populated = true;

                            for ( i2 = 0; i2 < items.length; i2++ ) {
                                var tmp = {
                                    "
label": items[ i2 ]
                                }

                                if ( type == "
shapes" ) {
                                    var io = items[ i2 ].indexOf( "
//" ) == -1;
                                    
var url = ( io _this.config.path "shapes/" "" ) + itemsi2 ];

                                    
tmp.action "add";
                                    
tmp.url url;
                                    
tmp.icon url;
                                    
tmp.ignore io;
                                    
tmp"class" ] = "export-drawing-shape";

                                } else if ( 
type == "colors" ) {
                                    
tmp.style "background-color: " itemsi2 ];
                                    
tmp.action "change";
                                    
tmp.color itemsi2 ];
                                    
tmp"class" ] = "export-drawing-color";

                                } else if ( 
type == "widths" ) {
                                    
tmp.action "change";
                                    
tmp.width itemsi2 ];
                                    
tmp.label document.createElement"span" );

                                    
tmp.label.style.width _this.numberToPxitemsi2 ] );
                                    
tmp.label.style.height _this.numberToPxitemsi2 ] );
                                    
tmp"class" ] = "export-drawing-width";
                                } else if ( 
type == "opacities" ) {
                                    
tmp.style "opacity: " itemsi2 ];
                                    
tmp.action "change";
                                    
tmp.opacity itemsi2 ];
                                    
tmp.label = ( itemsi2 ] * 100 ) + "%";
                                    
tmp"class" ] = "export-drawing-opacity";
                                } else if ( 
type == "modes" ) {
                                    
tmp.label _this.i18l"menu.label.draw.modes." itemsi2 ] );
                                    
tmp.click = ( function( mode ) {
                                        return function() {
                                            
_this.drawing.mode mode;
                                        }
                                    } )( 
itemsi2 ] );
                                    
tmp"class" ] = "export-drawing-mode";
                                }

                                
item.menu.pushtmp );
                            }

                            
// ADD CLICK HANDLER
                        
} else if ( !item.click && !item.menu && !item.items ) {
                            
// DRAWING METHODS
                            
if ( _this.drawing.handleraction ] instanceof Function ) {
                                
item.action action;
                                
item.click = ( function( item ) {
                                    return function() {
                                        
this.drawing.handleritem.action ]( item );
                                    }
                                } )( 
item );

                                
// DRAWING
                            
} else if ( _this.drawing.buffer.enabled ) {
                                
item.click = ( function( item ) {
                                    return function() {
                                        if ( 
this.config.drawing.autoClose ) {
                                            
this.drawing.handler.done();
                                        }
                                        
this"to" item.format ]( item, function( data ) {
                                            if ( 
item.action == "download" ) {
                                                
this.downloaddataitem.mimeType, [ item.fileNameitem.extension ].join"." ) );
                                            }
                                        } );
                                    }
                                } )( 
item );

                                
// REGULAR
                            
} else if ( item.format != "UNDEFINED" ) {
                                
item.click = ( function( item ) {
                                    return function() {
                                        if ( 
item.capture || item.action == "print" || item.format == "PRINT" ) {
                                            
this.captureitem, function() {
                                                if ( 
this.config.drawing.autoClose ) {
                                                    
this.drawing.handler.done();
                                                }
                                                
this"to" item.format ]( item, function( data ) {
                                                    if ( 
item.action == "download" ) {
                                                        
this.downloaddataitem.mimeType, [ item.fileNameitem.extension ].join"." ) );
                                                    }
                                                } );
                                            } )

                                        } else if ( 
this"to" item.format ] ) {
                                            
this"to" item.format ]( item, function( data ) {
                                                
this.downloaddataitem.mimeType, [ item.fileNameitem.extension ].join"." ) );
                                            } );
                                        } else {
                                            throw new 
Error'Invalid format. Could not determine output type.' );
                                        }
                                    }
                                } )( 
item );
                            }
                        }

                        
// HIDE EMPTY ONES
                        
if ( item.menu !== undefined && !item.menu.length ) {
                            continue;
                        }

                        
// ADD LINK ATTR
                        
a.setAttribute"href""#" );
                        
a.addEventListener"click", ( function( callbackitem ) {
                            return function( 
) {
                                
e.preventDefault();
                                var 
args = [ eitem ];

                                
// DELAYED
                                
if ( ( item.action == "draw" || item.format == "PRINT" || ( item.format != "UNDEFINED" && item.capture ) ) && !_this.drawing.enabled ) {
                                    
item.delay item.delay item.delay _this.config.delay;
                                    if ( 
item.delay ) {
                                        
_this.delayitemcallback );
                                        return;
                                    }
                                }

                                
callback.apply_thisargs );
                            }
                        } )( 
item.click || function( ) {
                            
e.preventDefault();
                        }, 
item ) );
                        
li.appendChild);

                        
// ADD LABEL
                        
if ( _this.isElementitem.label ) ) {
                            
span.appendChilditem.label );
                        } else {
                            
span.innerHTML item.label;
                        }

                        
// APPEND ITEMS
                        
if ( item"class" ] ) {
                            
li.className item"class" ];
                        }

                        if ( 
item.style ) {
                            
li.setAttribute"style"item.style );
                        }

                        if ( 
item.icon ) {
                            
img.setAttribute"src", ( !item.ignore && item.icon.slice010 ).indexOf"//" ) == -chart.pathToImages "" ) + item.icon );
                            
a.appendChildimg );
                        }
                        if ( 
item.label ) {
                            
a.appendChildspan );
                        }
                        if ( 
item.title ) {
                            
a.setAttribute"title"item.title );
                        }

                        
// CALLBACK; REVIVER FOR MENU ITEMS
                        
if ( _this.config.menuReviver ) {
                            
li _this.config.menuReviver.apply_this, [ itemli ] );
                        }

                        
// ADD ELEMENTS FOR EASY ACCESS
                        
item.elements = {
                            
lili,
                            
aa,
                            
imgimg,
                            
spanspan
                        
}

                        
// ADD SUBLIST; JUST WITH ENTRIES
                        
if ( ( item.menu || item.items ) && item.action != "draw" ) {
                            if ( 
buildListitem.menu || item.itemsli ).childNodes.length ) {
                                
ul.appendChildli );
                            }
                        } else {
                            
ul.appendChildli );
                        }
                    }

                    
// JUST ADD THOSE WITH ENTRIES
                    
if ( ul.childNodes.length ) {
                        
container.appendChildul );
                    }

                    return 
ul;
                }

                
// DETERMINE CONTAINER
                
if ( !container ) {
                    if ( 
typeof _this.config.divId == "string" ) {
                        
_this.config.divId container document.getElementById_this.config.divId );
                    } else if ( 
_this.isElement_this.config.divId ) ) {
                        
container _this.config.divId;
                    } else {
                        
container _this.setup.chart.containerDiv;
                    }
                }

                
// CREATE / RESET MENU CONTAINER
                
if ( _this.isElement_this.setup.menu ) ) {
                    
_this.setup.menu.innerHTML "";
                } else {
                    
_this.setup.menu document.createElement"div" );
                }
                
_this.setup.menu.setAttribute"class"_this.setup.chart.classNamePrefix "-export-menu " _this.setup.chart.classNamePrefix "-export-menu-" _this.config.position " amExportButton" );

                
// CALLBACK; REPLACES THE MENU WALKER
                
if ( _this.config.menuWalker ) {
                    
buildList _this.config.menuWalker;
                }
                
buildList.applythis, [ list, _this.setup.menu ] );

                
// JUST ADD THOSE WITH ENTRIES
                
if ( _this.setup.menu.childNodes.length ) {
                    
container.appendChild_this.setup.menu );
                }

                return 
_this.setup.menu;
            },

            
/**
             * Method to trigger the callback delayed
             */
            
delay: function( optionscallback ) {
                var 
cfg _this.deepMerge( {
                    
delay3,
                    
precision2
                
}, options || {} );
                var 
t1t2start Number( new Date() );
                var 
menu _this.createMenu( [ {
                    
label_this.i18l"capturing.delayed.menu.label" ).replace"{{duration}}"AmCharts.toFixedcfg.delaycfg.precision ) ),
                    
title_this.i18l"capturing.delayed.menu.title" ),
                    
"class""export-delayed-capturing",
                    
click: function() {
                        
clearTimeoutt1 );
                        
clearTimeoutt2 );
                        
_this.createMenu_this.config.menu );
                    }
                } ] );
                var 
label menu.getElementsByTagName"a" )[ ];

                
// MENU UPDATE
                
t1 setInterval( function() {
                    var 
diff cfg.delay - ( Number( new Date() ) - start ) / 1000;
                    if ( 
diff <= ) {
                        
clearTimeoutt1 );
                        if ( 
cfg.action != "draw" ) {
                            
_this.createMenu_this.config.menu );
                        }
                    } else if ( 
label ) {
                        
label.innerHTML _this.i18l"capturing.delayed.menu.label" ).replace"{{duration}}"AmCharts.toFixeddiff) );
                    }
                }, 
10 );

                
// CALLBACK
                
t2 setTimeout( function() {
                    
callback.apply_thisarguments );
                }, 
cfg.delay 1000 );
            },

            
/**
             * Migration method to support old export setup
             */
            
migrateSetup: function( setup ) {
                var 
cfg = {
                    
enabledtrue,
                    
migratedtrue,
                    
libs: {
                        
autoLoadtrue
                    
},
                    
menu: []
                };

                function 
crawler( object ) {
                    var 
key;
                    for ( 
key in object ) {
                        var 
value objectkey ];

                        if ( 
key.slice0) == "export" && value ) {
                            
cfg.menu.pushkey.slice) );
                        } else if ( 
key == "userCFG" ) {
                            
crawlervalue );
                        } else if ( 
key == "menuItems" ) {
                            
cfg.menu value;
                        } else if ( 
key == "libs" ) {
                            
cfg.libs value;
                        } else if ( 
typeof key == "string" ) {
                            
cfgkey ] = value;
                        }
                    }
                }

                
crawlersetup );

                return 
cfg;
            },

            
/*
             ** Add event listener
             */
            
loadListeners: function() {
                function 
handleClone( clone ) {
                    if ( clone ) {
                        clone.
set( {
                            
top: clone.top 10,
                            
left: clone.left 10
                        
} );
                        
_this.setup.fabric.add( clone );
                    }
                }

                
// OBSERVE; KEY LISTENER; DRAWING FEATURES
                
if ( _this.config.keyListener && _this.config.keyListener != "attached" ) {
                    
_this.config.keyListener "attached";
                    
document.addEventListener"keydown", function( ) {
                        var 
current _this.drawing.buffer.target;

                        
// REMOVE; key: BACKSPACE / DELETE
                        
if ( ( e.keyCode == || e.keyCode == 46 ) && current ) {
                            
e.preventDefault();
                            
_this.setup.fabric.removecurrent );

                            
// ESCAPE DRAWIN MODE; key: escape
                        
} else if ( e.keyCode == 27 && _this.drawing.enabled ) {
                            
e.preventDefault();
                            
_this.drawing.handler.done();

                            
// COPY; key: C
                        
} else if ( e.keyCode == 67 && ( e.metaKey || e.ctrlKey ) && current ) {
                            
_this.drawing.buffer.copy current;

                            
// CUT; key: X
                        
} else if ( e.keyCode == 88 && ( e.metaKey || e.ctrlKey ) && current ) {
                            
_this.drawing.buffer.copy current;
                            
_this.setup.fabric.removecurrent );

                            
// PASTE; key: V
                        
} else if ( e.keyCode == 86 && ( e.metaKey || e.ctrlKey ) ) {
                            if ( 
_this.drawing.buffer.copy ) {
                                
handleClone_this.drawing.buffer.copy.clone( handleClone ) )
                            }

                            
// UNDO / REDO; key: Z
                        
} else if ( e.keyCode == 90 && ( e.metaKey || e.ctrlKey ) ) {
                            
e.preventDefault();
                            if ( 
e.shiftKey ) {
                                
_this.drawing.handler.redo();
                            } else {
                                
_this.drawing.handler.undo();
                            }
                        }
                    } );
                }

                
// OBSERVE; DRAG AND DROP LISTENER; DRAWING FEATURE
                
if ( _this.config.fileListener ) {
                    
_this.setup.chart.containerDiv.addEventListener"dragover"_this.handleDropbox );
                    
_this.setup.chart.containerDiv.addEventListener"dragleave"_this.handleDropbox );
                    
_this.setup.chart.containerDiv.addEventListener"drop"_this.handleDropbox );
                }
            },

            
/**
             * Initiate export menu; waits for chart container to place menu
             */
            
init: function() {
                
clearTimeout_this.timer );
                
_this.timer setInterval( function() {
                    if ( 
_this.setup.chart.containerDiv ) {
                        
clearTimeout_this.timer );

                        if ( 
_this.config.enabled ) {
                            
// CREATE REFERENCE
                            
_this.setup.chart.AmExport _this;

                            
// OVERWRITE PARENT OVERFLOW
                            
if ( _this.config.overflow ) {
                                
_this.setup.chart.div.style.overflow "visible";
                            }

                            
// ATTACH EVENTS
                            
_this.loadListeners();

                            
// CREATE MENU
                            
_this.createMenu_this.config.menu );
                        }
                    }
                }, 
AmCharts.updateRate );

            },

            
/**
             * Initiates export instance; merges given config; attaches event listener
             */
            
construct: function() {
                
// ANNOTATION; MAP "DONE"
                
_this.drawing.handler.cancel _this.drawing.handler.done;

                
// CHECK BLOB CONSTRUCTOR
                
try {
                    
_this.setup.hasBlob = !!new Blob;
                } catch ( 
) {}

                
// WORK AROUND TO BYPASS FILESAVER CHECK TRYING TO OPEN THE BLOB URL IN SAFARI BROWSER
                
window.safari window.safari window.safari : {};

                
// OVERTAKE CHART FONTSIZE IF GIVEN
                
_this.defaults.fabric.drawing.fontSize _this.setup.chart.fontSize || 11;

                
// MERGE SETTINGS
                
_this.config.drawing _this.deepMerge_this.defaults.fabric.drawing_this.config.drawing || {}, true );
                if ( 
_this.config.border ) {
                    
_this.config.border _this.deepMerge_this.defaults.fabric.border_this.config.border || {}, true );
                }
                
_this.deepMerge_this.defaults.fabric_this.configtrue );
                
_this.deepMerge_this.defaults.fabric_this.config.fabric || {}, true );
                
_this.deepMerge_this.defaults.pdfMake_this.configtrue );
                
_this.deepMerge_this.defaults.pdfMake_this.config.pdfMake || {}, true );
                
_this.deepMerge_this.libs_this.config.libs || {}, true );

                
// UPDATE CONFIG
                
_this.config.drawing _this.defaults.fabric.drawing;
                
_this.config.fabric _this.defaults.fabric;
                
_this.config.pdfMake _this.defaults.pdfMake;
                
_this.config _this.deepMerge_this.defaults_this.configtrue );

                
// MERGE; SETUP DRAWING MENU
                
if ( _this.config.fabric.drawing.enabled ) {
                    if ( 
_this.config.fabric.drawing.menu === undefined ) {
                        
_this.config.fabric.drawing.menu = [];
                        
_this.deepMerge_this.config.fabric.drawing.menu, [ {
                            
"class""export-drawing",
                            
menu: [ {
                                
label_this.i18l"menu.label.draw.add" ),
                                
menu: [ {
                                    
label_this.i18l"menu.label.draw.shapes" ),
                                    
action"draw.shapes"
                                
}, {
                                    
label_this.i18l"menu.label.draw.text" ),
                                    
action"text"
                                
} ]
                            }, {
                                
label_this.i18l"menu.label.draw.change" ),
                                
menu: [ {
                                    
label_this.i18l"menu.label.draw.modes" ),
                                    
action"draw.modes"
                                
}, {
                                    
label_this.i18l"menu.label.draw.colors" ),
                                    
action"draw.colors"
                                
}, {
                                    
label_this.i18l"menu.label.draw.widths" ),
                                    
action"draw.widths"
                                
}, {
                                    
label_this.i18l"menu.label.draw.opacities" ),
                                    
action"draw.opacities"
                                
}, "UNDO""REDO" ]
                            }, {
                                
label_this.i18l"menu.label.save.image" ),
                                
menu: [ "PNG""JPG""SVG""PDF" ]
                            }, 
"PRINT""CANCEL" ]
                        } ] );
                    }
                }

                
// MERGE; SETUP MAIN MENU
                
if ( _this.config.menu === undefined ) {
                    
_this.config.menu = [];
                    
// PARENT MENU
                    
_this.deepMerge_this.config, {
                        
menu: [ {
                            
"class""export-main",
                            
menu: [ {
                                
label_this.i18l"menu.label.save.image" ),
                                
menu: [ "PNG""JPG""SVG""PDF" ]
                            }, {
                                
label_this.i18l"menu.label.save.data" ),
                                
menu: [ "CSV""XLSX""JSON" ]
                            }, {
                                
label_this.i18l"menu.label.draw" ),
                                
action"draw",
                                
menu_this.config.fabric.drawing.menu
                            
}, {
                                
format"PRINT",
                                
label_this.i18l"menu.label.print" )
                            } ]
                        } ]
                    } );
                }

                
// ADD MISSING PATH
                
if ( !_this.libs.path ) {
                    
_this.libs.path _this.config.path "libs/";
                }

                
// CHECK ACCEPTANCE
                
if ( _this.isSupported() ) {
                    
// LOAD DEPENDENCIES
                    
_this.loadDependencies_this.libs.resources_this.libs.reload );
                    
// ADD CLASSNAMES
                    
_this.setup.chart.addClassNames true;
                    
// REFERENCE
                    
_this.setup.chart_this.name ] = _this;
                    
// INIT MENU; WAIT FOR CHART INSTANCE
                    
_this.init();
                }
            }
        }

        
// USE GIVEN CONFIG
        
if ( config ) {
            
_this.config config;

            
// USE CHART EXPORT CONFIG
        
} else if ( _this.setup.chart_this.name ] ) {
            
_this.config _this.setup.chart_this.name ];

            
// MIGRATE OLD EXPORT CHART CONFIG
        
} else if ( _this.setup.chart.amExport || _this.setup.chart.exportConfig ) {
            
_this.config _this.migrateSetup_this.setup.chart.amExport || _this.setup.chart.exportConfig );

            
// EXIT; NO CONFIG
        
} else {
            return;
        }

        
// CONSTRUCT INSTANCE
        
_this.construct();

        
// EXPORT SCOPE
        
return _this.deepMergethis_this );
    }
} )();

/**
 * Set init handler
 */
AmCharts.addInitHandler( function( chart ) {
    new 
AmCharts"export" ]( chart );

}, [ 
"pie""serial""xy""funnel""radar""gauge""stock""map""gantt" ] );
?>
Онлайн: 3
Реклама