1/**
2 * $Id: mxBootstrap.js,v 1.0 2014/09/10 07:05:39 mate Exp $
3 * Copyright (c) 2006-2014, JGraph Ltd
4 */
5
6//**********************************************************************************************************************************************************
7//Rounded rectangle (adjustable rounding)
8//**********************************************************************************************************************************************************
9/**
10* Extends mxShape.
11*/
12function mxShapeBootstrapRRect(bounds, fill, stroke, strokewidth)
13{
14	mxShape.call(this);
15	this.bounds = bounds;
16	this.fill = fill;
17	this.stroke = stroke;
18	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
19};
20
21/**
22* Extends mxShape.
23*/
24mxUtils.extend(mxShapeBootstrapRRect, mxShape);
25
26mxShapeBootstrapRRect.prototype.cst = {
27		PACKAGE : 'mxgraph.bootstrap.rrect',
28		R_SIZE : 'rSize'
29};
30
31mxShapeBootstrapRRect.prototype.customProperties = [
32	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10}
33];
34
35/**
36* Function: paintVertexShape
37*
38* Paints the vertex shape.
39*/
40mxShapeBootstrapRRect.prototype.paintVertexShape = function(c, x, y, w, h)
41{
42	c.translate(x, y);
43
44	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeBootstrapRRect.prototype.cst.R_SIZE, '10'));
45	c.roundrect(0, 0, w, h, rSize);
46	c.fillAndStroke();
47};
48
49mxCellRenderer.registerShape(mxShapeBootstrapRRect.prototype.cst.PACKAGE, mxShapeBootstrapRRect);
50
51//**********************************************************************************************************************************************************
52//Top Button
53//**********************************************************************************************************************************************************
54/**
55* Extends mxShape.
56*/
57function mxShapeBootstrapTopButton(bounds, fill, stroke, strokewidth)
58{
59	mxShape.call(this);
60	this.bounds = bounds;
61	this.fill = fill;
62	this.stroke = stroke;
63	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
64};
65
66/**
67* Extends mxShape.
68*/
69mxUtils.extend(mxShapeBootstrapTopButton, mxShape);
70
71mxShapeBootstrapTopButton.prototype.cst = {
72		TOP_BUTTON : 'mxgraph.bootstrap.topButton',
73		R_SIZE : 'rSize'
74};
75
76mxShapeBootstrapTopButton.prototype.customProperties = [
77	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10}
78];
79
80/**
81* Function: paintVertexShape
82*
83* Paints the vertex shape.
84*/
85mxShapeBootstrapTopButton.prototype.paintVertexShape = function(c, x, y, w, h)
86{
87	c.translate(x, y);
88
89	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeBootstrapTopButton.prototype.cst.R_SIZE, '10'));
90
91	c.begin();
92	c.moveTo(0, rSize);
93	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
94	c.lineTo(w - rSize, 0);
95	c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
96	c.lineTo(w, h);
97	c.lineTo(0, h);
98	c.close();
99	c.fillAndStroke();
100};
101
102mxCellRenderer.registerShape(mxShapeBootstrapTopButton.prototype.cst.TOP_BUTTON, mxShapeBootstrapTopButton);
103
104//**********************************************************************************************************************************************************
105//Bottom Button
106//**********************************************************************************************************************************************************
107/**
108* Extends mxShape.
109*/
110function mxShapeBootstrapBottomButton(bounds, fill, stroke, strokewidth)
111{
112	mxShape.call(this);
113	this.bounds = bounds;
114	this.fill = fill;
115	this.stroke = stroke;
116	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
117};
118
119/**
120* Extends mxShape.
121*/
122mxUtils.extend(mxShapeBootstrapBottomButton, mxShape);
123
124mxShapeBootstrapBottomButton.prototype.cst = {
125		BOTTOM_BUTTON : 'mxgraph.bootstrap.bottomButton',
126		R_SIZE : 'rSize'
127};
128
129mxShapeBootstrapBottomButton.prototype.customProperties = [
130	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10}
131];
132
133/**
134* Function: paintVertexShape
135*
136* Paints the vertex shape.
137*/
138mxShapeBootstrapBottomButton.prototype.paintVertexShape = function(c, x, y, w, h)
139{
140	c.translate(x, y);
141
142	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeBootstrapBottomButton.prototype.cst.R_SIZE, '10'));
143
144	c.begin();
145	c.moveTo(0, 0);
146	c.lineTo(w, 0);
147	c.lineTo(w, h - rSize);
148	c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
149	c.lineTo(rSize, h);
150	c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
151	c.close();
152	c.fillAndStroke();
153};
154
155mxCellRenderer.registerShape(mxShapeBootstrapBottomButton.prototype.cst.BOTTOM_BUTTON, mxShapeBootstrapBottomButton);
156
157//**********************************************************************************************************************************************************
158//Right Button
159//**********************************************************************************************************************************************************
160/**
161* Extends mxShape.
162*/
163function mxShapeBootstrapRightButton(bounds, fill, stroke, strokewidth)
164{
165	mxShape.call(this);
166	this.bounds = bounds;
167	this.fill = fill;
168	this.stroke = stroke;
169	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
170};
171
172/**
173* Extends mxShape.
174*/
175mxUtils.extend(mxShapeBootstrapRightButton, mxShape);
176
177mxShapeBootstrapRightButton.prototype.cst = {
178		RIGHT_BUTTON : 'mxgraph.bootstrap.rightButton',
179		R_SIZE : 'rSize'
180};
181
182mxShapeBootstrapRightButton.prototype.customProperties = [
183	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10}
184];
185
186/**
187* Function: paintVertexShape
188*
189* Paints the vertex shape.
190*/
191mxShapeBootstrapRightButton.prototype.paintVertexShape = function(c, x, y, w, h)
192{
193	c.translate(x, y);
194
195	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeBootstrapRightButton.prototype.cst.R_SIZE, '10'));
196
197	c.begin();
198	c.moveTo(0, 0);
199	c.lineTo(w - rSize, 0);
200	c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
201	c.lineTo(w, h - rSize);
202	c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
203	c.lineTo(0, h);
204	c.close();
205	c.fillAndStroke();
206};
207
208mxCellRenderer.registerShape(mxShapeBootstrapRightButton.prototype.cst.RIGHT_BUTTON, mxShapeBootstrapRightButton);
209
210//**********************************************************************************************************************************************************
211//Left Button
212//**********************************************************************************************************************************************************
213/**
214* Extends mxShape.
215*/
216function mxShapeBootstrapLeftButton(bounds, fill, stroke, strokewidth)
217{
218	mxShape.call(this);
219	this.bounds = bounds;
220	this.fill = fill;
221	this.stroke = stroke;
222	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
223};
224
225/**
226* Extends mxShape.
227*/
228mxUtils.extend(mxShapeBootstrapLeftButton, mxShape);
229
230mxShapeBootstrapLeftButton.prototype.cst = {
231		LEFT_BUTTON : 'mxgraph.bootstrap.leftButton',
232		R_SIZE : 'rSize'
233};
234
235mxShapeBootstrapLeftButton.prototype.customProperties = [
236	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10}
237];
238
239/**
240* Function: paintVertexShape
241*
242* Paints the vertex shape.
243*/
244mxShapeBootstrapLeftButton.prototype.paintVertexShape = function(c, x, y, w, h)
245{
246	c.translate(x, y);
247
248	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeBootstrapLeftButton.prototype.cst.R_SIZE, '10'));
249
250	c.begin();
251	c.moveTo(w, 0);
252	c.lineTo(w, h);
253	c.lineTo(rSize, h);
254	c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
255	c.lineTo(0, rSize);
256	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
257	c.close();
258	c.fillAndStroke();
259};
260
261mxCellRenderer.registerShape(mxShapeBootstrapLeftButton.prototype.cst.LEFT_BUTTON, mxShapeBootstrapLeftButton);
262
263//**********************************************************************************************************************************************************
264//Left Button (Striped)
265//**********************************************************************************************************************************************************
266/**
267* Extends mxShape.
268*/
269function mxShapeBootstrapLeftButtonStriped(bounds, fill, stroke, strokewidth)
270{
271	mxShape.call(this);
272	this.bounds = bounds;
273	this.fill = fill;
274	this.stroke = stroke;
275	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
276};
277
278/**
279* Extends mxShape.
280*/
281mxUtils.extend(mxShapeBootstrapLeftButtonStriped, mxShape);
282
283mxShapeBootstrapLeftButtonStriped.prototype.cst = {
284		LEFT_BUTTON_STRIPED : 'mxgraph.bootstrap.leftButtonStriped'
285};
286
287
288
289/**
290* Function: paintVertexShape
291*
292* Paints the vertex shape.
293*/
294mxShapeBootstrapLeftButtonStriped.prototype.paintVertexShape = function(c, x, y, w, h)
295{
296	c.translate(x, y);
297
298	rSize = 5;
299	c.begin();
300	c.moveTo(w, 0);
301	c.lineTo(w, h);
302	c.lineTo(rSize, h);
303	c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
304	c.lineTo(0, rSize);
305	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
306	c.close();
307	c.fill();
308
309
310	var fillColor = '#ffffff';
311	c.setAlpha('0.2');
312	var stripeW = h * 0.5;
313
314	c.setFillColor(fillColor);
315	c.begin();
316	c.moveTo(0, h * 0.75);
317	c.lineTo(0, h * 0.25);
318	c.lineTo(h * 0.75, h);
319	c.lineTo(h * 0.25, h);
320	c.close();
321	c.fill();
322
323	var end = false;
324	var startX = stripeW * 0.5;
325
326	while (!end)
327	{
328		c.begin();
329		c.moveTo(startX, 0);
330
331		if (startX + stripeW >= w)
332		{
333			c.lineTo(w, 0);
334			c.lineTo(w, w - startX);
335		}
336		else
337		{
338			c.lineTo(startX + stripeW, 0);
339
340			if (startX + stripeW + h > w)
341			{
342				c.lineTo(w, w - startX - stripeW);
343
344				if (w - startX > h)
345				{
346					c.lineTo(w, h);
347					c.lineTo(startX + h, h);
348				}
349				else
350				{
351					c.lineTo(w, w - startX);
352				}
353			}
354			else
355			{
356				c.lineTo(startX + stripeW + h, h);
357				c.lineTo(startX + h, h);
358			}
359		}
360
361		c.close();
362		c.fill();
363
364		startX = startX + 2 * stripeW;
365
366		if (startX > w)
367		{
368			end = true;
369		}
370	}
371};
372
373mxCellRenderer.registerShape(mxShapeBootstrapLeftButtonStriped.prototype.cst.LEFT_BUTTON_STRIPED, mxShapeBootstrapLeftButtonStriped);
374
375//**********************************************************************************************************************************************************
376//Rounded Button
377//**********************************************************************************************************************************************************
378/**
379* Extends mxShape.
380*/
381function mxShapeBootstrapRoundedButton(bounds, fill, stroke, strokewidth)
382{
383	mxShape.call(this);
384	this.bounds = bounds;
385	this.fill = fill;
386	this.stroke = stroke;
387	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
388};
389
390/**
391* Extends mxShape.
392*/
393mxUtils.extend(mxShapeBootstrapRoundedButton, mxShape);
394
395mxShapeBootstrapRoundedButton.prototype.cst = {
396		ROUNDED_BUTTON : 'mxgraph.bootstrap.roundedButton'
397};
398
399
400
401/**
402* Function: paintVertexShape
403*
404* Paints the vertex shape.
405*/
406mxShapeBootstrapRoundedButton.prototype.paintVertexShape = function(c, x, y, w, h)
407{
408	c.translate(x, y);
409
410	if (w > h)
411	{
412		var r = h * 0.5;
413
414		c.begin();
415		c.moveTo(w - r, 0);
416		c.arcTo(r, r, 0, 0, 1, w - r, h);
417		c.lineTo(r, h);
418		c.arcTo(r, r, 0, 0, 1, r, 0);
419		c.close();
420		c.fillAndStroke();
421	}
422	else
423	{
424		var r = w * 0.5;
425
426		c.begin();
427		c.moveTo(0, h - r);
428		c.arcTo(r, r, 0, 0, 0, w, h - r);
429		c.lineTo(w, r);
430		c.arcTo(r, r, 0, 0, 0, 0, r);
431		c.close();
432		c.fillAndStroke();
433	}
434};
435
436mxCellRenderer.registerShape(mxShapeBootstrapRoundedButton.prototype.cst.ROUNDED_BUTTON, mxShapeBootstrapRoundedButton);
437
438//**********************************************************************************************************************************************************
439//Arrow
440//**********************************************************************************************************************************************************
441/**
442* Extends mxShape.
443*/
444function mxShapeBootstrapArrow(bounds, fill, stroke, strokewidth)
445{
446	mxShape.call(this);
447	this.bounds = bounds;
448	this.fill = fill;
449	this.stroke = stroke;
450	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
451};
452
453/**
454* Extends mxShape.
455*/
456mxUtils.extend(mxShapeBootstrapArrow, mxShape);
457
458mxShapeBootstrapArrow.prototype.cst = {
459		ARROW : 'mxgraph.bootstrap.arrow'
460};
461
462
463
464/**
465* Function: paintVertexShape
466*
467* Paints the vertex shape.
468*/
469mxShapeBootstrapArrow.prototype.paintVertexShape = function(c, x, y, w, h)
470{
471	c.translate(x, y);
472
473	c.begin();
474	c.moveTo(0, h * 0.5);
475	c.lineTo(w, h * 0.5);
476	c.moveTo(w * 0.9, 0);
477	c.lineTo(w, h * 0.5);
478	c.lineTo(w * 0.9, h);
479	c.stroke();
480};
481
482mxCellRenderer.registerShape(mxShapeBootstrapArrow.prototype.cst.ARROW, mxShapeBootstrapArrow);
483
484//**********************************************************************************************************************************************************
485//Tab Top
486//**********************************************************************************************************************************************************
487/**
488* Extends mxShape.
489*/
490function mxShapeBootstrapTabTop(bounds, fill, stroke, strokewidth)
491{
492	mxShape.call(this);
493	this.bounds = bounds;
494	this.fill = fill;
495	this.stroke = stroke;
496	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
497};
498
499/**
500* Extends mxShape.
501*/
502mxUtils.extend(mxShapeBootstrapTabTop, mxShape);
503
504mxShapeBootstrapTabTop.prototype.cst = {
505		TAB_TOP : 'mxgraph.bootstrap.tabTop',
506		R_SIZE  : 'rSize'
507};
508
509mxShapeBootstrapTabTop.prototype.customProperties = [
510	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:5}
511];
512
513/**
514* Function: paintVertexShape
515*
516* Paints the vertex shape.
517*/
518mxShapeBootstrapTabTop.prototype.paintVertexShape = function(c, x, y, w, h)
519{
520	c.translate(x, y);
521	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeBootstrapTopButton.prototype.cst.R_SIZE, '10'));
522	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
523	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
524
525	c.setStrokeColor(fillColor);
526	c.begin();
527	c.moveTo(0, rSize);
528	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
529	c.lineTo(w - rSize, 0);
530	c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
531	c.lineTo(w, h);
532	c.lineTo(0, h);
533	c.close();
534	c.fillAndStroke();
535
536	c.setStrokeColor(strokeColor);
537	c.begin();
538	c.moveTo(0, h);
539	c.lineTo(0, rSize);
540	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
541	c.lineTo(w - rSize, 0);
542	c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
543	c.lineTo(w, h);
544	c.stroke();
545};
546
547mxCellRenderer.registerShape(mxShapeBootstrapTabTop.prototype.cst.TAB_TOP, mxShapeBootstrapTabTop);
548
549//**********************************************************************************************************************************************************
550//Image
551//**********************************************************************************************************************************************************
552/**
553* Extends mxShape.
554*/
555function mxShapeBootstrapImage(bounds, fill, stroke, strokewidth)
556{
557	mxShape.call(this);
558	this.bounds = bounds;
559	this.fill = fill;
560	this.stroke = stroke;
561	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
562};
563
564/**
565* Extends mxShape.
566*/
567mxUtils.extend(mxShapeBootstrapImage, mxShape);
568
569mxShapeBootstrapImage.prototype.cst = {
570		IMAGE : 'mxgraph.bootstrap.image',
571		R_SIZE  : 'rSize'
572};
573
574mxShapeBootstrapImage.prototype.customProperties = [
575	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:5}
576];
577
578/**
579* Function: paintVertexShape
580*
581* Paints the vertex shape.
582*/
583mxShapeBootstrapImage.prototype.paintVertexShape = function(c, x, y, w, h)
584{
585	c.translate(x, y);
586	var rSize = Math.max(0, parseInt(mxUtils.getValue(this.style, mxShapeBootstrapTopButton.prototype.cst.R_SIZE, '10')));
587	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
588	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
589
590	c.begin();
591	c.moveTo(0, rSize);
592	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
593	c.lineTo(w - rSize, 0);
594	c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
595	c.lineTo(w, h - rSize);
596	c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
597	c.lineTo(rSize, h);
598	c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
599	c.close();
600	c.stroke();
601
602	var rsHalf = rSize * 0.5;
603	c.translate(rsHalf, rsHalf);
604	w = Math.max(0, w - rSize);
605	h = Math.max(0, h - rSize);
606
607	c.begin();
608	c.moveTo(0, rsHalf);
609	c.arcTo(rsHalf, rsHalf, 0, 0, 1, rsHalf, 0);
610	c.lineTo(w - rsHalf, 0);
611	c.arcTo(rsHalf, rsHalf, 0, 0, 1, w, rsHalf);
612	c.lineTo(w, h - rsHalf);
613	c.arcTo(rsHalf, rsHalf, 0, 0, 1, w - rsHalf, h);
614	c.lineTo(rsHalf, h);
615	c.arcTo(rsHalf, rsHalf, 0, 0, 1, 0, h - rsHalf);
616	c.close();
617	c.fill();
618};
619
620mxCellRenderer.registerShape(mxShapeBootstrapImage.prototype.cst.IMAGE, mxShapeBootstrapImage);
621
622//**********************************************************************************************************************************************************
623//Checkbox
624//**********************************************************************************************************************************************************
625/**
626* Extends mxShape.
627*/
628function mxShapeBootstrapCheckbox(bounds, fill, stroke, strokewidth)
629{
630	mxShape.call(this);
631	this.bounds = bounds;
632	this.fill = fill;
633	this.stroke = stroke;
634	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
635};
636
637/**
638* Extends mxShape.
639*/
640mxUtils.extend(mxShapeBootstrapCheckbox, mxShape);
641
642mxShapeBootstrapCheckbox.prototype.cst = {
643		CHECKBOX : 'mxgraph.bootstrap.checkbox'
644};
645
646
647
648/**
649* Function: paintVertexShape
650*
651* Paints the vertex shape.
652*/
653mxShapeBootstrapCheckbox.prototype.paintVertexShape = function(c, x, y, w, h)
654{
655	c.translate(x, y);
656	var rSize = 3;
657	c.roundrect(0, 0, w, h, rSize, rSize);
658	c.fillAndStroke();
659
660	c.setStrokeWidth('3');
661	c.begin();
662	c.moveTo(w * 0.8, h * 0.2);
663	c.lineTo(w * 0.4, h * 0.8);
664	c.lineTo(w * 0.25, h * 0.6);
665	c.stroke();
666};
667
668mxCellRenderer.registerShape(mxShapeBootstrapCheckbox.prototype.cst.CHECKBOX, mxShapeBootstrapCheckbox);
669
670//**********************************************************************************************************************************************************
671//Checkbox v2
672//**********************************************************************************************************************************************************
673/**
674* Extends mxShape.
675*/
676function mxShapeBootstrapCheckbox2(bounds, fill, stroke, strokewidth)
677{
678	mxShape.call(this);
679	this.bounds = bounds;
680	this.fill = fill;
681	this.stroke = stroke;
682	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
683};
684
685/**
686* Extends mxShape.
687*/
688mxUtils.extend(mxShapeBootstrapCheckbox2, mxShape);
689
690mxShapeBootstrapCheckbox2.prototype.customProperties = [
691	{name: 'checked', dispName: 'Checked', type: 'bool', defVal: false},
692	{name: 'checkedFill', dispName: 'Checked Fill Color', type: 'color', defVal: '#ffffff'},
693	{name: 'checkedStroke', dispName: 'Checked Stroke Color', type: 'color', defVal: '#000000'}
694];
695
696mxShapeBootstrapCheckbox2.prototype.cst = {
697		CHECKBOX2 : 'mxgraph.bootstrap.checkbox2'
698};
699
700/**
701* Function: paintVertexShape
702*
703* Paints the vertex shape.
704*/
705mxShapeBootstrapCheckbox2.prototype.paintVertexShape = function(c, x, y, w, h)
706{
707	var isChecked = mxUtils.getValue(this.style, 'checked', false);
708	var checkedFill = mxUtils.getValue(this.style, 'checkedFill', '#ffffff');
709	var checkedStroke = mxUtils.getValue(this.style, 'checkedStroke', '#000000');
710
711	c.translate(x, y);
712	var rSize = 2;
713
714	if (isChecked)
715	{
716		c.setFillColor(checkedFill);
717		c.setStrokeColor(checkedStroke);
718
719		c.roundrect(0, 0, w, h, rSize, rSize);
720		c.fill();
721
722		c.setStrokeWidth('2');
723		c.begin();
724		c.moveTo(w * 0.8, h * 0.2);
725		c.lineTo(w * 0.4, h * 0.75);
726		c.lineTo(w * 0.25, h * 0.6);
727		c.stroke();
728	}
729	else
730	{
731		c.roundrect(0, 0, w, h, rSize, rSize);
732		c.fillAndStroke();
733	}
734};
735
736mxCellRenderer.registerShape(mxShapeBootstrapCheckbox2.prototype.cst.CHECKBOX2, mxShapeBootstrapCheckbox2);
737
738//**********************************************************************************************************************************************************
739//Radio Button
740//**********************************************************************************************************************************************************
741/**
742* Extends mxShape.
743*/
744function mxShapeBootstrapRadioButton(bounds, fill, stroke, strokewidth)
745{
746	mxShape.call(this);
747	this.bounds = bounds;
748	this.fill = fill;
749	this.stroke = stroke;
750	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
751};
752
753/**
754* Extends mxShape.
755*/
756mxUtils.extend(mxShapeBootstrapRadioButton, mxShape);
757
758mxShapeBootstrapRadioButton.prototype.cst = {
759		RADIO_BUTTON : 'mxgraph.bootstrap.radioButton'
760};
761
762
763
764/**
765* Function: paintVertexShape
766*
767* Paints the vertex shape.
768*/
769mxShapeBootstrapRadioButton.prototype.paintVertexShape = function(c, x, y, w, h)
770{
771	c.translate(x, y);
772
773	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
774	c.ellipse(0, 0, w, h);
775	c.fillAndStroke();
776
777	c.setFillColor(strokeColor);
778	c.ellipse(w * 0.25, h * 0.25, w * 0.5, h * 0.5);
779	c.fill();
780};
781
782mxCellRenderer.registerShape(mxShapeBootstrapRadioButton.prototype.cst.RADIO_BUTTON, mxShapeBootstrapRadioButton);
783
784//**********************************************************************************************************************************************************
785//Radio Button v2
786//**********************************************************************************************************************************************************
787/**
788* Extends mxShape.
789*/
790function mxShapeBootstrapRadioButton2(bounds, fill, stroke, strokewidth)
791{
792	mxShape.call(this);
793	this.bounds = bounds;
794	this.fill = fill;
795	this.stroke = stroke;
796	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
797};
798
799/**
800* Extends mxShape.
801*/
802mxUtils.extend(mxShapeBootstrapRadioButton2, mxShape);
803
804mxShapeBootstrapRadioButton2.prototype.customProperties = [
805	{name: 'checked', dispName: 'Checked', type: 'bool', defVal: false},
806	{name: 'checkedFill', dispName: 'Checked Fill Color', type: 'color', defVal: '#ffffff'},
807	{name: 'checkedStroke', dispName: 'Checked Stroke Color', type: 'color', defVal: '#000000'}
808];
809
810mxShapeBootstrapRadioButton2.prototype.cst = {
811		RADIO_BUTTON2 : 'mxgraph.bootstrap.radioButton2'
812};
813
814/**
815* Function: paintVertexShape
816*
817* Paints the vertex shape.
818*/
819mxShapeBootstrapRadioButton2.prototype.paintVertexShape = function(c, x, y, w, h)
820{
821	var isChecked = mxUtils.getValue(this.style, 'checked', false);
822	var checkedFill = mxUtils.getValue(this.style, 'checkedFill', '#ffffff');
823	var checkedStroke = mxUtils.getValue(this.style, 'checkedStroke', '#000000');
824
825	c.translate(x, y);
826
827	if (isChecked)
828	{
829		c.setFillColor(checkedFill);
830		c.setStrokeColor(checkedFill);
831
832		c.ellipse(0, 0, w, h);
833		c.fillAndStroke();
834
835		c.setFillColor(checkedStroke);
836		c.ellipse(w * 0.2, h * 0.2, w * 0.6, h * 0.6);
837		c.fill();
838	}
839	else
840	{
841		c.ellipse(0, 0, w, h);
842		c.fillAndStroke();
843	}
844};
845
846mxCellRenderer.registerShape(mxShapeBootstrapRadioButton2.prototype.cst.RADIO_BUTTON2, mxShapeBootstrapRadioButton2);
847
848//**********************************************************************************************************************************************************
849//Horizontal Lines
850//**********************************************************************************************************************************************************
851/**
852* Extends mxShape.
853*/
854function mxShapeBootstrapHorLines(bounds, fill, stroke, strokewidth)
855{
856	mxShape.call(this);
857	this.bounds = bounds;
858	this.fill = fill;
859	this.stroke = stroke;
860	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
861};
862
863/**
864* Extends mxShape.
865*/
866mxUtils.extend(mxShapeBootstrapHorLines, mxShape);
867
868mxShapeBootstrapHorLines.prototype.cst = {
869		HOR_LINES : 'mxgraph.bootstrap.horLines'
870};
871
872
873
874/**
875* Function: paintVertexShape
876*
877* Paints the vertex shape.
878*/
879mxShapeBootstrapHorLines.prototype.paintVertexShape = function(c, x, y, w, h)
880{
881	c.translate(x, y);
882
883	c.rect(0, 0, w, h);
884	c.fill();
885
886	c.begin();
887	c.moveTo(0, 0);
888	c.lineTo(w, 0);
889	c.moveTo(0, h);
890	c.lineTo(w, h);
891	c.stroke();
892};
893
894mxCellRenderer.registerShape(mxShapeBootstrapHorLines.prototype.cst.HOR_LINES, mxShapeBootstrapHorLines);
895
896//**********************************************************************************************************************************************************
897//User 2
898//**********************************************************************************************************************************************************
899/**
900* Extends mxShape.
901*/
902function mxShapeBootstrapUserTwo(bounds, fill, stroke, strokewidth)
903{
904	mxShape.call(this);
905	this.bounds = bounds;
906	this.fill = fill;
907	this.stroke = stroke;
908	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
909};
910
911/**
912* Extends mxShape.
913*/
914mxUtils.extend(mxShapeBootstrapUserTwo, mxShape);
915
916mxShapeBootstrapUserTwo.prototype.cst = {
917		USER2 : 'mxgraph.bootstrap.user2'
918};
919
920
921
922/**
923* Function: paintVertexShape
924*
925* Paints the vertex shape.
926*/
927mxShapeBootstrapUserTwo.prototype.paintVertexShape = function(c, x, y, w, h)
928{
929	c.translate(x, y);
930
931	c.begin();
932	c.moveTo(0, h * 0.95);
933	c.arcTo(w * 0.3, h * 0.3, 0, 0, 1, w * 0.02, h * 0.87);
934	c.arcTo(w * 0.1, h * 0.1, 0, 0, 1, w * 0.08, h * 0.812);
935	c.arcTo(w * 3, h * 3, 0, 0, 1, w * 0.29, h * 0.732);
936	c.arcTo(w * 0.15, h * 0.15, 0, 0, 0, w * 0.385, h * 0.607);
937	c.arcTo(w * 0.11, h * 0.11, 0, 0, 0, w * 0.355, h * 0.53);
938	c.arcTo(w * 0.3, h * 0.3, 0, 0, 1, w * 0.305, h * 0.44);
939	c.arcTo(w * 0.33, h * 0.38, 0, 0, 1, w * 0.312, h * 0.15);
940	c.arcTo(w * 0.218, h * 0.218 , 0, 0, 1, w * 0.688, h * 0.15);
941	c.arcTo(w * 0.33, h * 0.38, 0, 0, 1, w * 0.693, h * 0.44);
942	c.arcTo(w * 0.25, h * 0.25, 0, 0, 1, w * 0.645, h * 0.53);
943	c.arcTo(w * 0.1, h * 0.1, 0, 0, 0, w * 0.612, h * 0.6);
944	c.arcTo(w * 0.15, h * 0.15, 0, 0, 0, w * 0.7, h * 0.726);
945	c.arcTo(w * 3, h * 3, 0, 0, 1, w * 0.92, h * 0.812);
946	c.arcTo(w * 0.1, h * 0.1, 0, 0, 1, w * 0.97, h * 0.865);
947	c.arcTo(w * 0.2, h * 0.2, 0, 0, 1, w * 0.995, h * 0.952);
948	c.close();
949	c.fill();
950};
951
952mxCellRenderer.registerShape(mxShapeBootstrapUserTwo.prototype.cst.USER2, mxShapeBootstrapUserTwo);
953
954//**********************************************************************************************************************************************************
955//Rating
956//**********************************************************************************************************************************************************
957/**
958* Extends mxShape.
959*/
960function mxShapeBootstrapRating(bounds, fill, stroke, strokewidth)
961{
962	mxShape.call(this);
963	this.bounds = bounds;
964	this.fill = fill;
965	this.stroke = stroke;
966	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
967};
968
969/**
970* Extends mxShape.
971*/
972mxUtils.extend(mxShapeBootstrapRating, mxShape);
973
974mxShapeBootstrapRating.prototype.cst = {
975		RATING : 'mxgraph.bootstrap.rating',
976		RATING_STYLE : 'ratingStyle',
977		RATING_SCALE : 'ratingScale',
978		RATING_HEART : 'heart',
979		RATING_STAR : 'star',
980		EMPTY_FILL_COLOR : 'emptyFillColor',
981		GRADE : 'grade'
982};
983
984mxShapeBootstrapRating.prototype.customProperties = [
985	{name: 'ratingStyle', dispName: 'Rating Style', type: 'enum',
986		enumList: [{val: 'heart', dispName: 'Heart'},
987		   {val: 'star', dispName: 'Star'}]
988	},
989	{name: 'ratingScale', dispName: 'Rating Scale', type: 'int', min:1, defVal:5},
990	{name: 'emptyFillColor', dispName: 'Inactive Color', type: 'color', defVal:'none'},
991	{name: 'grade', dispName: 'Grade', type: 'int', min:1, defVal:3}
992];
993
994/**
995* Function: paintVertexShape
996*
997* Paints the vertex shape.
998*/
999mxShapeBootstrapRating.prototype.paintVertexShape = function(c, x, y, w, h)
1000{
1001	var ratingStyle = mxUtils.getValue(this.style, mxShapeBootstrapRating.prototype.cst.RATING_STYLE, mxShapeBootstrapRating.prototype.cst.RATING_STAR);
1002	var grade = mxUtils.getValue(this.style, mxShapeBootstrapRating.prototype.cst.GRADE, '5');
1003	var ratingScale = mxUtils.getValue(this.style, mxShapeBootstrapRating.prototype.cst.RATING_SCALE, '10');
1004
1005	c.translate(x, y);
1006
1007	if (ratingStyle === mxShapeBootstrapRating.prototype.cst.RATING_STAR)
1008	{
1009		for (var i = 0; i < grade; i++)
1010		{
1011			c.begin();
1012			c.moveTo(i * h * 1.2, 0.33 * h);
1013			c.lineTo(i * h * 1.2 + 0.364 * h, 0.33 * h);
1014			c.lineTo(i * h * 1.2 + 0.475 * h, 0);
1015			c.lineTo(i * h * 1.2 + 0.586 * h, 0.33 * h);
1016			c.lineTo(i * h * 1.2 + 0.95 * h, 0.33 * h);
1017			c.lineTo(i * h * 1.2 + 0.66 * h, 0.551 * h);
1018			c.lineTo(i * h * 1.2 + 0.775 * h, 0.9 * h);
1019			c.lineTo(i * h * 1.2 + 0.475 * h, 0.684 * h);
1020			c.lineTo(i * h * 1.2 + 0.175 * h, 0.9 * h);
1021			c.lineTo(i * h * 1.2 + 0.29 * h, 0.551 * h);
1022			c.close();
1023			c.fillAndStroke();
1024		}
1025	}
1026	else if (ratingStyle === mxShapeBootstrapRating.prototype.cst.RATING_HEART)
1027	{
1028		for (var i = 0; i < grade; i++)
1029		{
1030			c.begin();
1031			c.moveTo(i * h * 1.2 + h * 0.519, h * 0.947);
1032			c.curveTo(i * h * 1.2 + h * 0.558, h * 0.908,
1033					  i * h * 1.2 + h * 0.778, h * 0.682,
1034					  i * h * 1.2 + h * 0.916, h * 0.54);
1035			c.curveTo(i * h * 1.2 + h * 1.039, h * 0.414,
1036					  i * h * 1.2 + h * 1.036, h * 0.229,
1037					  i * h * 1.2 + h * 0.924, h * 0.115);
1038			c.curveTo(i * h * 1.2 + h * 0.812, 0,
1039					  i * h * 1.2 + h * 0.631, 0,
1040					  i * h * 1.2 + h * 0.519, h * 0.115);
1041			c.curveTo(i * h * 1.2 + h * 0.408, 0,
1042					  i * h * 1.2 + h * 0.227, 0,
1043					  i * h * 1.2 + h * 0.115, h * 0.115);
1044			c.curveTo(i * h * 1.2 + h * 0.03, h * 0.229,
1045					  i * h * 1.2, h * 0.414,
1046					  i * h * 1.2 + h * 0.123, h * 0.54);
1047			c.close();
1048			c.fillAndStroke();
1049		}
1050	}
1051
1052	var emptyFillColor = mxUtils.getValue(this.style, mxShapeBootstrapRating.prototype.cst.EMPTY_FILL_COLOR, '#ffffff');
1053	c.setFillColor(emptyFillColor);
1054
1055	if (ratingStyle === mxShapeBootstrapRating.prototype.cst.RATING_STAR)
1056	{
1057		for (var i = grade; i < ratingScale; i++)
1058		{
1059			c.begin();
1060			c.moveTo(i * h * 1.2, 0.33 * h);
1061			c.lineTo(i * h * 1.2 + 0.364 * h, 0.33 * h);
1062			c.lineTo(i * h * 1.2 + 0.475 * h, 0);
1063			c.lineTo(i * h * 1.2 + 0.586 * h, 0.33 * h);
1064			c.lineTo(i * h * 1.2 + 0.95 * h, 0.33 * h);
1065			c.lineTo(i * h * 1.2 + 0.66 * h, 0.551 * h);
1066			c.lineTo(i * h * 1.2 + 0.775 * h, 0.9 * h);
1067			c.lineTo(i * h * 1.2 + 0.475 * h, 0.684 * h);
1068			c.lineTo(i * h * 1.2 + 0.175 * h, 0.9 * h);
1069			c.lineTo(i * h * 1.2 + 0.29 * h, 0.551 * h);
1070			c.close();
1071			c.fillAndStroke();
1072		}
1073	}
1074	else if (ratingStyle === mxShapeBootstrapRating.prototype.cst.RATING_HEART)
1075	{
1076		for (var i = grade; i < ratingScale; i++)
1077		{
1078			c.begin();
1079			c.moveTo(i * h * 1.2 + h * 0.519, h * 0.947);
1080			c.curveTo(i * h * 1.2 + h * 0.558, h * 0.908,
1081					  i * h * 1.2 + h * 0.778, h * 0.682,
1082					  i * h * 1.2 + h * 0.916, h * 0.54);
1083			c.curveTo(i * h * 1.2 + h * 1.039, h * 0.414,
1084					  i * h * 1.2 + h * 1.036, h * 0.229,
1085					  i * h * 1.2 + h * 0.924, h * 0.115);
1086			c.curveTo(i * h * 1.2 + h * 0.812, 0,
1087					  i * h * 1.2 + h * 0.631, 0,
1088					  i * h * 1.2 + h * 0.519, h * 0.115);
1089			c.curveTo(i * h * 1.2 + h * 0.408, 0,
1090					  i * h * 1.2 + h * 0.227, 0,
1091					  i * h * 1.2 + h * 0.115, h * 0.115);
1092			c.curveTo(i * h * 1.2 + h * 0.03, h * 0.229,
1093					  i * h * 1.2, h * 0.414,
1094					  i * h * 1.2 + h * 0.123, h * 0.54);
1095			c.close();
1096			c.fillAndStroke();
1097		}
1098	}
1099};
1100
1101mxCellRenderer.registerShape(mxShapeBootstrapRating.prototype.cst.RATING, mxShapeBootstrapRating);
1102
1103//**********************************************************************************************************************************************************
1104//Anchor (a dummy shape without visuals used for anchoring)
1105//**********************************************************************************************************************************************************
1106/**
1107* Extends mxShape.
1108*/
1109function mxShapeBoostrapAnchor(bounds, fill, stroke, strokewidth)
1110{
1111	mxShape.call(this);
1112	this.bounds = bounds;
1113};
1114
1115/**
1116* Extends mxShape.
1117*/
1118mxUtils.extend(mxShapeBoostrapAnchor, mxShape);
1119
1120mxShapeBoostrapAnchor.prototype.cst = {
1121		ANCHOR : 'mxgraph.bootstrap.anchor'
1122};
1123
1124
1125/**
1126* Function: paintVertexShape
1127*
1128* Paints the vertex shape.
1129*/
1130mxShapeBoostrapAnchor.prototype.paintVertexShape = function(c, x, y, w, h)
1131{
1132};
1133
1134mxCellRenderer.registerShape(mxShapeBoostrapAnchor.prototype.cst.ANCHOR, mxShapeBoostrapAnchor);
1135
1136//**********************************************************************************************************************************************************
1137//Range input
1138//**********************************************************************************************************************************************************
1139/**
1140* Extends mxShape.
1141*/
1142function mxShapeBootstrapRangeInput(bounds, fill, stroke, strokewidth)
1143{
1144	mxShape.call(this);
1145	this.bounds = bounds;
1146	this.fill = fill;
1147	this.stroke = stroke;
1148	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1149	this.dx = 0.3;
1150};
1151
1152/**
1153* Extends mxShape.
1154*/
1155mxUtils.extend(mxShapeBootstrapRangeInput, mxShape);
1156
1157mxShapeBootstrapRangeInput.prototype.customProperties = [
1158	{name: 'dx', dispName: 'Handle Position', type: 'float', min:0, max:1, defVal:0.3},
1159	{name: 'rangeStyle', dispName: 'Range Style', type: 'enum',
1160		enumList: [{val: 'rect', dispName: 'Rectangle'},
1161				   {val: 'rounded', dispName: 'Rounded'}]
1162	},
1163	{name: 'handleStyle', dispName: 'Handle Style', type: 'enum',
1164		enumList: [{val: 'rect', dispName: 'Rectangle'},
1165				   {val: 'circle', dispName: 'Circle'}]
1166	}
1167];
1168
1169mxShapeBootstrapRangeInput.prototype.cst = {
1170		RANGE_INPUT : 'mxgraph.bootstrap.rangeInput'
1171};
1172
1173/**
1174* Function: paintVertexShape
1175*
1176* Paints the vertex shape.
1177*/
1178mxShapeBootstrapRangeInput.prototype.paintVertexShape = function(c, x, y, w, h)
1179{
1180	var dx = w * Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'dx', this.dx))));
1181	var gradientColor = mxUtils.getValue(this.style, 'gradientColor', 'none');
1182	var fillColor = mxUtils.getValue(this.state.style, 'fillColor', '#ffffff');
1183	var strokeColor = mxUtils.getValue(this.state.style, 'strokeColor', '#000000');
1184	var gradientDir = mxUtils.getValue(this.state.style, 'gradientDirection', 'south');
1185	var rangeStyle = mxUtils.getValue(this.state.style, 'rangeStyle', 'rounded');
1186	var handleStyle = mxUtils.getValue(this.state.style, 'handleStyle', 'circle');
1187	var barH = Math.min(h * 0.5, w * 0.5);
1188	var r = barH * 0.5;
1189
1190	c.translate(x, y);
1191
1192	if (rangeStyle == 'rect')
1193	{
1194		var opacity = parseFloat(mxUtils.getValue(this.style, 'opacity', '100'));
1195		var op1 = opacity;
1196		var op2 = opacity;
1197
1198		if (fillColor == 'none')
1199		{
1200			op1 = 0;
1201		}
1202
1203		if (gradientColor == 'none')
1204		{
1205			op2 = 0;
1206		}
1207
1208		c.setGradient(fillColor, fillColor, 0, 0, w, h, gradientDir, op1, op2);
1209
1210		c.rect(0, h * 0.5 - 2, w, 4);
1211		c.fill();
1212	}
1213	else if (rangeStyle == 'rounded')
1214	{
1215		c.begin();
1216		c.moveTo(0, h * 0.5);
1217		c.arcTo(r, r, 0, 0, 1, r, h * 0.5 - r);
1218		c.lineTo(w - r, h * 0.5 - r);
1219		c.arcTo(r, r, 0, 0, 1, w, h * 0.5);
1220		c.arcTo(r, r, 0, 0, 1, w - r, h * 0.5 + r);
1221		c.lineTo(r, h * 0.5 + r);
1222		c.arcTo(r, r, 0, 0, 1, 0, h * 0.5);
1223		c.close();
1224		c.fill();
1225	}
1226
1227	if (handleStyle == 'rect')
1228	{
1229		c.setGradient(fillColor, gradientColor, 0, 0, w, h, gradientDir, op1, op2);
1230
1231		var hw = h * 0.5;
1232		c.rect(dx - hw * 0.5, 0, hw, h);
1233		c.fillAndStroke();
1234
1235		c.begin();
1236		c.moveTo(dx - hw * 0.25, h * 0.3);
1237		c.lineTo(dx + hw * 0.25, h * 0.3);
1238		c.moveTo(dx - hw * 0.25, h * 0.5);
1239		c.lineTo(dx + hw * 0.25, h * 0.5);
1240		c.moveTo(dx - hw * 0.25, h * 0.7);
1241		c.lineTo(dx + hw * 0.25, h * 0.7);
1242		c.stroke();
1243	}
1244	else if (handleStyle == 'circle')
1245	{
1246		c.setFillColor(strokeColor);
1247		c.ellipse(dx - barH, 0, 2 * barH, 2 * barH);
1248		c.fill();
1249	}
1250};
1251
1252mxCellRenderer.registerShape(mxShapeBootstrapRangeInput.prototype.cst.RANGE_INPUT, mxShapeBootstrapRangeInput);
1253
1254mxShapeBootstrapRangeInput.prototype.constraints = null;
1255
1256Graph.handleFactory[mxShapeBootstrapRangeInput.prototype.cst.RANGE_INPUT] = function(state)
1257{
1258	var handles = [Graph.createHandle(state, ['dx'], function(bounds)
1259			{
1260				var dx = Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.state.style, 'dx', this.dx))));
1261
1262				return new mxPoint(bounds.x + dx * bounds.width, bounds.y + bounds.height / 2);
1263			}, function(bounds, pt)
1264			{
1265				this.state.style['dx'] = Math.round(100 * Math.max(0, Math.min(1, (pt.x - bounds.x) / bounds.width))) / 100;
1266			})];
1267
1268	return handles;
1269}
1270
1271//**********************************************************************************************************************************************************
1272//Switch
1273//**********************************************************************************************************************************************************
1274/**
1275* Extends mxShape.
1276*/
1277function mxShapeBootstrapSwitch(bounds, fill, stroke, strokewidth)
1278{
1279	mxShape.call(this);
1280	this.bounds = bounds;
1281	this.fill = fill;
1282	this.stroke = stroke;
1283	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1284};
1285
1286/**
1287* Extends mxShape.
1288*/
1289mxUtils.extend(mxShapeBootstrapSwitch, mxShape);
1290
1291mxShapeBootstrapSwitch.prototype.customProperties = [
1292	{name: 'buttonState', dispName: 'Button State', type: 'bool', defVal : true},
1293	{name: 'onStrokeColor', dispName: 'On Stroke Color', type: 'color'},
1294	{name: 'onFillColor', dispName: 'On Fill Color', type: 'color'},
1295];
1296
1297mxShapeBootstrapSwitch.prototype.cst = {
1298		SHAPE_SWITCH : 'mxgraph.bootstrap.switch'
1299};
1300
1301/**
1302* Function: paintVertexShape
1303*
1304* Paints the vertex shape.
1305*/
1306mxShapeBootstrapSwitch.prototype.paintVertexShape = function(c, x, y, w, h)
1307{
1308	c.translate(x, y);
1309	w = Math.max(w, 2 * h);
1310	var state = mxUtils.getValue(this.style, 'buttonState', true);
1311	this.background(c, x, y, w, h, state);
1312	c.setShadow(false);
1313	this.foreground(c, x, y, w, h, state);
1314};
1315
1316mxShapeBootstrapSwitch.prototype.background = function(c, x, y, w, h, state)
1317{
1318	if (state == true)
1319	{
1320		c.setStrokeColor(mxUtils.getValue(this.style, 'onStrokeColor', '#ffffff'));
1321		c.setFillColor(mxUtils.getValue(this.style, 'onFillColor', '#0085FC'));
1322
1323		c.roundrect(0, 0, w, h, h * 0.5, h * 0.5);
1324		c.fill();
1325	}
1326	else
1327	{
1328		c.roundrect(0, 0, w, h, h * 0.5, h * 0.5);
1329		c.fillAndStroke();
1330	}
1331
1332};
1333
1334mxShapeBootstrapSwitch.prototype.foreground = function(c, x, y, w, h, state)
1335{
1336	var r = h * 0.8;
1337
1338	if (state == true)
1339	{
1340		c.setFillColor(mxUtils.getValue(this.style, 'onStrokeColor', '#ffffff'));
1341		c.ellipse(w - h * 0.9, h * 0.1, r, r);
1342		c.fill();
1343	}
1344	else
1345	{
1346		c.setFillColor(mxUtils.getValue(this.style, 'strokeColor', '#000000'));
1347		c.ellipse(h * 0.1, h * 0.1, r, r);
1348		c.fill();
1349	}
1350};
1351
1352mxCellRenderer.registerShape(mxShapeBootstrapSwitch.prototype.cst.SHAPE_SWITCH, mxShapeBootstrapSwitch);
1353
1354//**********************************************************************************************************************************************************
1355//X
1356//**********************************************************************************************************************************************************
1357/**
1358* Extends mxShape.
1359*/
1360function mxShapeBootstrapX(bounds, fill, stroke, strokewidth)
1361{
1362	mxShape.call(this);
1363	this.bounds = bounds;
1364	this.fill = fill;
1365	this.stroke = stroke;
1366	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1367};
1368
1369/**
1370* Extends mxShape.
1371*/
1372mxUtils.extend(mxShapeBootstrapX, mxShape);
1373
1374mxShapeBootstrapX.prototype.cst = {
1375		SHAPE_X : 'mxgraph.bootstrap.x'
1376};
1377
1378/**
1379* Function: paintVertexShape
1380*
1381* Paints the vertex shape.
1382*/
1383mxShapeBootstrapX.prototype.paintVertexShape = function(c, x, y, w, h)
1384{
1385	c.translate(x, y);
1386
1387	c.begin();
1388	c.moveTo(0, 0);
1389	c.lineTo(w, h);
1390	c.moveTo(w, 0);
1391	c.lineTo(0, h);
1392	c.stroke();
1393};
1394
1395mxCellRenderer.registerShape(mxShapeBootstrapX.prototype.cst.SHAPE_X, mxShapeBootstrapX);
1396
1397//**********************************************************************************************************************************************************
1398//Popover
1399//**********************************************************************************************************************************************************
1400/**
1401* Extends mxShape.
1402*/
1403function mxShapeInfographicPopover(bounds, fill, stroke, strokewidth)
1404{
1405	mxShape.call(this);
1406	this.bounds = bounds;
1407	this.fill = fill;
1408	this.stroke = stroke;
1409	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1410	this.dx = 0.5;
1411	this.dy = 0.5;
1412};
1413
1414/**
1415* Extends mxShape.
1416*/
1417mxUtils.extend(mxShapeInfographicPopover, mxActor);
1418
1419mxShapeInfographicPopover.prototype.cst = {SHAPE_POPOVER : 'mxgraph.bootstrap.popover'};
1420
1421mxShapeInfographicPopover.prototype.customProperties = [
1422	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10},
1423	{name:'dx', dispName:'Callout Position', min:0, defVal: 100},
1424	{name:'dy', dispName:'Callout Size', min:0, defVal: 30}
1425];
1426
1427/**
1428* Function: paintVertexShape
1429*
1430* Paints the vertex shape.
1431*/
1432mxShapeInfographicPopover.prototype.paintVertexShape = function(c, x, y, w, h)
1433{
1434	c.translate(x, y);
1435
1436	var r = parseInt(mxUtils.getValue(this.style, 'rSize', '10'));
1437	var dx = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'dx', this.dx))));
1438	var dy = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'dy', this.dy))));
1439
1440	var x1 = Math.max(dx - dy, 0);
1441	var x2 = Math.min(dx + dy, w);
1442
1443	c.begin();
1444	c.moveTo(r, 0);
1445	c.lineTo(w - r, 0);
1446	c.arcTo(r, r, 0, 0, 1, w, r);
1447	c.lineTo(w, h - dy - r);
1448	c.arcTo(r, r, 0, 0, 1, w - r, h - dy);
1449	c.lineTo(x2, h - dy);
1450	c.lineTo(dx, h);
1451	c.lineTo(x1, h - dy);
1452	c.lineTo(r, h - dy);
1453	c.arcTo(r, r, 0, 0, 1, 0, h - dy - r);
1454	c.lineTo(0, r);
1455	c.arcTo(r, r, 0, 0, 1, r, 0);
1456	c.close();
1457	c.fillAndStroke();
1458};
1459
1460mxCellRenderer.registerShape(mxShapeInfographicPopover.prototype.cst.SHAPE_POPOVER, mxShapeInfographicPopover);
1461
1462mxShapeInfographicPopover.prototype.constraints = null;
1463
1464Graph.handleFactory[mxShapeInfographicPopover.prototype.cst.SHAPE_POPOVER] = function(state)
1465{
1466	var handles = [Graph.createHandle(state, ['dx', 'dy'], function(bounds)
1467	{
1468		var dx = Math.max(0, Math.min(bounds.width, parseFloat(mxUtils.getValue(this.state.style, 'dx', this.dx))));
1469		var dy = Math.max(0, Math.min(bounds.height, parseFloat(mxUtils.getValue(this.state.style, 'dy', this.dy))));
1470
1471		return new mxPoint(bounds.x + dx, bounds.y + bounds.height -  dy);
1472	}, function(bounds, pt)
1473	{
1474		this.state.style['dx'] = Math.round(100 * Math.max(0, Math.min(bounds.width, pt.x - bounds.x))) / 100;
1475		this.state.style['dy'] = Math.round(100 * Math.max(0, Math.min(bounds.height, bounds.y + bounds.height - pt.y))) / 100;
1476	})];
1477
1478	return handles;
1479};
1480
1481mxShapeInfographicPopover.prototype.getConstraints = function(style, w, h)
1482{
1483	var constr = [];
1484	var dx = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'dx', this.dx))));
1485	var dy = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'dy', this.dy))));
1486	var x1 = Math.max(dx - dy * 0.35, 0);
1487	var x2 = Math.min(dx + dy * 0.35, w);
1488
1489	constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false));
1490	constr.push(new mxConnectionConstraint(new mxPoint(0.25, 0), false));
1491	constr.push(new mxConnectionConstraint(new mxPoint(0.5, 0), false));
1492	constr.push(new mxConnectionConstraint(new mxPoint(0.75, 0), false));
1493	constr.push(new mxConnectionConstraint(new mxPoint(1, 0), false));
1494	constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, (h - dy) * 0.5));
1495	constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, h - dy));
1496	constr.push(new mxConnectionConstraint(new mxPoint(0.75, 0), false, null, 0, h - dy));
1497	constr.push(new mxConnectionConstraint(new mxPoint(0.25, 0), false, null, 0, h - dy));
1498	constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx, h));
1499	constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, h - dy));
1500
1501	return (constr);
1502};
1503
1504