Legend object for generating and displaying a legend.
Constructor: new Legend(props), where props is an object containing many properties.
Other than the "items" property, it is preferable to leave other properties to their defaults
for style consistency.
339150
function(props) {
  props = defaultValue(props, {});

  this.title = props.title;

  /**
   * Gets or sets the list of items, ordered from bottom to top, with properties:
   * * `color`: CSS color description,
   * * `lineColor`: CSS color description,
   * * `multipleColors`: An array of CSS color descriptions.  A grid of these colors will be displayed in the box to the left of the item label.
   * * `title`: label placed level with middle of box
   * * `titleAbove`: label placed level with top of box
   * * `titleBelow`: label placed level with bottom of box
   * * `imageUrl`: url of image that will be drawn instead of a coloured box
   * * `imageWidth`, `imageHeight`: image dimensions
   * * `spacingAbove`: adds to itemSpacing for this item only.
   * @type {Object[]}
   */
  this.items = defaultValue(props.items, []);

  /**
   * Gets or sets a color map used to draw a smooth gradient instead of discrete color boxes.
   * @type {ColorMap}
   */
  this.gradientColorMap = props.gradientColorMap;

  /**
   * Gets or sets the maximum height of the whole color bar, unless very many items.
   * @type {Number}
   * @default 130
   */
  this.barHeightMax = defaultValue(props.barHeightMax, 130);

  /**
   * Gets or sets the minimum height of the whole color bar.
   * @type {Number}
   * @default 30
   */
  this.barHeightMin = defaultValue(props.barHeightMax, 30);

  /**
   * Gets or sets the width of each color box (and hence, the color bar)
   * @type {Number}
   * @default 30
   */
  this.itemWidth = defaultValue(props.itemWidth, 30);

  /**
   * Gets or sets the asbolute minimum height of each color box, overruling barHeightMax.
   * @type {Number}
   * @default 12
   */
  this.itemHeightMin = defaultValue(props.itemHeightMin, 12);

  /**
   * Gets or sets the forced height of each color box. Better to leave unset.
   * @type {Number}
   * @default the smaller of `props.barHeightMax / props.items.length` and 30.
   */
  this.itemHeight = props.itemHeight;

  /**
   * Gets or sets the gap between each pair of color boxes.
   * @type {Number}
   * @default 0
   */
  this.itemSpacing = defaultValue(props.itemSpacing, 0);

  /**
   * Gets or sets the spacing to the left of the color bar.
   * @type {Number}
   * @default 5
   */
  this.barLeft = defaultValue(props.barLeft, 5);

  /**
   * Gets or sets the spacing between the title and color bar.
   * @type {Number}
   * @default 5
   */
  this.barTop = defaultValue(props.barTop, 5);

  /**
   * Gets or sets the forced total width of the legend.
   * @type {Number}
   * @default 315
   */
  this.width = defaultValue(props.width, 315);

  /**
   * Gets or sets the horizontal offset of variable title.
   * @type {Number}
   * @default 5
   */
  this.variableNameLeft = defaultValue(props.variableNameLeft, 5);

  /**
   * Gets or sets the vertical offset of variable title.
   * @type {Number}
   * @default 17
   */
  this.variableNameTop = defaultValue(props.variableNameTop, 17);

  /**
   * Gets or sets the CSS class that will be applied to the legend when it is displayed.
   * This is used to ensure that the correct font is used when measuring text for word wrapping.
   * @type {String}
   */
  this.cssClass = defaultValue(props.cssClass, "tjs-legend__legend");

  this._svg = undefined;
}
194301
function (item) {
		var legend = this,
			options = legend.options,
			symbolPadding = options.symbolPadding,
			ltr = !options.rtl,
			legendItemPos = item._legendItemPos,
			itemX = legendItemPos[0],
			itemY = legendItemPos[1],
			checkbox = item.checkbox;

		if (item.legendGroup) {
			item.legendGroup.translate(
				ltr ? itemX : legend.legendWidth - itemX - 2 * symbolPadding - 4,
				itemY
			);
		}

		if (checkbox) {
			checkbox.x = itemX;
			checkbox.y = itemY;
		}
	}
