From 554de444b87aab5f93cb1593a8095612cf9479a7 Mon Sep 17 00:00:00 2001
From: yujian <yujian@163.com>
Date: 星期二, 09 六月 2020 17:34:30 +0800
Subject: [PATCH] 订单

---
 fanli/src/main/webapp/admin/new/js/third-party/highcharts/modules/exporting.src.js | 1418 +++++++++++++++++++++++++++++-----------------------------
 1 files changed, 709 insertions(+), 709 deletions(-)

diff --git a/fanli/src/main/webapp/admin/new/js/third-party/highcharts/modules/exporting.src.js b/fanli/src/main/webapp/admin/new/js/third-party/highcharts/modules/exporting.src.js
index dfc825c..13423d5 100644
--- a/fanli/src/main/webapp/admin/new/js/third-party/highcharts/modules/exporting.src.js
+++ b/fanli/src/main/webapp/admin/new/js/third-party/highcharts/modules/exporting.src.js
@@ -1,709 +1,709 @@
-/**
- * @license Highcharts JS v3.0.6 (2013-10-04)
- * Exporting module
- *
- * (c) 2010-2013 Torstein H酶nsi
- *
- * License: www.highcharts.com/license
- */
-
-// JSLint options:
-/*global Highcharts, document, window, Math, setTimeout */
-
-(function (Highcharts) { // encapsulate
-
-// create shortcuts
-var Chart = Highcharts.Chart,
-	addEvent = Highcharts.addEvent,
-	removeEvent = Highcharts.removeEvent,
-	createElement = Highcharts.createElement,
-	discardElement = Highcharts.discardElement,
-	css = Highcharts.css,
-	merge = Highcharts.merge,
-	each = Highcharts.each,
-	extend = Highcharts.extend,
-	math = Math,
-	mathMax = math.max,
-	doc = document,
-	win = window,
-	isTouchDevice = Highcharts.isTouchDevice,
-	M = 'M',
-	L = 'L',
-	DIV = 'div',
-	HIDDEN = 'hidden',
-	NONE = 'none',
-	PREFIX = 'highcharts-',
-	ABSOLUTE = 'absolute',
-	PX = 'px',
-	UNDEFINED,
-	symbols = Highcharts.Renderer.prototype.symbols,
-	defaultOptions = Highcharts.getOptions(),
-	buttonOffset;
-
-	// Add language
-	extend(defaultOptions.lang, {
-		printChart: 'Print chart',
-		downloadPNG: 'Download PNG image',
-		downloadJPEG: 'Download JPEG image',
-		downloadPDF: 'Download PDF document',
-		downloadSVG: 'Download SVG vector image',
-		contextButtonTitle: 'Chart context menu'
-	});
-
-// Buttons and menus are collected in a separate config option set called 'navigation'.
-// This can be extended later to add control buttons like zoom and pan right click menus.
-defaultOptions.navigation = {
-	menuStyle: {
-		border: '1px solid #A0A0A0',
-		background: '#FFFFFF',
-		padding: '5px 0'
-	},
-	menuItemStyle: {
-		padding: '0 10px',
-		background: NONE,
-		color: '#303030',
-		fontSize: isTouchDevice ? '14px' : '11px'
-	},
-	menuItemHoverStyle: {
-		background: '#4572A5',
-		color: '#FFFFFF'
-	},
-
-	buttonOptions: {
-		symbolFill: '#E0E0E0',
-		symbolSize: 14,
-		symbolStroke: '#666',
-		symbolStrokeWidth: 3,
-		symbolX: 12.5,
-		symbolY: 10.5,
-		align: 'right',
-		buttonSpacing: 3, 
-		height: 22,
-		// text: null,
-		theme: {
-			fill: 'white', // capture hover
-			stroke: 'none'
-		},
-		verticalAlign: 'top',
-		width: 24
-	}
-};
-
-
-
-// Add the export related options
-defaultOptions.exporting = {
-	//enabled: true,
-	//filename: 'chart',
-	type: 'image/png',
-	url: 'http://export.highcharts.com/',
-	//width: undefined,
-	//scale: 2
-	buttons: {
-		contextButton: {
-			menuClassName: PREFIX + 'contextmenu',
-			//x: -10,
-			symbol: 'menu',
-			_titleKey: 'contextButtonTitle',
-			menuItems: [{
-				textKey: 'printChart',
-				onclick: function () {
-					this.print();
-				}
-			}, {
-				separator: true
-			}, {
-				textKey: 'downloadPNG',
-				onclick: function () {
-					this.exportChart();
-				}
-			}, {
-				textKey: 'downloadJPEG',
-				onclick: function () {
-					this.exportChart({
-						type: 'image/jpeg'
-					});
-				}
-			}, {
-				textKey: 'downloadPDF',
-				onclick: function () {
-					this.exportChart({
-						type: 'application/pdf'
-					});
-				}
-			}, {
-				textKey: 'downloadSVG',
-				onclick: function () {
-					this.exportChart({
-						type: 'image/svg+xml'
-					});
-				}
-			}
-			// Enable this block to add "View SVG" to the dropdown menu
-			/*
-			,{
-
-				text: 'View SVG',
-				onclick: function () {
-					var svg = this.getSVG()
-						.replace(/</g, '\n&lt;')
-						.replace(/>/g, '&gt;');
-
-					doc.body.innerHTML = '<pre>' + svg + '</pre>';
-				}
-			} // */
-			]
-		}
-	}
-};
-
-// Add the Highcharts.post utility
-Highcharts.post = function (url, data) {
-	var name,
-		form;
-	
-	// create the form
-	form = createElement('form', {
-		method: 'post',
-		action: url,
-		enctype: 'multipart/form-data'
-	}, {
-		display: NONE
-	}, doc.body);
-
-	// add the data
-	for (name in data) {
-		createElement('input', {
-			type: HIDDEN,
-			name: name,
-			value: data[name]
-		}, null, form);
-	}
-
-	// submit
-	form.submit();
-
-	// clean up
-	discardElement(form);
-};
-
-extend(Chart.prototype, {
-
-	/**
-	 * Return an SVG representation of the chart
-	 *
-	 * @param additionalOptions {Object} Additional chart options for the generated SVG representation
-	 */
-	getSVG: function (additionalOptions) {
-		var chart = this,
-			chartCopy,
-			sandbox,
-			svg,
-			seriesOptions,
-			sourceWidth,
-			sourceHeight,
-			cssWidth,
-			cssHeight,
-			options = merge(chart.options, additionalOptions); // copy the options and add extra options
-
-		// IE compatibility hack for generating SVG content that it doesn't really understand
-		if (!doc.createElementNS) {
-			/*jslint unparam: true*//* allow unused parameter ns in function below */
-			doc.createElementNS = function (ns, tagName) {
-				return doc.createElement(tagName);
-			};
-			/*jslint unparam: false*/
-		}
-
-		// create a sandbox where a new chart will be generated
-		sandbox = createElement(DIV, null, {
-			position: ABSOLUTE,
-			top: '-9999em',
-			width: chart.chartWidth + PX,
-			height: chart.chartHeight + PX
-		}, doc.body);
-		
-		// get the source size
-		cssWidth = chart.renderTo.style.width;
-		cssHeight = chart.renderTo.style.height;
-		sourceWidth = options.exporting.sourceWidth ||
-			options.chart.width ||
-			(/px$/.test(cssWidth) && parseInt(cssWidth, 10)) ||
-			600;
-		sourceHeight = options.exporting.sourceHeight ||
-			options.chart.height ||
-			(/px$/.test(cssHeight) && parseInt(cssHeight, 10)) ||
-			400;
-
-		// override some options
-		extend(options.chart, {
-			animation: false,
-			renderTo: sandbox,
-			forExport: true,
-			width: sourceWidth,
-			height: sourceHeight
-		});
-		options.exporting.enabled = false; // hide buttons in print
-		
-		// prepare for replicating the chart
-		options.series = [];
-		each(chart.series, function (serie) {
-			seriesOptions = merge(serie.options, {
-				animation: false, // turn off animation
-				showCheckbox: false,
-				visible: serie.visible
-			});
-
-			if (!seriesOptions.isInternal) { // used for the navigator series that has its own option set
-				options.series.push(seriesOptions);
-			}
-		});
-
-		// generate the chart copy
-		chartCopy = new Highcharts.Chart(options, chart.callback);
-
-		// reflect axis extremes in the export
-		each(['xAxis', 'yAxis'], function (axisType) {
-			each(chart[axisType], function (axis, i) {
-				var axisCopy = chartCopy[axisType][i],
-					extremes = axis.getExtremes(),
-					userMin = extremes.userMin,
-					userMax = extremes.userMax;
-
-				if (axisCopy && (userMin !== UNDEFINED || userMax !== UNDEFINED)) {
-					axisCopy.setExtremes(userMin, userMax, true, false);
-				}
-			});
-		});
-
-		// get the SVG from the container's innerHTML
-		svg = chartCopy.container.innerHTML;
-
-		// free up memory
-		options = null;
-		chartCopy.destroy();
-		discardElement(sandbox);
-
-		// sanitize
-		svg = svg
-			.replace(/zIndex="[^"]+"/g, '')
-			.replace(/isShadow="[^"]+"/g, '')
-			.replace(/symbolName="[^"]+"/g, '')
-			.replace(/jQuery[0-9]+="[^"]+"/g, '')
-			.replace(/url\([^#]+#/g, 'url(#')
-			.replace(/<svg /, '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ')
-			.replace(/ href=/g, ' xlink:href=')
-			.replace(/\n/, ' ')
-			.replace(/<\/svg>.*?$/, '</svg>') // any HTML added to the container after the SVG (#894)
-			/* This fails in IE < 8
-			.replace(/([0-9]+)\.([0-9]+)/g, function(s1, s2, s3) { // round off to save weight
-				return s2 +'.'+ s3[0];
-			})*/
-
-			// Replace HTML entities, issue #347
-			.replace(/&nbsp;/g, '\u00A0') // no-break space
-			.replace(/&shy;/g,  '\u00AD') // soft hyphen
-
-			// IE specific
-			.replace(/<IMG /g, '<image ')
-			.replace(/height=([^" ]+)/g, 'height="$1"')
-			.replace(/width=([^" ]+)/g, 'width="$1"')
-			.replace(/hc-svg-href="([^"]+)">/g, 'xlink:href="$1"/>')
-			.replace(/id=([^" >]+)/g, 'id="$1"')
-			.replace(/class=([^" >]+)/g, 'class="$1"')
-			.replace(/ transform /g, ' ')
-			.replace(/:(path|rect)/g, '$1')
-			.replace(/style="([^"]+)"/g, function (s) {
-				return s.toLowerCase();
-			});
-
-		// IE9 beta bugs with innerHTML. Test again with final IE9.
-		svg = svg.replace(/(url\(#highcharts-[0-9]+)&quot;/g, '$1')
-			.replace(/&quot;/g, "'");
-
-		return svg;
-	},
-
-	/**
-	 * Submit the SVG representation of the chart to the server
-	 * @param {Object} options Exporting options. Possible members are url, type and width.
-	 * @param {Object} chartOptions Additional chart options for the SVG representation of the chart
-	 */
-	exportChart: function (options, chartOptions) {
-		options = options || {};
-		
-		var chart = this,
-			chartExportingOptions = chart.options.exporting,
-			svg = chart.getSVG(merge(
-				{ chart: { borderRadius: 0 } },
-				chartExportingOptions.chartOptions,
-				chartOptions, 
-				{
-					exporting: {
-						sourceWidth: options.sourceWidth || chartExportingOptions.sourceWidth,
-						sourceHeight: options.sourceHeight || chartExportingOptions.sourceHeight
-					}
-				}
-			));
-
-		// merge the options
-		options = merge(chart.options.exporting, options);
-		
-		// do the post
-		Highcharts.post(options.url, {
-			filename: options.filename || 'chart',
-			type: options.type,
-			width: options.width || 0, // IE8 fails to post undefined correctly, so use 0
-			scale: options.scale || 2,
-			svg: svg
-		});
-
-	},
-	
-	/**
-	 * Print the chart
-	 */
-	print: function () {
-
-		var chart = this,
-			container = chart.container,
-			origDisplay = [],
-			origParent = container.parentNode,
-			body = doc.body,
-			childNodes = body.childNodes;
-
-		if (chart.isPrinting) { // block the button while in printing mode
-			return;
-		}
-
-		chart.isPrinting = true;
-
-		// hide all body content
-		each(childNodes, function (node, i) {
-			if (node.nodeType === 1) {
-				origDisplay[i] = node.style.display;
-				node.style.display = NONE;
-			}
-		});
-
-		// pull out the chart
-		body.appendChild(container);
-
-		// print
-		win.focus(); // #1510
-		win.print();
-
-		// allow the browser to prepare before reverting
-		setTimeout(function () {
-
-			// put the chart back in
-			origParent.appendChild(container);
-
-			// restore all body content
-			each(childNodes, function (node, i) {
-				if (node.nodeType === 1) {
-					node.style.display = origDisplay[i];
-				}
-			});
-
-			chart.isPrinting = false;
-
-		}, 1000);
-
-	},
-
-	/**
-	 * Display a popup menu for choosing the export type
-	 *
-	 * @param {String} className An identifier for the menu
-	 * @param {Array} items A collection with text and onclicks for the items
-	 * @param {Number} x The x position of the opener button
-	 * @param {Number} y The y position of the opener button
-	 * @param {Number} width The width of the opener button
-	 * @param {Number} height The height of the opener button
-	 */
-	contextMenu: function (className, items, x, y, width, height, button) {
-		var chart = this,
-			navOptions = chart.options.navigation,
-			menuItemStyle = navOptions.menuItemStyle,
-			chartWidth = chart.chartWidth,
-			chartHeight = chart.chartHeight,
-			cacheName = 'cache-' + className,
-			menu = chart[cacheName],
-			menuPadding = mathMax(width, height), // for mouse leave detection
-			boxShadow = '3px 3px 10px #888',
-			innerMenu,
-			hide,
-			hideTimer,
-			menuStyle;
-
-		// create the menu only the first time
-		if (!menu) {
-
-			// create a HTML element above the SVG
-			chart[cacheName] = menu = createElement(DIV, {
-				className: className
-			}, {
-				position: ABSOLUTE,
-				zIndex: 1000,
-				padding: menuPadding + PX
-			}, chart.container);
-
-			innerMenu = createElement(DIV, null,
-				extend({
-					MozBoxShadow: boxShadow,
-					WebkitBoxShadow: boxShadow,
-					boxShadow: boxShadow
-				}, navOptions.menuStyle), menu);
-
-			// hide on mouse out
-			hide = function () {
-				css(menu, { display: NONE });
-				if (button) {
-					button.setState(0);
-				}
-				chart.openMenu = false;
-			};
-
-			// Hide the menu some time after mouse leave (#1357)
-			addEvent(menu, 'mouseleave', function () {
-				hideTimer = setTimeout(hide, 500);
-			});
-			addEvent(menu, 'mouseenter', function () {
-				clearTimeout(hideTimer);
-			});
-			// Hide it on clicking or touching outside the menu (#2258)
-			addEvent(document, 'mousedown', function (e) {
-				if (!chart.pointer.inClass(e.target, className)) {
-					hide();
-				}
-			});
-
-
-			// create the items
-			each(items, function (item) {
-				if (item) {
-					var element = item.separator ? 
-						createElement('hr', null, null, innerMenu) :
-						createElement(DIV, {
-							onmouseover: function () {
-								css(this, navOptions.menuItemHoverStyle);
-							},
-							onmouseout: function () {
-								css(this, menuItemStyle);
-							},
-							onclick: function () {
-								hide();
-								item.onclick.apply(chart, arguments);
-							},
-							innerHTML: item.text || chart.options.lang[item.textKey]
-						}, extend({
-							cursor: 'pointer'
-						}, menuItemStyle), innerMenu);
-
-
-					// Keep references to menu divs to be able to destroy them
-					chart.exportDivElements.push(element);
-				}
-			});
-
-			// Keep references to menu and innerMenu div to be able to destroy them
-			chart.exportDivElements.push(innerMenu, menu);
-
-			chart.exportMenuWidth = menu.offsetWidth;
-			chart.exportMenuHeight = menu.offsetHeight;
-		}
-
-		menuStyle = { display: 'block' };
-
-		// if outside right, right align it
-		if (x + chart.exportMenuWidth > chartWidth) {
-			menuStyle.right = (chartWidth - x - width - menuPadding) + PX;
-		} else {
-			menuStyle.left = (x - menuPadding) + PX;
-		}
-		// if outside bottom, bottom align it
-		if (y + height + chart.exportMenuHeight > chartHeight && button.alignOptions.verticalAlign !== 'top') {
-			menuStyle.bottom = (chartHeight - y - menuPadding)  + PX;
-		} else {
-			menuStyle.top = (y + height - menuPadding) + PX;
-		}
-
-		css(menu, menuStyle);
-		chart.openMenu = true;
-	},
-
-	/**
-	 * Add the export button to the chart
-	 */
-	addButton: function (options) {
-		var chart = this,
-			renderer = chart.renderer,
-			btnOptions = merge(chart.options.navigation.buttonOptions, options),
-			onclick = btnOptions.onclick,
-			menuItems = btnOptions.menuItems,
-			symbol,
-			button,
-			symbolAttr = {
-				stroke: btnOptions.symbolStroke,
-				fill: btnOptions.symbolFill
-			},
-			symbolSize = btnOptions.symbolSize || 12;
-		if (!chart.btnCount) {
-			chart.btnCount = 0;
-		}
-
-		// Keeps references to the button elements
-		if (!chart.exportDivElements) {
-			chart.exportDivElements = [];
-			chart.exportSVGElements = [];
-		}
-
-		if (btnOptions.enabled === false) {
-			return;
-		}
-
-
-		var attr = btnOptions.theme,
-			states = attr.states,
-			hover = states && states.hover,
-			select = states && states.select,
-			callback;
-
-		delete attr.states;
-
-		if (onclick) {
-			callback = function () {
-				onclick.apply(chart, arguments);
-			};
-
-		} else if (menuItems) {
-			callback = function () {
-				chart.contextMenu(
-					button.menuClassName, 
-					menuItems, 
-					button.translateX, 
-					button.translateY, 
-					button.width, 
-					button.height,
-					button
-				);
-				button.setState(2);
-			};
-		}
-
-
-		if (btnOptions.text && btnOptions.symbol) {
-			attr.paddingLeft = Highcharts.pick(attr.paddingLeft, 25);
-		
-		} else if (!btnOptions.text) {
-			extend(attr, {
-				width: btnOptions.width,
-				height: btnOptions.height,
-				padding: 0
-			});
-		}
-
-		button = renderer.button(btnOptions.text, 0, 0, callback, attr, hover, select)
-			.attr({
-				title: chart.options.lang[btnOptions._titleKey],
-				'stroke-linecap': 'round'
-			});
-		button.menuClassName = options.menuClassName || PREFIX + 'menu-' + chart.btnCount++;
-
-		if (btnOptions.symbol) {
-			symbol = renderer.symbol(
-					btnOptions.symbol,
-					btnOptions.symbolX - (symbolSize / 2),
-					btnOptions.symbolY - (symbolSize / 2),
-					symbolSize,				
-					symbolSize
-				)
-				.attr(extend(symbolAttr, {
-					'stroke-width': btnOptions.symbolStrokeWidth || 1,
-					zIndex: 1
-				})).add(button);
-		}
-
-		button.add()
-			.align(extend(btnOptions, {
-				width: button.width,
-				x: Highcharts.pick(btnOptions.x, buttonOffset) // #1654
-			}), true, 'spacingBox');
-
-		buttonOffset += (button.width + btnOptions.buttonSpacing) * (btnOptions.align === 'right' ? -1 : 1);
-
-		chart.exportSVGElements.push(button, symbol);
-
-	},
-
-	/**
-	 * Destroy the buttons.
-	 */
-	destroyExport: function (e) {
-		var chart = e.target,
-			i,
-			elem;
-
-		// Destroy the extra buttons added
-		for (i = 0; i < chart.exportSVGElements.length; i++) {
-			elem = chart.exportSVGElements[i];
-			
-			// Destroy and null the svg/vml elements
-			if (elem) { // #1822
-				elem.onclick = elem.ontouchstart = null;
-				chart.exportSVGElements[i] = elem.destroy();
-			}
-		}
-
-		// Destroy the divs for the menu
-		for (i = 0; i < chart.exportDivElements.length; i++) {
-			elem = chart.exportDivElements[i];
-
-			// Remove the event handler
-			removeEvent(elem, 'mouseleave');
-
-			// Remove inline events
-			chart.exportDivElements[i] = elem.onmouseout = elem.onmouseover = elem.ontouchstart = elem.onclick = null;
-
-			// Destroy the div by moving to garbage bin
-			discardElement(elem);
-		}
-	}
-});
-
-
-symbols.menu = function (x, y, width, height) {
-	var arr = [
-		M, x, y + 2.5,
-		L, x + width, y + 2.5,
-		M, x, y + height / 2 + 0.5,
-		L, x + width, y + height / 2 + 0.5,
-		M, x, y + height - 1.5,
-		L, x + width, y + height - 1.5
-	];
-	return arr;
-};
-
-// Add the buttons on chart load
-Chart.prototype.callbacks.push(function (chart) {
-	var n,
-		exportingOptions = chart.options.exporting,
-		buttons = exportingOptions.buttons;
-
-	buttonOffset = 0;
-
-	if (exportingOptions.enabled !== false) {
-
-		for (n in buttons) {
-			chart.addButton(buttons[n]);
-		}
-
-		// Destroy the export elements at chart destroy
-		addEvent(chart, 'destroy', chart.destroyExport);
-	}
-
-});
-
-
-}(Highcharts));
+/**
+ * @license Highcharts JS v3.0.6 (2013-10-04)
+ * Exporting module
+ *
+ * (c) 2010-2013 Torstein H酶nsi
+ *
+ * License: www.highcharts.com/license
+ */
+
+// JSLint options:
+/*global Highcharts, document, window, Math, setTimeout */
+
+(function (Highcharts) { // encapsulate
+
+// create shortcuts
+var Chart = Highcharts.Chart,
+	addEvent = Highcharts.addEvent,
+	removeEvent = Highcharts.removeEvent,
+	createElement = Highcharts.createElement,
+	discardElement = Highcharts.discardElement,
+	css = Highcharts.css,
+	merge = Highcharts.merge,
+	each = Highcharts.each,
+	extend = Highcharts.extend,
+	math = Math,
+	mathMax = math.max,
+	doc = document,
+	win = window,
+	isTouchDevice = Highcharts.isTouchDevice,
+	M = 'M',
+	L = 'L',
+	DIV = 'div',
+	HIDDEN = 'hidden',
+	NONE = 'none',
+	PREFIX = 'highcharts-',
+	ABSOLUTE = 'absolute',
+	PX = 'px',
+	UNDEFINED,
+	symbols = Highcharts.Renderer.prototype.symbols,
+	defaultOptions = Highcharts.getOptions(),
+	buttonOffset;
+
+	// Add language
+	extend(defaultOptions.lang, {
+		printChart: 'Print chart',
+		downloadPNG: 'Download PNG image',
+		downloadJPEG: 'Download JPEG image',
+		downloadPDF: 'Download PDF document',
+		downloadSVG: 'Download SVG vector image',
+		contextButtonTitle: 'Chart context menu'
+	});
+
+// Buttons and menus are collected in a separate config option set called 'navigation'.
+// This can be extended later to add control buttons like zoom and pan right click menus.
+defaultOptions.navigation = {
+	menuStyle: {
+		border: '1px solid #A0A0A0',
+		background: '#FFFFFF',
+		padding: '5px 0'
+	},
+	menuItemStyle: {
+		padding: '0 10px',
+		background: NONE,
+		color: '#303030',
+		fontSize: isTouchDevice ? '14px' : '11px'
+	},
+	menuItemHoverStyle: {
+		background: '#4572A5',
+		color: '#FFFFFF'
+	},
+
+	buttonOptions: {
+		symbolFill: '#E0E0E0',
+		symbolSize: 14,
+		symbolStroke: '#666',
+		symbolStrokeWidth: 3,
+		symbolX: 12.5,
+		symbolY: 10.5,
+		align: 'right',
+		buttonSpacing: 3, 
+		height: 22,
+		// text: null,
+		theme: {
+			fill: 'white', // capture hover
+			stroke: 'none'
+		},
+		verticalAlign: 'top',
+		width: 24
+	}
+};
+
+
+
+// Add the export related options
+defaultOptions.exporting = {
+	//enabled: true,
+	//filename: 'chart',
+	type: 'image/png',
+	url: 'http://export.highcharts.com/',
+	//width: undefined,
+	//scale: 2
+	buttons: {
+		contextButton: {
+			menuClassName: PREFIX + 'contextmenu',
+			//x: -10,
+			symbol: 'menu',
+			_titleKey: 'contextButtonTitle',
+			menuItems: [{
+				textKey: 'printChart',
+				onclick: function () {
+					this.print();
+				}
+			}, {
+				separator: true
+			}, {
+				textKey: 'downloadPNG',
+				onclick: function () {
+					this.exportChart();
+				}
+			}, {
+				textKey: 'downloadJPEG',
+				onclick: function () {
+					this.exportChart({
+						type: 'image/jpeg'
+					});
+				}
+			}, {
+				textKey: 'downloadPDF',
+				onclick: function () {
+					this.exportChart({
+						type: 'application/pdf'
+					});
+				}
+			}, {
+				textKey: 'downloadSVG',
+				onclick: function () {
+					this.exportChart({
+						type: 'image/svg+xml'
+					});
+				}
+			}
+			// Enable this block to add "View SVG" to the dropdown menu
+			/*
+			,{
+
+				text: 'View SVG',
+				onclick: function () {
+					var svg = this.getSVG()
+						.replace(/</g, '\n&lt;')
+						.replace(/>/g, '&gt;');
+
+					doc.body.innerHTML = '<pre>' + svg + '</pre>';
+				}
+			} // */
+			]
+		}
+	}
+};
+
+// Add the Highcharts.post utility
+Highcharts.post = function (url, data) {
+	var name,
+		form;
+	
+	// create the form
+	form = createElement('form', {
+		method: 'post',
+		action: url,
+		enctype: 'multipart/form-data'
+	}, {
+		display: NONE
+	}, doc.body);
+
+	// add the data
+	for (name in data) {
+		createElement('input', {
+			type: HIDDEN,
+			name: name,
+			value: data[name]
+		}, null, form);
+	}
+
+	// submit
+	form.submit();
+
+	// clean up
+	discardElement(form);
+};
+
+extend(Chart.prototype, {
+
+	/**
+	 * Return an SVG representation of the chart
+	 *
+	 * @param additionalOptions {Object} Additional chart options for the generated SVG representation
+	 */
+	getSVG: function (additionalOptions) {
+		var chart = this,
+			chartCopy,
+			sandbox,
+			svg,
+			seriesOptions,
+			sourceWidth,
+			sourceHeight,
+			cssWidth,
+			cssHeight,
+			options = merge(chart.options, additionalOptions); // copy the options and add extra options
+
+		// IE compatibility hack for generating SVG content that it doesn't really understand
+		if (!doc.createElementNS) {
+			/*jslint unparam: true*//* allow unused parameter ns in function below */
+			doc.createElementNS = function (ns, tagName) {
+				return doc.createElement(tagName);
+			};
+			/*jslint unparam: false*/
+		}
+
+		// create a sandbox where a new chart will be generated
+		sandbox = createElement(DIV, null, {
+			position: ABSOLUTE,
+			top: '-9999em',
+			width: chart.chartWidth + PX,
+			height: chart.chartHeight + PX
+		}, doc.body);
+		
+		// get the source size
+		cssWidth = chart.renderTo.style.width;
+		cssHeight = chart.renderTo.style.height;
+		sourceWidth = options.exporting.sourceWidth ||
+			options.chart.width ||
+			(/px$/.test(cssWidth) && parseInt(cssWidth, 10)) ||
+			600;
+		sourceHeight = options.exporting.sourceHeight ||
+			options.chart.height ||
+			(/px$/.test(cssHeight) && parseInt(cssHeight, 10)) ||
+			400;
+
+		// override some options
+		extend(options.chart, {
+			animation: false,
+			renderTo: sandbox,
+			forExport: true,
+			width: sourceWidth,
+			height: sourceHeight
+		});
+		options.exporting.enabled = false; // hide buttons in print
+		
+		// prepare for replicating the chart
+		options.series = [];
+		each(chart.series, function (serie) {
+			seriesOptions = merge(serie.options, {
+				animation: false, // turn off animation
+				showCheckbox: false,
+				visible: serie.visible
+			});
+
+			if (!seriesOptions.isInternal) { // used for the navigator series that has its own option set
+				options.series.push(seriesOptions);
+			}
+		});
+
+		// generate the chart copy
+		chartCopy = new Highcharts.Chart(options, chart.callback);
+
+		// reflect axis extremes in the export
+		each(['xAxis', 'yAxis'], function (axisType) {
+			each(chart[axisType], function (axis, i) {
+				var axisCopy = chartCopy[axisType][i],
+					extremes = axis.getExtremes(),
+					userMin = extremes.userMin,
+					userMax = extremes.userMax;
+
+				if (axisCopy && (userMin !== UNDEFINED || userMax !== UNDEFINED)) {
+					axisCopy.setExtremes(userMin, userMax, true, false);
+				}
+			});
+		});
+
+		// get the SVG from the container's innerHTML
+		svg = chartCopy.container.innerHTML;
+
+		// free up memory
+		options = null;
+		chartCopy.destroy();
+		discardElement(sandbox);
+
+		// sanitize
+		svg = svg
+			.replace(/zIndex="[^"]+"/g, '')
+			.replace(/isShadow="[^"]+"/g, '')
+			.replace(/symbolName="[^"]+"/g, '')
+			.replace(/jQuery[0-9]+="[^"]+"/g, '')
+			.replace(/url\([^#]+#/g, 'url(#')
+			.replace(/<svg /, '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ')
+			.replace(/ href=/g, ' xlink:href=')
+			.replace(/\n/, ' ')
+			.replace(/<\/svg>.*?$/, '</svg>') // any HTML added to the container after the SVG (#894)
+			/* This fails in IE < 8
+			.replace(/([0-9]+)\.([0-9]+)/g, function(s1, s2, s3) { // round off to save weight
+				return s2 +'.'+ s3[0];
+			})*/
+
+			// Replace HTML entities, issue #347
+			.replace(/&nbsp;/g, '\u00A0') // no-break space
+			.replace(/&shy;/g,  '\u00AD') // soft hyphen
+
+			// IE specific
+			.replace(/<IMG /g, '<image ')
+			.replace(/height=([^" ]+)/g, 'height="$1"')
+			.replace(/width=([^" ]+)/g, 'width="$1"')
+			.replace(/hc-svg-href="([^"]+)">/g, 'xlink:href="$1"/>')
+			.replace(/id=([^" >]+)/g, 'id="$1"')
+			.replace(/class=([^" >]+)/g, 'class="$1"')
+			.replace(/ transform /g, ' ')
+			.replace(/:(path|rect)/g, '$1')
+			.replace(/style="([^"]+)"/g, function (s) {
+				return s.toLowerCase();
+			});
+
+		// IE9 beta bugs with innerHTML. Test again with final IE9.
+		svg = svg.replace(/(url\(#highcharts-[0-9]+)&quot;/g, '$1')
+			.replace(/&quot;/g, "'");
+
+		return svg;
+	},
+
+	/**
+	 * Submit the SVG representation of the chart to the server
+	 * @param {Object} options Exporting options. Possible members are url, type and width.
+	 * @param {Object} chartOptions Additional chart options for the SVG representation of the chart
+	 */
+	exportChart: function (options, chartOptions) {
+		options = options || {};
+		
+		var chart = this,
+			chartExportingOptions = chart.options.exporting,
+			svg = chart.getSVG(merge(
+				{ chart: { borderRadius: 0 } },
+				chartExportingOptions.chartOptions,
+				chartOptions, 
+				{
+					exporting: {
+						sourceWidth: options.sourceWidth || chartExportingOptions.sourceWidth,
+						sourceHeight: options.sourceHeight || chartExportingOptions.sourceHeight
+					}
+				}
+			));
+
+		// merge the options
+		options = merge(chart.options.exporting, options);
+		
+		// do the post
+		Highcharts.post(options.url, {
+			filename: options.filename || 'chart',
+			type: options.type,
+			width: options.width || 0, // IE8 fails to post undefined correctly, so use 0
+			scale: options.scale || 2,
+			svg: svg
+		});
+
+	},
+	
+	/**
+	 * Print the chart
+	 */
+	print: function () {
+
+		var chart = this,
+			container = chart.container,
+			origDisplay = [],
+			origParent = container.parentNode,
+			body = doc.body,
+			childNodes = body.childNodes;
+
+		if (chart.isPrinting) { // block the button while in printing mode
+			return;
+		}
+
+		chart.isPrinting = true;
+
+		// hide all body content
+		each(childNodes, function (node, i) {
+			if (node.nodeType === 1) {
+				origDisplay[i] = node.style.display;
+				node.style.display = NONE;
+			}
+		});
+
+		// pull out the chart
+		body.appendChild(container);
+
+		// print
+		win.focus(); // #1510
+		win.print();
+
+		// allow the browser to prepare before reverting
+		setTimeout(function () {
+
+			// put the chart back in
+			origParent.appendChild(container);
+
+			// restore all body content
+			each(childNodes, function (node, i) {
+				if (node.nodeType === 1) {
+					node.style.display = origDisplay[i];
+				}
+			});
+
+			chart.isPrinting = false;
+
+		}, 1000);
+
+	},
+
+	/**
+	 * Display a popup menu for choosing the export type
+	 *
+	 * @param {String} className An identifier for the menu
+	 * @param {Array} items A collection with text and onclicks for the items
+	 * @param {Number} x The x position of the opener button
+	 * @param {Number} y The y position of the opener button
+	 * @param {Number} width The width of the opener button
+	 * @param {Number} height The height of the opener button
+	 */
+	contextMenu: function (className, items, x, y, width, height, button) {
+		var chart = this,
+			navOptions = chart.options.navigation,
+			menuItemStyle = navOptions.menuItemStyle,
+			chartWidth = chart.chartWidth,
+			chartHeight = chart.chartHeight,
+			cacheName = 'cache-' + className,
+			menu = chart[cacheName],
+			menuPadding = mathMax(width, height), // for mouse leave detection
+			boxShadow = '3px 3px 10px #888',
+			innerMenu,
+			hide,
+			hideTimer,
+			menuStyle;
+
+		// create the menu only the first time
+		if (!menu) {
+
+			// create a HTML element above the SVG
+			chart[cacheName] = menu = createElement(DIV, {
+				className: className
+			}, {
+				position: ABSOLUTE,
+				zIndex: 1000,
+				padding: menuPadding + PX
+			}, chart.container);
+
+			innerMenu = createElement(DIV, null,
+				extend({
+					MozBoxShadow: boxShadow,
+					WebkitBoxShadow: boxShadow,
+					boxShadow: boxShadow
+				}, navOptions.menuStyle), menu);
+
+			// hide on mouse out
+			hide = function () {
+				css(menu, { display: NONE });
+				if (button) {
+					button.setState(0);
+				}
+				chart.openMenu = false;
+			};
+
+			// Hide the menu some time after mouse leave (#1357)
+			addEvent(menu, 'mouseleave', function () {
+				hideTimer = setTimeout(hide, 500);
+			});
+			addEvent(menu, 'mouseenter', function () {
+				clearTimeout(hideTimer);
+			});
+			// Hide it on clicking or touching outside the menu (#2258)
+			addEvent(document, 'mousedown', function (e) {
+				if (!chart.pointer.inClass(e.target, className)) {
+					hide();
+				}
+			});
+
+
+			// create the items
+			each(items, function (item) {
+				if (item) {
+					var element = item.separator ? 
+						createElement('hr', null, null, innerMenu) :
+						createElement(DIV, {
+							onmouseover: function () {
+								css(this, navOptions.menuItemHoverStyle);
+							},
+							onmouseout: function () {
+								css(this, menuItemStyle);
+							},
+							onclick: function () {
+								hide();
+								item.onclick.apply(chart, arguments);
+							},
+							innerHTML: item.text || chart.options.lang[item.textKey]
+						}, extend({
+							cursor: 'pointer'
+						}, menuItemStyle), innerMenu);
+
+
+					// Keep references to menu divs to be able to destroy them
+					chart.exportDivElements.push(element);
+				}
+			});
+
+			// Keep references to menu and innerMenu div to be able to destroy them
+			chart.exportDivElements.push(innerMenu, menu);
+
+			chart.exportMenuWidth = menu.offsetWidth;
+			chart.exportMenuHeight = menu.offsetHeight;
+		}
+
+		menuStyle = { display: 'block' };
+
+		// if outside right, right align it
+		if (x + chart.exportMenuWidth > chartWidth) {
+			menuStyle.right = (chartWidth - x - width - menuPadding) + PX;
+		} else {
+			menuStyle.left = (x - menuPadding) + PX;
+		}
+		// if outside bottom, bottom align it
+		if (y + height + chart.exportMenuHeight > chartHeight && button.alignOptions.verticalAlign !== 'top') {
+			menuStyle.bottom = (chartHeight - y - menuPadding)  + PX;
+		} else {
+			menuStyle.top = (y + height - menuPadding) + PX;
+		}
+
+		css(menu, menuStyle);
+		chart.openMenu = true;
+	},
+
+	/**
+	 * Add the export button to the chart
+	 */
+	addButton: function (options) {
+		var chart = this,
+			renderer = chart.renderer,
+			btnOptions = merge(chart.options.navigation.buttonOptions, options),
+			onclick = btnOptions.onclick,
+			menuItems = btnOptions.menuItems,
+			symbol,
+			button,
+			symbolAttr = {
+				stroke: btnOptions.symbolStroke,
+				fill: btnOptions.symbolFill
+			},
+			symbolSize = btnOptions.symbolSize || 12;
+		if (!chart.btnCount) {
+			chart.btnCount = 0;
+		}
+
+		// Keeps references to the button elements
+		if (!chart.exportDivElements) {
+			chart.exportDivElements = [];
+			chart.exportSVGElements = [];
+		}
+
+		if (btnOptions.enabled === false) {
+			return;
+		}
+
+
+		var attr = btnOptions.theme,
+			states = attr.states,
+			hover = states && states.hover,
+			select = states && states.select,
+			callback;
+
+		delete attr.states;
+
+		if (onclick) {
+			callback = function () {
+				onclick.apply(chart, arguments);
+			};
+
+		} else if (menuItems) {
+			callback = function () {
+				chart.contextMenu(
+					button.menuClassName, 
+					menuItems, 
+					button.translateX, 
+					button.translateY, 
+					button.width, 
+					button.height,
+					button
+				);
+				button.setState(2);
+			};
+		}
+
+
+		if (btnOptions.text && btnOptions.symbol) {
+			attr.paddingLeft = Highcharts.pick(attr.paddingLeft, 25);
+		
+		} else if (!btnOptions.text) {
+			extend(attr, {
+				width: btnOptions.width,
+				height: btnOptions.height,
+				padding: 0
+			});
+		}
+
+		button = renderer.button(btnOptions.text, 0, 0, callback, attr, hover, select)
+			.attr({
+				title: chart.options.lang[btnOptions._titleKey],
+				'stroke-linecap': 'round'
+			});
+		button.menuClassName = options.menuClassName || PREFIX + 'menu-' + chart.btnCount++;
+
+		if (btnOptions.symbol) {
+			symbol = renderer.symbol(
+					btnOptions.symbol,
+					btnOptions.symbolX - (symbolSize / 2),
+					btnOptions.symbolY - (symbolSize / 2),
+					symbolSize,				
+					symbolSize
+				)
+				.attr(extend(symbolAttr, {
+					'stroke-width': btnOptions.symbolStrokeWidth || 1,
+					zIndex: 1
+				})).add(button);
+		}
+
+		button.add()
+			.align(extend(btnOptions, {
+				width: button.width,
+				x: Highcharts.pick(btnOptions.x, buttonOffset) // #1654
+			}), true, 'spacingBox');
+
+		buttonOffset += (button.width + btnOptions.buttonSpacing) * (btnOptions.align === 'right' ? -1 : 1);
+
+		chart.exportSVGElements.push(button, symbol);
+
+	},
+
+	/**
+	 * Destroy the buttons.
+	 */
+	destroyExport: function (e) {
+		var chart = e.target,
+			i,
+			elem;
+
+		// Destroy the extra buttons added
+		for (i = 0; i < chart.exportSVGElements.length; i++) {
+			elem = chart.exportSVGElements[i];
+			
+			// Destroy and null the svg/vml elements
+			if (elem) { // #1822
+				elem.onclick = elem.ontouchstart = null;
+				chart.exportSVGElements[i] = elem.destroy();
+			}
+		}
+
+		// Destroy the divs for the menu
+		for (i = 0; i < chart.exportDivElements.length; i++) {
+			elem = chart.exportDivElements[i];
+
+			// Remove the event handler
+			removeEvent(elem, 'mouseleave');
+
+			// Remove inline events
+			chart.exportDivElements[i] = elem.onmouseout = elem.onmouseover = elem.ontouchstart = elem.onclick = null;
+
+			// Destroy the div by moving to garbage bin
+			discardElement(elem);
+		}
+	}
+});
+
+
+symbols.menu = function (x, y, width, height) {
+	var arr = [
+		M, x, y + 2.5,
+		L, x + width, y + 2.5,
+		M, x, y + height / 2 + 0.5,
+		L, x + width, y + height / 2 + 0.5,
+		M, x, y + height - 1.5,
+		L, x + width, y + height - 1.5
+	];
+	return arr;
+};
+
+// Add the buttons on chart load
+Chart.prototype.callbacks.push(function (chart) {
+	var n,
+		exportingOptions = chart.options.exporting,
+		buttons = exportingOptions.buttons;
+
+	buttonOffset = 0;
+
+	if (exportingOptions.enabled !== false) {
+
+		for (n in buttons) {
+			chart.addButton(buttons[n]);
+		}
+
+		// Destroy the export elements at chart destroy
+		addEvent(chart, 'destroy', chart.destroyExport);
+	}
+
+});
+
+
+}(Highcharts));

--
Gitblit v1.8.0