var defaultConfig = {

		// INHERIT
		// showScale: true,						// Boolean - If we should show the scale at all
		// scaleOverride: false,				// Boolean - If we want to override with a hard coded scale
		// ** Required if scaleOverride is true **
		// *** scaleSteps: null,				// Number - The number of steps in a hard coded scale
		// *** scaleStepWidth: null,			// Number - The value jump in the hard coded scale
		// *** scaleStartValue: null,			// Number - The scale starting value

		// scaleLineColor: "rgba(0,0,0,.1)",		// String - Colour of the scale line
		// scaleLineWidth: 1,						// Number - Pixel width of the scale line
		// scaleShowLabels: true,					// Boolean - Whether to show labels on the scale
		// scaleLabel: "<%=value%>",				// Interpolated JS string - can access value
		scaleArgLabel: "<%=value%>",				// Interpolated JS string - can access value

		// SCALE
		scaleShowGridLines: true,				//Boolean - Whether grid lines are shown across the chart
		scaleGridLineWidth: 1,					//Number - Width of the grid lines
		scaleGridLineColor: "rgba(0,0,0,.05)",	//String - Colour of the grid lines
		scaleShowHorizontalLines: true,			//Boolean - Whether to show horizontal lines (except X axis)
		scaleShowVerticalLines: true,			//Boolean - Whether to show vertical lines (except Y axis)



		// LINES
		datasetStroke: true,			// Boolean - Whether to show a stroke for datasets
		datasetStrokeWidth: 2,			// Number - Pixel width of dataset stroke
		datasetStrokeColor: '#007ACC',	// String - Color of dataset stroke

		bezierCurve: true,				// Boolean - Whether the line is curved between points
		bezierCurveTension: 0.4,		// Number - Tension of the bezier curve between points



		// POINTS
		pointDot: true,					// Boolean - Whether to show a dot for each point
		pointDotStrokeWidth: 1,			// Number - Pixel width of point dot stroke
		pointDotRadius: 4,				// Number - Radius of each point dot in pixels
		pointHitDetectionRadius: 4,		// Number - amount extra to add to the radius to cater for hit detection outside the drawn point


		multiTooltipTemplate: "<%=arg%>; <%=value%>",
		tooltipTemplate: "<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%=arg%>; <%=value%>"
	};

	chartjs.AltScale = chartjs.Element.extend({

		initialize: function () {

			// this.dataRange - минимальные и максимальные значения данных

			// инициализируем настройки
			// рассчитываем вспомогательные параметры

			this.font = helpers.fontString(this.fontSize, this.fontStyle, this.fontFamily);
			this.padding = this.fontSize * 1.5;
		},

		api: {

			getElementOrDefault: function (array, index, defaultValue) {

				return index >= 0 && index < array.length
					? array[index]
					: defaultValue;
			},

			applyRange: function (value, min, max) {

				return value > max? max
					: value < min? min
					: value;
			},

			calculateControlPoints: function (prev, current, next, range, tension) {

				var tensionBefore =!!prev? tension : 0;
				var tensionAfter =!!next? tension : 0;

				var innerCurrent = current;
				var innerPrev = prev? prev : current;
				var innerNext = next? next : current;

				var a = { xx: innerCurrent.arg - innerPrev.arg, yy: innerCurrent.value - innerPrev.value }
				var b = { xx: innerNext.arg - innerPrev.arg, yy: innerNext.value - innerPrev.value }

				var mul = a.xx * b.xx + a.yy * b.yy;
				var mod = Math.sqrt(b.xx * b.xx + b.yy * b.yy);

				var k = Math.min(Math.max(mul / (mod * mod), 0.3), 0.7);

				var result = {
					before: {
						x: innerCurrent.arg - b.xx * k * tensionBefore,
						y: innerCurrent.value - b.yy * k * tensionBefore
					},
					after: {
						x: innerCurrent.arg + b.xx * (1 - k) * tensionAfter,
						y: innerCurrent.value + b.yy * (1 - k) * tensionAfter
					}
				};

				// Cap inner bezier handles to the upper/lower scale bounds
				result.before.y = this.applyRange(result.before.y, range.ymin, range.ymax);
				result.after.y = this.applyRange(result.after.y, range.ymin, range.ymax);

				return result;
			}
		},

		fit: function () {

			// vertical labels & padding
			this.yScaleRange = helpers.calculateScaleRange(
				[this.dataRange.ymin, this.dataRange.ymax],
				this.chart.height,
				this.fontSize,
				this.beginAtZero,
				this.integersOnly);

			this.yLabels = helpers.generateLabels(
				this.labelTemplate,
				this.yScaleRange.steps,
				this.yScaleRange.min,
				this.yScaleRange.stepValue);

			this.xPadding = this.showLabels
				? helpers.longestText(this.chart.ctx, this.font, this.yLabels) + this.padding : 0;

			// horisontal labels & padding
			this.xScaleRange = helpers.calculateScaleRange(
				[this.dataRange.xmin, this.dataRange.xmax],
				this.chart.width,
				this.fontSize,
				this.beginAtZero,
				this.integersOnly);

			this.xLabels = helpers.generateLabels(
				this.argLabelTemplate,
				this.xScaleRange.steps,
				this.xScaleRange.min,
				this.xScaleRange.stepValue);

			var xStepWidth = Math.floor((this.chart.width - this.xPadding) / this.xScaleRange.steps);
			var xLabelMaxWidth = helpers.longestText(this.chart.ctx, this.font, this.xLabels);
			var xLabelHeight = this.fontSize * 1.5;

			this.xLabelRotation = xLabelMaxWidth > xStepWidth;

			this.yPadding = this.showLabels
				? (this.xLabelRotation? xLabelMaxWidth : xLabelHeight) + this.padding
				: 0;
		},

		updateBezierControlPoints: function (dataSetPoints, ease, tension) {

			for (var i = 0; i < dataSetPoints.length; i++) {

				var current = this.api.getElementOrDefault(dataSetPoints, i);
				var prev = this.api.getElementOrDefault(dataSetPoints, i - 1);
				var next = this.api.getElementOrDefault(dataSetPoints, i + 1);

				var obj = this.api.calculateControlPoints(prev, current, next, this.dataRange, tension);

				current.controlPoints = {

					x1: this.calculateX(obj.before.x),
					y1: this.calculateY(obj.before.y, ease),

					x2: this.calculateX(obj.after.x),
					y2: this.calculateY(obj.after.y, ease)
				};
			}
		},

		updatePoints: function (dataSetPoints, ease) {

			for (var i = 0; i < dataSetPoints.length; i++) {

				var current = dataSetPoints[i];

				current.x = this.calculateX(current.arg);
				current.y = this.calculateY(current.value, ease);
			}
		},

		calculateX: function (x) {

			return this.xPadding + ((x - this.xScaleRange.min) * (this.chart.width - this.xPadding) / (this.xScaleRange.max - this.xScaleRange