105865
function inherit(x, props) {
  var r = Object.create(x);
  return extend(r, props);
}
968825
function ThemeProvider(props) {
  const { children, theme: localTheme } = props;
  const outerTheme = useTheme();

  warning(
    outerTheme !== null || typeof localTheme !== 'function',
    [
      'Material-UI: you are providing a theme function property ' +
        'to the ThemeProvider component:',
      '<ThemeProvider theme={outerTheme => outerTheme} />',
      '',
      'However, no outer theme is present.',
      'Make sure a theme is already injected higher in the React tree ' +
        'or provide a theme object.',
    ].join('\n'),
  );

  const theme = React.useMemo(() => {
    const output = outerTheme === null ? localTheme : mergeOuterLocalTheme(outerTheme, localTheme);

    if (outerTheme !== null && output) {
      output[nested] = true;
    }

    return output;
  }, [localTheme, outerTheme]);

  return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>;
}
1267253
function (options) {

            // Extend default options with user options
            options = $.extend(true, {}, Mapael.prototype.defaultOptions, options);

            // Extend legend default options
            $.each(['area', 'plot'], function (key, type) {
                if ($.isArray(options.legend[type])) {
                    for (var i = 0; i < options.legend[type].length; ++i)
                        options.legend[type][i] = $.extend(true, {}, Mapael.prototype.legendDefaultOptions[type], options.legend[type][i]);
                } else {
                    options.legend[type] = $.extend(true, {}, Mapael.prototype.legendDefaultOptions[type], options.legend[type]);
                }
            });

            return options;
        }
1345862
def _legend(self):
        """"""
        if not self.show_legend:
            return
        truncation = self.truncate_legend
        if self.legend_at_bottom:
            x = self.margin_box.left + self.spacing
            y = (
                self.margin_box.top + self.view.height + self._x_title_height +
                self._x_labels_height + self.spacing
            )
            cols = self.legend_at_bottom_columns or ceil(sqrt(self._order)
                                                         ) or 1

            if not truncation:
                available_space = self.view.width / cols - (
                    self.legend_box_size + 5
                )
                truncation = reverse_text_len(
                    available_space, self.style.legend_font_size
                )
        else:
            x = self.spacing
            y = self.margin_box.top + self.spacing
            cols = 1
            if not truncation:
                truncation = 15

        legends = self.svg.node(
            self.nodes['graph'],
            class_='legends',
            transform='translate(%d, %d)' % (x, y)
        )

        h = max(self.legend_box_size, self.style.legend_font_size)
        x_step = self.view.width / cols
        if self.legend_at_bottom:
            secondary_legends = legends  # svg node is the same
        else:

            # draw secondary axis on right
            x = self.margin_box.left + self.view.width + self.spacing
            if self._y_2nd_labels:
                h, w = get_texts_box(
                    cut(self._y_2nd_labels), self.style.label_font_size
                )
                x += self.spacing + max(
                    w * abs(cos(rad(self.y_label_rotation))), h
                )

            y = self.margin_box.top + self.spacing

            secondary_legends = self.svg.node(
                self.nodes['graph'],
                class_='legends',
                transform='translate(%d, %d)' % (x, y)
            )

        serie_number = -1
        i = 0

        for titles, is_secondary in ((self._legends, False),
                                     (self._secondary_legends, True)):
            if not self.legend_at_bottom and is_secondary:
                i = 0

            for title in titles:
                serie_number += 1
                if title is None:
                    continue
                col = i % cols
                row = i // cols

                legend = self.svg.node(
                    secondary_legends if is_secondary else legends,
                    class_='legend reactive activate-serie',
                    id="activate-serie-%d" % serie_number
                )
                self.svg.node(
                    legend,
                    'rect',
                    x=col * x_step,
                    y=1.5 * row * h + (
                        self.style.legend_font_size - self.legend_box_size
                        if self.style.legend_font_size > self.legend_box_size
                        else 0
                    ) / 2,
                    width=self.legend_box_size,
                    height=self.legend_box_size,
                    class_="color-%d reactive" % serie_number
                )

                if isinstance(title, dict):
                    node = decorate(self.svg, legend, title)
                    title = title['title']
                else:
                    node = legend

                truncated = truncate(title, truncation)
                self.svg.node(
                    node,
                    'text',
                    x=col * x_step + self.legend_box_size + 5,
                    y=1.5 * row * h + .5 * h + .3 * self.style.legend_font_size
                ).text = truncated

                if truncated != title:
                    self.svg.node(legend, 'title').text = title

                i += 1
308310
def _draw_legend(self):
        
        legend_box = self.guides.build(self)
        if not legend_box:
            return

        figure = self.figure
        left = figure.subplotpars.left
        right = figure.subplotpars.right
        top = figure.subplotpars.top
        bottom = figure.subplotpars.bottom
        W, H = figure.get_size_inches()
        position = self.guides.position
        get_property = self.theme.themeables.property
        # defaults
        spacing = 0.1
        strip_margin_x = 0
        strip_margin_y = 0

        with suppress(KeyError):
            spacing = get_property('legend_box_spacing')
        with suppress(KeyError):
            strip_margin_x = get_property('strip_margin_x')
        with suppress(KeyError):
            strip_margin_y = get_property('strip_margin_y')

        right_strip_width = self.facet.strip_size('right')
        top_strip_height = self.facet.strip_size('top')

        # Other than when the legend is on the right the rest of
        # the computed x, y locations are not gauranteed not to
        # overlap with the axes or the labels. The user must then
        # use the legend_margin theme parameter to adjust the
        # location. This should get fixed when MPL has a better
        # layout manager.
        if position == 'right':
            loc = 6
            pad = right_strip_width*(1+strip_margin_x) + spacing
            x = right + pad/W
            y = 0.5
        elif position == 'left':
            loc = 7
            x = left - spacing/W
            y = 0.5
        elif position == 'top':
            loc = 8
            x = 0.5
            pad = top_strip_height*(1+strip_margin_y) + spacing
            y = top + pad/H
        elif position == 'bottom':
            loc = 9
            x = 0.5
            y = bottom - spacing/H
        else:
            loc = 10
            x, y = position

        anchored_box = AnchoredOffsetbox(
            loc=loc,
            child=legend_box,
            pad=0.,
            frameon=False,
            bbox_to_anchor=(x, y),
            bbox_transform=figure.transFigure,
            borderpad=0.)

        anchored_box.set_zorder(90.1)
        self.figure._themeable['legend_background'] = anchored_box
        ax = self.axs[0]
        ax.add_artist(anchored_box)
654093
function colorizeItem(item, visible) {
			var legendItem = item.legendItem,
				legendLine = item.legendLine,
				legendSymbol = item.legendSymbol,
				hiddenColor = itemHiddenStyle.color,
				textColor = visible ? options.itemStyle.color : hiddenColor,
				lineColor = visible ? item.color : hiddenColor,
				symbolAttr = visible ? item.pointAttr[NORMAL_STATE] : {
					stroke: hiddenColor,
					fill: hiddenColor
				};

			if (legendItem) {
				legendItem.css({ fill: textColor });
			}
			if (legendLine) {
				legendLine.attr({ stroke: lineColor });
			}
			if (legendSymbol) {
				legendSymbol.attr(symbolAttr);
			}

		}
459130
function renderLegend() {
			itemX = initialItemX;
			itemY = y;
			offsetWidth = 0;
			lastItemY = 0;

			if (!legendGroup) {
				legendGroup = renderer.g('legend')
					.attr({ zIndex: 7 })
					.add();
			}


			// add each series or point
			allItems = [];
			each(series, function (serie) {
				var seriesOptions = serie.options;

				if (!seriesOptions.showInLegend) {
					return;
				}

				// use points or series for the legend item depending on legendType
				allItems = allItems.concat(seriesOptions.legendType === 'point' ?
					serie.data :
					serie
				);

			});

			// sort by legendIndex
			stableSort(allItems, function (a, b) {
				return (a.options.legendIndex || 0) - (b.options.legendIndex || 0);
			});

			// reversed legend
			if (reversedLegend) {
				allItems.reverse();
			}

			// render the items
			
			// PATCH by Simon Fishel
            //
            // call label render hook before rendering the legend items
            //
            // + if(hooks.labelRenderHook) {
            // +    hooks.labelRenderHook(allItems, options, itemStyle, spacingBox, renderer);
            // + }
            
            if(hooks.labelRenderHook) {
                hooks.labelRenderHook(allItems, options, itemStyle, spacingBox, renderer);
            }
			
			each(allItems, renderItem);



			// Draw the border
			legendWidth = widthOption || offsetWidth;
			legendHeight = lastItemY - y + itemHeight;

			if (legendBorderWidth || legendBackgroundColor) {
				legendWidth += 2 * padding;
				legendHeight += 2 * padding;

				if (!box) {
					box = renderer.rect(
						0,
						0,
						legendWidth,
						legendHeight,
						options.borderRadius,
						legendBorderWidth || 0
					).attr({
						stroke: options.borderColor,
						'stroke-width': legendBorderWidth || 0,
						fill: legendBackgroundColor || NONE
					})
					.add(legendGroup)
					.shadow(options.shadow);
					box.isNew = true;

				} else if (legendWidth > 0 && legendHeight > 0) {
					box[box.isNew ? 'attr' : 'animate'](
						box.crisp(null, null, null, legendWidth, legendHeight)
					);
					box.isNew = false;
				}

				// hide the border if no items
				box[allItems.length ? 'show' : 'hide']();
			}

			// 1.x compatibility: positioning based on style
			var props = ['left', 'right', 'top', 'bottom'],
				prop,
				i = 4;
			while (i--) {
				prop = props[i];
				if (style[prop] && style[prop] !== 'auto') {
					options[i < 2 ? 'align' : 'verticalAlign'] = prop;
					options[i < 2 ? 'x' : 'y'] = pInt(style[prop]) * (i % 2 ? -1 : 1);
				}
			}
			
			// PATCH by Simon Fishel
            // 
            // call placement hook before aligning the legend element
            //
            // + if(hooks.placementHook) {
            // +    hooks.placementHook(options, legendWidth, legendHeight, spacingBox);
            // + }
            
            if(hooks.placementHook) {
                hooks.placementHook(options, legendWidth, legendHeight, spacingBox);
            }

			if (allItems.length) {
				legendGroup.align(extend(options, {
					width: legendWidth,
					height: legendHeight
				}), true, spacingBox);
			}

			if (!isResizing) {
				positionCheckboxes();
			}
		}
672843
function(isInit) {
                var containerWidth = self.$map.width();

                if (self.paper.width !== containerWidth) {
                    var newScale = containerWidth / self.mapConf.width;
                    // Set new size
                    self.paper.setSize(containerWidth, self.mapConf.height * newScale);

                    // Create plots legend again to take into account the new scale
                    // Do not do this on init (it will be done later)
                    if (isInit !== true && self.options.legend.redrawOnResize) {
                        self.createLegends("plot", self.plots, newScale);
                    }
                }
            }
775267
function createElement(name, props) {
		var c = document,
			d = c.createElement(name);
		if (props && "[object Object]" === Object.prototype.toString.call(props)) {
			var e;
			for (e in props)
				if ("html" === e) d.innerHTML = props[e];
				else if ("text" === e) {
				var f = c.createTextNode(props[e]);
				d.appendChild(f);
			} else d.setAttribute(e, props[e]);
		}
		return d;
	}
618797
function (defaultOptions, elemOptions, legendOptions) {
            var self = this;
            var options = $.extend(true, {}, defaultOptions, elemOptions);
            if (options.value !== undefined) {
                if ($.isArray(legendOptions)) {
                    for (var i = 0; i < legendOptions.length; ++i) {
                        options = $.extend(true, {}, options, self.getLegendSlice(options.value[i], legendOptions[i]));
                    }
                } else {
                    options = $.extend(true, {}, options, self.getLegendSlice(options.value, legendOptions));
                }
            }
            return options;
        }
285158
function() {
            var i, j, seriesObject, loopSeries, prevSeries, loopPoint, prevStackedTotal,
                fieldNames = this.processedData.fieldNames,
                series = this.processedData.series;

            for(i = 0; i < fieldNames.length; i++) {
                if(this.shouldShowSeries(fieldNames[i], this.properties)) {
                    seriesObject = this.constructSeriesObject(fieldNames[i], series[fieldNames[i]], this.properties);
                    this.hcConfig.series.push(seriesObject);
                }
            }
            // if the legend labels have been set by the user, honor them here
            if(this.legendLabels.length > 0) {
                var label, name,
                    newSeriesList = [],

                    // helper function for finding a series by its name
                    findInSeriesList = function(name) {
                        for(var j = 0; j < this.hcConfig.series.length; j++) {
                            if(this.hcConfig.series[j].name === name) {
                                return this.hcConfig.series[j];
                            }
                        }
                        return false;
                    }.bind(this);

                // first loop through the legend labels, either get the series for that field if it already exists
                // or add an empty field if it doesn't
                for(i = 0; i < this.legendLabels.length; i++) {
                    label = this.legendLabels[i];
                    loopSeries = findInSeriesList(label);
                    if(loopSeries) {
                        newSeriesList.push(loopSeries);
                    }
                    else {
                        newSeriesList.push({
                            name: label,
                            data: []
                        });
                    }
                }

                // then loop through the series data and add back any series that weren't in the legend label list
                for(i = 0; i < this.hcConfig.series.length; i++) {
                    name = this.hcConfig.series[i].name;
                    if($.inArray(name, this.legendLabels) === -1) {
                        newSeriesList.push(this.hcConfig.series[i]);
                    }
                }
                this.hcConfig.series = newSeriesList;
            }

            // SPL-50950: to correctly handle stacked mode with log axes, we have to reduce each point's y value to
            // the post-log difference between its value and the sum of the ones before it
            // SPL-55980: bypass this logic for line charts since they are never stacked
            if(this.logYAxis && (this.properties['chart.stackMode'] in { 'stacked': true, 'stacked100': true }) && this.properties['chart'] !== 'line') {
                var numSeries = this.hcConfig.series.length,
                    lastSeries = this.hcConfig.series[numSeries - 1];

                // initialize the 'stackedTotal' of each point in the last (aka bottom) series to its pre-log y value
                for(i = 0; i < lastSeries.data.length; i++) {
                    lastSeries.data[i].stackedTotal = lastSeries.data[i].rawY;
                }
                // loop through the series list backward so that we traverse bottom to top, starting with the
                // second from the bottom
                for(i = numSeries - 2; i >= 0; i--) {
                    loopSeries = this.hcConfig.series[i];
                    prevSeries = this.hcConfig.series[i + 1];
                    for(j = 0; j < loopSeries.data.length; j++) {
                        loopPoint = loopSeries.data[j];
                        prevStackedTotal = prevSeries.data[j].stackedTotal;
                        // adjust the point's y value based on the previous point's stacked total
                        loopPoint.y = this.mathUtils.absLogBaseTen(prevStackedTotal + loopPoint.rawY)
                                            - this.mathUtils.absLogBaseTen(prevStackedTotal);
                        // also update the points stacked total for the next point to use
                        loopPoint.stackedTotal = prevStackedTotal + loopPoint.rawY;
                    }
                }
            }
        }
223033
function (legend, item) {
		var padding = legend.padding,
			legendOptions = legend.options,
			horiz = this.horiz,
			box,
			width = pick(legendOptions.symbolWidth, horiz ? 200 : 12),
			height = pick(legendOptions.symbolHeight, horiz ? 12 : 200),
			labelPadding = pick(legendOptions.labelPadding, horiz ? 16 : 30),
			itemDistance = pick(legendOptions.itemDistance, 10);

		this.setLegendColor();

		// Create the gradient
		item.legendSymbol = this.chart.renderer.rect(
			0,
			legend.baseline - 11,
			width,
			height
		).attr({
			zIndex: 1
		}).add(item.legendGroup);
		box = item.legendSymbol.getBBox();

		// Set how much space this legend item takes up
		this.legendItemWidth = width + padding + (horiz ? itemDistance : labelPadding);
		this.legendItemHeight = height + padding + (horiz ? labelPadding : 0);
	}
695125
function () {

		var options = chart.options.legend;

		if (!options.enabled) {
			return;
		}

		var horizontal = options.layout === 'horizontal',
			symbolWidth = options.symbolWidth,
			symbolPadding = options.symbolPadding,
			allItems,
			style = options.style,
			itemStyle = options.itemStyle,
			itemHoverStyle = options.itemHoverStyle,
			itemHiddenStyle = options.itemHiddenStyle,
			padding = pInt(style.padding),
			y = 18,
			initialItemX = 4 + padding + symbolWidth + symbolPadding,
			itemX,
			itemY,
			lastItemY,
			itemHeight = 0,
			box,
			legendBorderWidth = options.borderWidth,
			legendBackgroundColor = options.backgroundColor,
			legendGroup,
			offsetWidth,
			widthOption = options.width,
			series = chart.series,
			reversedLegend = options.reversed;

		// PATCH by Simon Fishel
        //
        // read in hooks from the options object
        //
        // + var hooks = options.hooks || {};
        
        var hooks = options.hooks || {};

		/**
		 * Set the colors for the legend item
		 * @param {Object} item A Series or Point instance
		 * @param {Object} visible Dimmed or colored
		 */
		function colorizeItem(item, visible) {
			var legendItem = item.legendItem,
				legendLine = item.legendLine,
				legendSymbol = item.legendSymbol,
				hiddenColor = itemHiddenStyle.color,
				textColor = visible ? options.itemStyle.color : hiddenColor,
				lineColor = visible ? item.color : hiddenColor,
				symbolAttr = visible ? item.pointAttr[NORMAL_STATE] : {
					stroke: hiddenColor,
					fill: hiddenColor
				};

			if (legendItem) {
				legendItem.css({ fill: textColor });
			}
			if (legendLine) {
				legendLine.attr({ stroke: lineColor });
			}
			if (legendSymbol) {
				legendSymbol.attr(symbolAttr);
			}

		}

		/**
		 * Position the legend item
		 * @param {Object} item A Series or Point instance
		 * @param {Object} visible Dimmed or colored
		 */
		function positionItem(item, itemX, itemY) {
			var legendItem = item.legendItem,
				legendLine = item.legendLine,
				legendSymbol = item.legendSymbol,
				checkbox = item.checkbox;
			if (legendItem) {
				legendItem.attr({
					x: itemX,
					y: itemY
				});
			}
			if (legendLine) {
				legendLine.translate(itemX, itemY - 4);
			}
			if (legendSymbol) {
				legendSymbol.attr({
					x: itemX + legendSymbol.xOff,
					y: itemY + legendSymbol.yOff
				});
			}
			if (checkbox) {
				checkbox.x = itemX;
				checkbox.y = itemY;
			}
		}

		/**
		 * Destroy a single legend item
		 * @param {Object} item The series or point
		 */
		function destroyItem(item) {
			var checkbox = item.checkbox;

			// pull out from the array
			//erase(allItems, item);

			// destroy SVG elements
			each(['legendItem', 'legendLine', 'legendSymbol'], function (key) {
				if (item[key]) {
					item[key].destroy();
				}
			});

			if (checkbox) {
				discardElement(item.checkbox);
			}


		}

		/**
		 * Destroys the legend.
		 */
		function destroy() {
			if (box) {
				box = box.destroy();
			}

			if (legendGroup) {
				legendGroup = legendGroup.destroy();
			}
		}

		/**
		 * Position the checkboxes after the width is determined
		 */
		function positionCheckboxes() {
			each(allItems, function (item) {
				var checkbox = item.checkbox,
					alignAttr = legendGroup.alignAttr;
				if (checkbox) {
					css(checkbox, {
						left: (alignAttr.translateX + item.legendItemWidth + checkbox.x - 40) + PX,
						top: (alignAttr.translateY + checkbox.y - 11) + PX
					});
				}
			});
		}

		/**
		 * Render a single specific legend item
		 * @param {Object} item A series or point
		 */
		function renderItem(item) {
			var bBox,
				itemWidth,
				legendSymbol,
				symbolX,
				symbolY,
				simpleSymbol,
				li = item.legendItem,
				series = item.series || item,
				itemOptions = series.options,
				strokeWidth = (itemOptions && itemOptions.borderWidth) || 0;

			if (!li) { // generate it once, later move it

				// let these series types use a simple symbol
				simpleSymbol = /^(bar|pie|area|column)$/.test(series.type);

				// generate the list item text
				item.legendItem = li = renderer.text(
						options.labelFormatter.call(item),
						0,
						0
					)
					.css(item.visible ? itemStyle : itemHiddenStyle)
					.on('mouseover', function () {
						item.setState(HOVER_STATE);
						li.css(itemHoverStyle);
					})
					.on('mouseout', function () {
						li.css(item.visible ? itemStyle : itemHiddenStyle);
						item.setState();
					})
					
					// PATCH by Simon Fishel
					// 
					// see below
					// 
					// - .on('click', function () {
					// + .on('click', function (event) {
					
					.on('click', function (event) {
						var strLegendItemClick = 'legendItemClick',
							fnLegendItemClick = function () {
								item.setVisible();
							};
						
						// PATCH by Simon Fishel
						//
						// passing any control/command key modifiers to the event handler
						//
						// + var eventArgs = {
                        // +     ctrlKey: event.ctrlKey,
                        // +     metaKey: event.metaKey
                        // + };
						//
						//   // click the name or symbol
	                    //   if (item.firePointEvent) { // point
						// -     item.firePointEvent(strLegendItemClick, null, fnLegendItemClick);
	                    // +     item.firePointEvent(strLegendItemClick, eventArgs, fnLegendItemClick);
	                    //   } else {
						// -     fireEvent(item, strLegendItemClick, null, fnLegendItemClick);
	                    // +     fireEvent(item, strLegendItemClick, eventArgs, fnLegendItemClick);
	                    //   }
							
						var eventArgs = {
						    ctrlKey: event.ctrlKey,
						    metaKey: event.metaKey
						};

						// click the name or symbol
						if (item.firePointEvent) { // point
							item.firePointEvent(strLegendItemClick, eventArgs, fnLegendItemClick);
						} else {
							fireEvent(item, strLegendItemClick, eventArgs, fnLegendItemClick);
						}
					})
					.attr({ zIndex: 2 })
					.add(legendGroup);

				// draw the line
				if (!simpleSymbol && itemOptions && itemOptions.lineWidth) {
					var attrs = {
							'stroke-width': itemOptions.lineWidth,
							zIndex: 2
						};
					if (itemOptions.dashStyle) {
						attrs.dashstyle = itemOptions.dashStyle;
					}
					item.legendLine = renderer.path([
						M,
						-symbolWidth - symbolPadding,
						0,
						L,
						-symbolPadding,
						0
					])
					.attr(attrs)
					.add(legendGroup);
				}

				// draw a simple symbol
				if (simpleSymbol) { // bar|pie|area|column

					legendSymbol = renderer.rect(
						(symbolX = -symbolWidth - symbolPadding),
						(symbolY = -11),
						symbolWidth,
						12,
						2
					).attr({
						//'stroke-width': 0,
						zIndex: 3
					}).add(legendGroup);

				// draw the marker
				} else if (itemOptions && itemOptions.marker && itemOptions.marker.enabled) {
					legendSymbol = renderer.symbol(
						item.symbol,
						(symbolX = -symbolWidth / 2 - symbolPadding),
						(symbolY = -4),
						itemOptions.marker.radius
					)
					//.attr(item.pointAttr[NORMAL_STATE])
					.attr({ zIndex: 3 })
					.add(legendGroup);

				}
				if (legendSymbol) {
					legendSymbol.xOff = symbolX + (strokeWidth % 2 / 2);
					legendSymbol.yOff = symbolY + (strokeWidth % 2 / 2);
				}

				item.legendSymbol = legendSymbol;

				// colorize the items
				colorizeItem(item, item.visible);


				// add the HTML checkbox on top
				if (itemOptions && itemOptions.showCheckbox) {
					item.checkbox = createElement('input', {
						type: 'checkbox',
						checked: item.selected,
						defaultChecked: item.selected // required by IE7
					}, options.itemCheckboxStyle, container);

					addEvent(item.checkbox, 'click', function (event) {
						var target = event.target;
						fireEvent(item, 'checkboxClick', {
								checked: target.checked
							},
							function () {
								item.select();
							}
						);
					});
				}
			}


			// calculate the positions for the next line
			bBox = li.getBBox();

			itemWidth = item.legendItemWidth =
				options.itemWidth || symbolWidth + symbolPadding + bBox.width + padding;
			itemHeight = bBox.height;

			// if the item exceeds the width, start a new line
			if (horizontal && itemX - initialItemX + itemWidth >
					(widthOption || (chartWidth - 2 * padding - initialItemX))) {
				itemX = initialItemX;
				itemY += itemHeight;
			}
			lastItemY = itemY;

			// position the newly generated or reordered items
			positionItem(item, itemX, itemY);

			// advance
			if (horizontal) {
				itemX += itemWidth;
			} else {
				itemY += itemHeight;
			}

			// the width of the widest item
			offsetWidth = widthOption || mathMax(
				horizontal ? itemX - initialItemX : itemWidth,
				offsetWidth
			);



			// add it all to an array to use below
			//allItems.push(item);
		}

		/**
		 * Render the legend. This method can be called both before and after
		 * chart.render. If called after, it will only rearrange items instead
		 * of creating new ones.
		 */
		function renderLegend() {
			itemX = initialItemX;
			itemY = y;
			offsetWidth = 0;
			lastItemY = 0;

			if (!legendGroup) {
				legendGroup = renderer.g('legend')
					.attr({ zIndex: 7 })
					.add();
			}


			// add each series or point
			allItems = [];
			each(series, function (serie) {
				var seriesOptions = serie.options;

				if (!seriesOptions.showInLegend) {
					return;
				}

				// use points or series for the legend item depending on legendType
				allItems = allItems.concat(seriesOptions.legendType === 'point' ?
					serie.data :
					serie
				);

			});

			// sort by legendIndex
			stableSort(allItems, function (a, b) {
				return (a.options.legendIndex || 0) - (b.options.legendIndex || 0);
			});

			// reversed legend
			if (reversedLegend) {
				allItems.reverse();
			}

			// render the items
			
			// PATCH by Simon Fishel
            //
            // call label render hook before rendering the legend items
            //
            // + if(hooks.labelRenderHook) {
            // +    hooks.labelRenderHook(allItems, options, itemStyle, spacingBox, renderer);
            // + }
            
            if(hooks.labelRenderHook) {
                hooks.labelRenderHook(allItems, options, itemStyle, spacingBox, renderer);
            }
			
			each(allItems, renderItem);



			// Draw the border
			legendWidth = widthOption || offsetWidth;
			legendHeight = lastItemY - y + itemHeight;

			if (legendBorderWidth || legendBackgroundColor) {
				legendWidth += 2 * padding;
				legendHeight += 2 * padding;

				if (!box) {
					box = renderer.rect(
						0,
						0,
						legendWidth,
						legendHeight,
						options.borderRadius,
						legendBorderWidth || 0
					).attr({
						stroke: options.borderColor,
						'stroke-width': legendBorderWidth || 0,
						fill: legendBackgroundColor || NONE
					})
					.add(legendGroup)
					.shadow(options.shadow);
					box.isNew = true;

				} else if (legendWidth > 0 && legendHeight > 0) {
					box[box.isNew ? 'attr' : 'animate'](
						box.crisp(null, null, null, legendWidth, legendHeight)
					);
					box.isNew = false;
				}

				// hide the border if no items
				box[allItems.length ? 'show' : 'hide']();
			}

			// 1.x compatibility: positioning based on style
			var props = ['left', 'right', 'top', 'bottom'],
				prop,
				i = 4;
			while (i--) {
				prop = props[i];
				if (style[prop] && style[prop] !== 'auto') {
					options[i < 2 ? 'align' : 'verticalAlign'] = prop;
					options[i < 2 ? 'x' : 'y'] = pInt(style[prop]) * (i % 2 ? -1 : 1);
				}
			}
			
			// PATCH by Simon Fishel
            // 
            // call placement hook before aligning the legend element
            //
            // + if(hooks.placementHook) {
            // +    hooks.placementHook(options, legendWidth, legendHeight, spacingBox);
            // + }
            
            if(hooks.placementHook) {
                hooks.placementHook(options, legendWidth, legendHeight, spacingBox);
            }

			if (allItems.length) {
				legendGroup.align(extend(options, {
					width: legendWidth,
					height: legendHeight
				}), true, spacingBox);
			}

			if (!isResizing) {
				positionCheckboxes();
			}
		}


		// run legend
		renderLegend();

		// move checkboxes
		addEvent(chart, 'endResize', positionCheckboxes);

		// expose
		return {
			colorizeItem: colorizeItem,
			destroyItem: destroyItem,
			renderLegend: renderLegend,
			destroy: destroy
		};
	}
1365797
function (elements, legend) {
            var elements = elements || [];
            for (var i = 0; i < elements.length; i++) {
                if (elements[i].classList.contains(this.stylings.error) === false)
                    elements[i].classList.add(this.stylings.error);
                var legend = elements[i].getAttribute("data-label") || legend;
                var parent = elements[i].parentNode;
                parent.setAttribute("data-hint", legend);
                if (i === 0)
                    elements[i].focus();
            }
        }
222870
function Component (props) {
  this._parent = null
  this._collector = { refs: [], components: [] }

  /**
   * > Contains all component properties and children. <br>
   * > Do not modify it directly, but recreate a new component using `cloneElement` instead
   * @type {object}
   * @category Properties
   */
  this.props = props || {}

  /**
   * > HTMLElement used as "base" for the component instance. Can also be an array of elements if `template` return an array.
   * @type {(VNode|HTMLElement|array)}
   * @category Properties
   */
  this.base = null

  /**
   * Set to true when component is mounted
   * @type {boolean}
   * @category Properties
   */
  this.mounted = false
}