1/**
2 * $Id: mxRack.js,v 1.5 2014/01/21 13:10:37 gaudenz Exp $
3 * Copyright (c) 2006-2013, JGraph Ltd
4 */
5//**********************************************************************************************************************************************************
6//Rack Numbering
7//**********************************************************************************************************************************************************
8
9//**********************************************************************************************************************************************************
10// v2 Rack cabinet, old versions below this
11//**********************************************************************************************************************************************************
12
13//**********************************************************************************************************************************************************
14//START LEGACY RACKS
15//**********************************************************************************************************************************************************
16function mxRackContainer(bounds, fill, stroke, strokewidth)
17{
18	mxShape.call(this);
19	this.bounds = bounds;
20	this.fill = fill;
21	this.stroke = stroke;
22	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
23};
24
25/**
26 * Extends mxShape.
27 */
28mxUtils.extend(mxRackContainer, mxShape);
29
30mxRackContainer.prototype.unitSize = 20;
31
32mxRackContainer.prototype.cst =
33{
34		SHAPE_RACK_CONTAINER : 'mxgraph.rackGeneral.container',
35		TEXT_COLOR : 'textColor',
36		NUMBER_DISPLAY : 'numDisp',
37		OFF : 'off',
38		DIR_ASC : 'ascend',
39		DIR_DESC : 'descend'
40};
41
42mxRackContainer.prototype.customProperties = [
43	{name: 'fillColor2', dispName: 'Cabinet Color', type: 'color'},
44	{name: 'textColor', dispName: 'Numbers Color', type: 'color'},
45	{name: 'numDisp', dispName: 'Display Numbers', type: 'enum',
46		enumList: [{val: 'off', dispName: 'Off'}, {val: 'ascend', dispName: 'Ascending'}, {val: 'descend', dispName: 'Descending'}],
47		onChange: function(graph, newValue)
48		{
49			graph.setCellStyles('marginLeft', (newValue == 'off') ? 9 : 33, graph.getSelectionCells());
50		}
51	},
52	{name: 'rackUnitSize', dispName: 'Unit size', type: 'int'}
53];
54
55/**
56 * Function: paintVertexShape
57 *
58 * Paints the vertex shape.
59 */
60mxRackContainer.prototype.paintVertexShape = function(c, x, y, w, h)
61{
62	var fontSize = 12;
63	var displayNumbers = mxUtils.getValue(this.style, mxRackContainer.prototype.cst.NUMBER_DISPLAY, mxRackContainer.prototype.cst.DIR_ASC);
64	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
65	var fillColor2 = mxUtils.getValue(this.style, 'fillColor2', '#f4f4f4');
66
67	if (displayNumbers !== mxRackContainer.prototype.cst.OFF)
68	{
69		c.translate(x + fontSize * 2, y);
70		w = Math.max(w - fontSize * 2, 0);
71	}
72	else
73	{
74		c.translate(x, y);
75	};
76
77	c.setFillColor(fillColor);
78	this.background(c, w, h, fontSize);
79	c.setShadow(false);
80	c.setFillColor(fillColor2);
81	this.foreground(c, w, h, fontSize);
82
83	if (displayNumbers !== mxRackContainer.prototype.cst.OFF && w > 18 + fontSize * 2)
84	{
85		this.sideText(c, w, h, fontSize);
86	};
87};
88
89mxRackContainer.prototype.background = function(c, w, h, fontSize)
90{
91	c.rect(0, 0, w, h);
92	c.fillAndStroke();
93};
94
95mxRackContainer.prototype.foreground = function(c, w, h, fontSize)
96{
97	if (w > 18 + fontSize * 2 && h > 42)
98	{
99		c.rect(0, 0, w, 21);
100		c.fillAndStroke();
101		c.rect(0, h - 21, w, 21);
102		c.fillAndStroke();
103		c.rect(0, 21, 9, h - 42);
104		c.fillAndStroke();
105		c.rect(w - 9, 21, 9, h - 42);
106		c.fillAndStroke();
107		c.ellipse(2.5, 7.5, 6, 6);
108		c.stroke();
109		c.ellipse(w - 8.5, 7.5, 6, 6);
110		c.stroke();
111		c.ellipse(2.5, h - 13.5, 6, 6);
112		c.stroke();
113		c.ellipse(w - 8.5, h - 13.5, 6, 6);
114		c.stroke();
115	}
116};
117
118mxRackContainer.prototype.sideText = function(c, w, h, fontSize)
119{
120	var fontColor = mxUtils.getValue(this.style, mxRackContainer.prototype.cst.TEXT_COLOR, '#666666');
121	var displayNumbers = mxUtils.getValue(this.style, mxRackContainer.prototype.cst.NUMBER_DISPLAY, mxRackContainer.prototype.cst.DIR_ASC);
122	var unitSize = parseFloat(mxUtils.getValue(this.style, 'rackUnitSize', mxRackContainer.prototype.unitSize));
123	this.unitSize = unitSize;
124
125	c.setFontSize(fontSize);
126	c.setFontColor(fontColor);
127
128	// Calculate number of units
129	var units = Math.floor((Math.abs(h) - 42) / unitSize);
130
131	for (var i = 0; i < units; i++)
132	{
133		var displayNumber = (displayNumbers === mxRackContainer.prototype.cst.DIR_DESC) ? (i + 1).toString() : (units - i).toString();
134		c.text(-fontSize, 21 + unitSize * 0.5 + i * unitSize, 0, 0, displayNumber, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
135	}
136
137	c.begin();
138
139	for (var i = 0; i < units + 1; i++)
140	{
141		c.moveTo(-2 * fontSize, 21 + i * unitSize);
142		c.lineTo(0, 21 + i * unitSize);
143	};
144
145	c.stroke();
146};
147
148/**
149* Extends mxShape.
150*/
151function mxRackPlate(bounds, fill, stroke, strokewidth)
152{
153	mxShape.call(this);
154	this.bounds = bounds;
155	this.fill = fill;
156	this.stroke = stroke;
157	this.strokewidth = 1;
158};
159
160/**
161* Extends mxShape.
162*/
163mxUtils.extend(mxRackPlate, mxShape);
164
165mxRackPlate.prototype.cst =
166{
167		SHAPE_RACK_PLATE : 'mxgraph.rackGeneral.plate'
168};
169
170/**
171* Function: paintVertexShape
172*
173* Paints the vertex shape.
174*/
175mxRackPlate.prototype.paintVertexShape = function(c, x, y, w, h)
176{
177	c.translate(x, y);
178	this.background(c, w, h);
179	c.setShadow(false);
180	this.foreground(c, w, h);
181};
182
183mxRackPlate.prototype.background = function(c, w, h)
184{
185	c.begin();
186	c.rect(0, 0, w, h);
187	c.fillAndStroke();
188};
189
190mxRackPlate.prototype.foreground = function(c, w, h)
191{
192	var bufferSize = 9;
193
194	if (w > bufferSize * 2)
195	{
196		c.save();
197		c.setFillColor('#000000');
198		c.setAlpha(0.23);
199		c.rect(0,0, bufferSize, h);
200		c.fill();
201		c.rect(w - bufferSize,0, bufferSize, h);
202		c.fill();
203		c.restore();
204		c.rect(0, 0, w, h);
205		c.stroke();
206		c.rect(bufferSize, 0, w - bufferSize * 2, h);
207		c.stroke();
208	}
209};
210
211//**********************************************************************************************************************************************************
212//Horizontal Cable Duct
213//**********************************************************************************************************************************************************
214/**
215* Extends mxShape.
216*/
217function mxRackHorCableDuct(bounds, fill, stroke, strokewidth)
218{
219	mxShape.call(this);
220	this.bounds = bounds;
221	this.fill = fill;
222	this.stroke = stroke;
223	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
224};
225
226/**
227* Extends mxShape.
228*/
229mxUtils.extend(mxRackHorCableDuct, mxShape);
230
231mxRackHorCableDuct.prototype.cst =
232{
233		SHAPE_RACK_HOR_CABLE_DUCT : 'mxgraph.rackGeneral.horCableDuct'
234};
235
236/**
237* Function: paintVertexShape
238*
239* Paints the vertex shape.
240*/
241mxRackHorCableDuct.prototype.paintVertexShape = function(c, x, y, w, h)
242{
243	c.translate(x, y);
244	this.background(c, w, h);
245	c.setShadow(false);
246	this.foreground(c, w, h);
247};
248
249mxRackHorCableDuct.prototype.background = function(c, w, h)
250{
251	c.rect(0, 0, w, h);
252	c.fillAndStroke();
253};
254
255mxRackHorCableDuct.prototype.foreground = function(c, w, h)
256{
257	// Divide the space equally with 33 between each duct
258	var spaceBuffer = 20;
259	var unitSpacing = 33;
260	var unitsAcross = Math.floor((w - spaceBuffer) / unitSpacing);
261	var buffer = spaceBuffer / 2 + Math.floor(((w - spaceBuffer) - unitsAcross * unitSpacing) / 2);
262
263	if (unitsAcross > 0)
264	{
265		for (var i = 0; i <= unitsAcross; i++)
266		{
267			c.rect(buffer, 0, 3, 7);
268			c.stroke();
269			c.rect(buffer, 7, 3, 7.8);
270			c.stroke();
271
272			buffer += unitSpacing;
273		}
274	}
275};
276
277function mxRackHorRoutingBank(bounds, fill, stroke, strokewidth)
278{
279	mxShape.call(this);
280	this.bounds = bounds;
281	this.fill = fill;
282	this.stroke = stroke;
283	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
284};
285
286/**
287* Extends mxShape.
288*/
289mxUtils.extend(mxRackHorRoutingBank, mxShape);
290
291mxRackHorRoutingBank.prototype.cst =
292{
293		SHAPE_RACK_HOR_ROUTING_BANK : 'mxgraph.rackGeneral.horRoutingBank'
294};
295
296/**
297* Function: paintVertexShape
298*
299* Paints the vertex shape.
300*/
301mxRackHorRoutingBank.prototype.paintVertexShape = function(c, x, y, w, h)
302{
303	c.translate(x, y);
304	this.background(c, w, h);
305	c.setShadow(false);
306	this.foreground(c, w, h);
307};
308
309mxRackHorRoutingBank.prototype.background = function(c, w, h)
310{
311	c.rect(0, 0, w, h);
312	c.fillAndStroke();
313};
314
315mxRackHorRoutingBank.prototype.foreground = function(c, w, h)
316{
317	// Divide the space equally with 33 between each duct
318	var spaceBuffer = 20;
319	var unitSpacing = 22;
320	var rectWidth = 16;
321	var unitsAcross = Math.floor((w - spaceBuffer - rectWidth) / unitSpacing);
322	var unitsDown = Math.floor(h / mxRackContainer.unitSize);
323
324	if (unitsAcross > 0 && unitsDown > 0)
325	{
326		for (var i = 0; i < unitsDown; i++)
327		{
328			var buffer = (spaceBuffer + rectWidth) / 2 + Math.floor(((w - spaceBuffer - rectWidth) - unitsAcross * unitSpacing) / 2) - rectWidth / 2;
329
330			for (var j = 0; j <= unitsAcross; j++)
331			{
332				c.rect(buffer, 4 + (i * mxRackContainer.unitSize), rectWidth, 6.8);
333				c.stroke();
334
335				buffer += unitSpacing;
336			}
337		}
338	}
339};
340
341function mxRackNeatPatch(bounds, fill, stroke, strokewidth)
342{
343	mxShape.call(this);
344	this.bounds = bounds;
345	this.fill = fill;
346	this.stroke = stroke;
347	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
348};
349
350/**
351* Extends mxShape.
352*/
353mxUtils.extend(mxRackNeatPatch, mxShape);
354
355mxRackNeatPatch.prototype.cst =
356{
357		SHAPE_RACK_NEAT_PATCH : 'mxgraph.rackGeneral.neatPatch'
358};
359
360/**
361* Function: paintVertexShape
362*
363* Paints the vertex shape.
364*/
365mxRackNeatPatch.prototype.paintVertexShape = function(c, x, y, w, h)
366{
367	c.translate(x, y);
368	this.background(c, w, h);
369	c.setShadow(false);
370	this.mainText(c, w, h);
371};
372
373mxRackNeatPatch.prototype.background = function(c, w, h)
374{
375	c.setFillColor('#666666');
376	c.rect(0, 0, w, h);
377	c.fillAndStroke();
378};
379
380mxRackNeatPatch.prototype.mainText = function(c, w, h)
381{
382	c.setFontSize('12');
383	c.setFontColor('#ffffff');
384	c.setFontStyle(mxConstants.FONT_BOLD);
385	c.text(w / 2, h - 6, 0, 0, 'NEAT-PATCH', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
386};
387
388function mxRackShelf(bounds, fill, stroke, strokewidth)
389{
390	mxShape.call(this);
391	this.bounds = bounds;
392	this.fill = fill;
393	this.stroke = stroke;
394	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
395};
396
397/**
398* Extends mxShape.
399*/
400mxUtils.extend(mxRackShelf, mxShape);
401
402mxRackShelf.prototype.cst =
403{
404		SHAPE_RACK_SHELF : 'mxgraph.rackGeneral.shelf'
405};
406
407/**
408* Function: paintVertexShape
409*
410* Paints the vertex shape.
411*/
412mxRackShelf.prototype.paintVertexShape = function(c, x, y, w, h)
413{
414	c.translate(x, y);
415	this.background(c, w, h);
416};
417
418mxRackShelf.prototype.background = function(c, w, h)
419{
420	c.setStrokeWidth(2);
421	c.begin();
422	c.moveTo(1, 0);
423	c.lineTo(1, h - 1);
424	c.lineTo(w - 1, h - 1);
425	c.lineTo(w - 1, 1);
426	c.fillAndStroke();
427};
428
429function mxRackRackNumbering(bounds, fill, stroke, strokewidth)
430{
431	mxShape.call(this);
432	this.bounds = bounds;
433	this.fill = fill;
434	this.stroke = stroke;
435	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
436};
437
438/**
439 * Extends mxShape.
440 */
441mxUtils.extend(mxRackRackNumbering, mxShape);
442
443mxRackRackNumbering.prototype.cst =
444{
445		SHAPE_RACK_RACK_NUMBERING : 'mxgraph.rackGeneral.rackNumbering',
446		UNIT_NUM : 'unitNum',
447		UNIT_HEIGHT : 'unitHeight',
448		TEXT_COLOR : 'textColor',
449		NUM_DIR : 'numDir',
450		DIR_ASC : 'ascend',
451		DIR_DESC : 'descend',
452		TEXT_SIZE : 'textSize'
453};
454
455/**
456 * Function: paintVertexShape
457 *
458 * Paints the vertex shape.
459 */
460mxRackRackNumbering.prototype.paintVertexShape = function(c, x, y, w, h)
461{
462	var unitNum = parseFloat(mxUtils.getValue(this.style, mxRackRackNumbering.prototype.cst.UNIT_NUM, '42'));
463	var unitH = parseFloat(mxUtils.getValue(this.style, mxRackRackNumbering.prototype.cst.UNIT_HEIGHT, '14.8'));
464	var fontSize = parseFloat(mxUtils.getValue(this.style, mxRackRackNumbering.prototype.cst.TEXT_SIZE, '12'));
465	c.translate(x, y);
466
467	var h = unitNum * unitH;
468	this.background(c, w, h, fontSize);
469	c.setShadow(false);
470	this.sideText(c, w, h, unitNum, unitH, fontSize);
471};
472
473mxRackRackNumbering.prototype.background = function(c, w, h, fontSize)
474{
475	c.rect(fontSize * 3, 0, 160.9, h);
476	c.fillAndStroke();
477};
478
479mxRackRackNumbering.prototype.sideText = function(c, w, h, unitNum, unitH, fontSize)
480{
481	var fontColor = mxUtils.getValue(this.style, mxRackRackNumbering.prototype.cst.TEXT_COLOR, '#666666');
482	var numDir = mxUtils.getValue(this.style, mxRackRackNumbering.prototype.cst.NUM_DIR, mxRackRackNumbering.prototype.cst.DIR_DESC);
483	c.setFontSize(fontSize);
484	c.setFontColor(fontColor);
485
486	if (numDir === mxRackRackNumbering.prototype.cst.DIR_ASC)
487	{
488		for (var i = 0; i < unitNum; i++)
489		{
490			c.text(fontSize, unitH * 0.5 + i * unitH, 0, 0, (i + 1).toString(), mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
491		};
492	}
493	else
494	{
495		for (var i = 0; i < unitNum; i++)
496		{
497			c.text(fontSize, h - unitH * 0.5 - i * unitH, 0, 0, (i + 1).toString(), mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
498		};
499	};
500
501	c.setStrokeColor('#dddddd');
502
503	c.begin();
504
505	for (var i = 0; i < unitNum + 1; i++)
506	{
507		c.moveTo(0, i * unitH);
508		c.lineTo(fontSize * 3, i * unitH);
509	};
510
511	c.stroke();
512};
513
514//**********************************************************************************************************************************************************
515//Rack Cabinet
516//**********************************************************************************************************************************************************
517/**
518 * Extends mxShape.
519 */
520function mxRackRackCabinet(bounds, fill, stroke, strokewidth)
521{
522	mxShape.call(this);
523	this.bounds = bounds;
524	this.fill = fill;
525	this.stroke = stroke;
526	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
527};
528
529/**
530 * Extends mxShape.
531 */
532mxUtils.extend(mxRackRackCabinet, mxShape);
533
534mxRackRackCabinet.prototype.cst =
535{
536		SHAPE_RACK_RACK_CABINET : 'mxgraph.rackGeneral.rackCabinet',
537		UNIT_NUM : 'unitNum',
538		UNIT_HEIGHT : 'unitHeight',
539		TEXT_COLOR : 'textColor',
540		NUM_DIR : 'numDir',
541		NUMBER_DISPLAY : 'numDisp',
542		ON : 'on',
543		OFF : 'off',
544		DIR_ASC : 'ascend',
545		DIR_DESC : 'descend',
546		TEXT_SIZE : 'textSize'
547};
548
549/**
550 * Function: paintVertexShape
551 *
552 * Paints the vertex shape.
553 */
554mxRackRackCabinet.prototype.paintVertexShape = function(c, x, y, w, h)
555{
556	var unitNum = parseFloat(mxUtils.getValue(this.style, mxRackRackCabinet.prototype.cst.UNIT_NUM, '12'));
557	var unitH = parseFloat(mxUtils.getValue(this.style, mxRackRackCabinet.prototype.cst.UNIT_HEIGHT, '14.8'));
558	var fontSize = parseFloat(mxUtils.getValue(this.style, mxRackRackCabinet.prototype.cst.TEXT_SIZE, '12'));
559	var numDis = mxUtils.getValue(this.style, mxRackRackCabinet.prototype.cst.NUMBER_DISPLAY, mxRackRackCabinet.prototype.cst.ON);
560
561	if (numDis === mxRackRackCabinet.prototype.cst.ON)
562	{
563		c.translate(x + fontSize * 2, y);
564	}
565	else
566	{
567		c.translate(x, y);
568	};
569
570	var h = unitNum * unitH + 42;
571	this.background(c, w, h, fontSize);
572	c.setShadow(false);
573	this.foreground(c, w, h, fontSize);
574
575	if (numDis === mxRackRackCabinet.prototype.cst.ON)
576	{
577		this.sideText(c, w, h, unitNum, unitH, fontSize);
578	};
579};
580
581mxRackRackCabinet.prototype.background = function(c, w, h, fontSize)
582{
583	c.setFillColor('#ffffff');
584	c.rect(0, 0, 180, h);
585	c.fillAndStroke();
586};
587
588mxRackRackCabinet.prototype.foreground = function(c, w, h, fontSize)
589{
590	c.setFillColor('#f4f4f4');
591	c.rect(0, 0, 180, 21);
592	c.fillAndStroke();
593	c.rect(0, h - 21, 180, 21);
594	c.fillAndStroke();
595	c.rect(0, 21, 9, h - 42);
596	c.fillAndStroke();
597	c.rect(171, 21, 9, h - 42);
598	c.fillAndStroke();
599	c.ellipse(2.5, 7.5, 6, 6);
600	c.stroke();
601	c.ellipse(171.5, 7.5, 6, 6);
602	c.stroke();
603	c.ellipse(2.5, h - 13.5, 6, 6);
604	c.stroke();
605	c.ellipse(171.5, h - 13.5, 6, 6);
606	c.stroke();
607};
608
609mxRackRackCabinet.prototype.sideText = function(c, w, h, unitNum, unitH, fontSize)
610{
611	var fontColor = mxUtils.getValue(this.style, mxRackRackCabinet.prototype.cst.TEXT_COLOR, '#666666');
612	var numDir = mxUtils.getValue(this.style, mxRackRackCabinet.prototype.cst.NUM_DIR, mxRackRackCabinet.prototype.cst.DIR_DESC);
613	c.setFontSize(fontSize);
614	c.setFontColor(fontColor);
615
616	if (numDir === mxRackRackCabinet.prototype.cst.DIR_ASC)
617	{
618		for (var i = 0; i < unitNum; i++)
619		{
620			c.text(-fontSize, 21 + unitH * 0.5 + i * unitH, 0, 0, (i + 1).toString(), mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
621		};
622	}
623	else
624	{
625		for (var i = 0; i < unitNum; i++)
626		{
627			c.text(-fontSize, h - 21 - unitH * 0.5 - i * unitH, 0, 0, (i + 1).toString(), mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
628		};
629	};
630
631	c.setStrokeColor('#dddddd');
632
633	c.begin();
634
635	for (var i = 0; i < unitNum + 1; i++)
636	{
637		c.moveTo(-2 * fontSize, 21 + i * unitH);
638		c.lineTo(0, 21 + i * unitH);
639	};
640
641	c.stroke();
642};
643
644//**********************************************************************************************************************************************************
645//1U Horizontal Cable Duct
646//**********************************************************************************************************************************************************
647/**
648* Extends mxShape.
649*/
650function mxRackHorCableDuct1U(bounds, fill, stroke, strokewidth)
651{
652	mxShape.call(this);
653	this.bounds = bounds;
654	this.fill = fill;
655	this.stroke = stroke;
656	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
657};
658
659/**
660* Extends mxShape.
661*/
662mxUtils.extend(mxRackHorCableDuct1U, mxShape);
663
664mxRackHorCableDuct1U.prototype.cst =
665{
666		SHAPE_RACK_HOR_CABLE_DUCT_1U : 'mxgraph.rackGeneral.horCableDuct1U'
667};
668
669/**
670* Function: paintVertexShape
671*
672* Paints the vertex shape.
673*/
674mxRackHorCableDuct1U.prototype.paintVertexShape = function(c, x, y, w, h)
675{
676	c.translate(x, y);
677	this.background(c, w, h);
678	c.setShadow(false);
679	this.foreground(c, w, h);
680};
681
682mxRackHorCableDuct1U.prototype.background = function(c, w, h)
683{
684	c.rect(0, 0, 160.9, 14.8);
685	c.fillAndStroke();
686};
687
688mxRackHorCableDuct1U.prototype.foreground = function(c, w, h)
689{
690	c.rect(12, 0, 3, 7);
691	c.stroke();
692	c.rect(12, 7, 3, 7.8);
693	c.stroke();
694
695	c.rect(45.5, 0, 3, 7);
696	c.stroke();
697	c.rect(45.5, 7, 3, 7.8);
698	c.stroke();
699
700	c.rect(79, 0, 3, 7);
701	c.stroke();
702	c.rect(79, 7, 3, 7.8);
703	c.stroke();
704
705	c.rect(112.5, 0, 3, 7);
706	c.stroke();
707	c.rect(112.5, 7, 3, 7.8);
708	c.stroke();
709
710	c.rect(146, 0, 3, 7);
711	c.stroke();
712	c.rect(146, 7, 3, 7.8);
713	c.stroke();
714};
715
716//**********************************************************************************************************************************************************
717//2U Horizontal Cable Duct
718//**********************************************************************************************************************************************************
719/**
720* Extends mxShape.
721*/
722function mxRackHorCableDuct2U(bounds, fill, stroke, strokewidth)
723{
724	mxShape.call(this);
725	this.bounds = bounds;
726	this.fill = fill;
727	this.stroke = stroke;
728	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
729};
730
731/**
732* Extends mxShape.
733*/
734mxUtils.extend(mxRackHorCableDuct2U, mxShape);
735
736mxRackHorCableDuct2U.prototype.cst =
737{
738		SHAPE_RACK_HOR_CABLE_DUCT_2U : 'mxgraph.rackGeneral.horCableDuct2U'
739};
740
741/**
742* Function: paintVertexShape
743*
744* Paints the vertex shape.
745*/
746mxRackHorCableDuct2U.prototype.paintVertexShape = function(c, x, y, w, h)
747{
748	c.translate(x, y);
749	this.background(c, w, h);
750	c.setShadow(false);
751	this.foreground(c, w, h);
752};
753
754mxRackHorCableDuct2U.prototype.background = function(c, w, h)
755{
756	c.rect(0, 0, 160.9, 29.6);
757	c.fillAndStroke();
758};
759
760mxRackHorCableDuct2U.prototype.foreground = function(c, w, h)
761{
762	c.rect(12, 0, 3, 7);
763	c.stroke();
764	c.rect(12, 7, 3, 22.6);
765	c.stroke();
766
767	c.rect(45.5, 0, 3, 7);
768	c.stroke();
769	c.rect(45.5, 7, 3, 22.6);
770	c.stroke();
771
772	c.rect(79, 0, 3, 7);
773	c.stroke();
774	c.rect(79, 7, 3, 22.6);
775	c.stroke();
776
777	c.rect(112.5, 0, 3, 7);
778	c.stroke();
779	c.rect(112.5, 7, 3, 22.6);
780	c.stroke();
781
782	c.rect(146, 0, 3, 7);
783	c.stroke();
784	c.rect(146, 7, 3, 22.6);
785	c.stroke();
786};
787
788//**********************************************************************************************************************************************************
789//1U Cable Routing Bank
790//**********************************************************************************************************************************************************
791/**
792* Extends mxShape.
793*/
794function mxRackHorRoutingBank1U(bounds, fill, stroke, strokewidth)
795{
796	mxShape.call(this);
797	this.bounds = bounds;
798	this.fill = fill;
799	this.stroke = stroke;
800	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
801};
802
803/**
804* Extends mxShape.
805*/
806mxUtils.extend(mxRackHorRoutingBank1U, mxShape);
807
808mxRackHorRoutingBank1U.prototype.cst =
809{
810		SHAPE_RACK_HOR_ROUTING_BANK_1U : 'mxgraph.rackGeneral.horRoutingBank1U'
811};
812
813/**
814* Function: paintVertexShape
815*
816* Paints the vertex shape.
817*/
818mxRackHorRoutingBank1U.prototype.paintVertexShape = function(c, x, y, w, h)
819{
820	c.translate(x, y);
821	this.background(c, w, h);
822	c.setShadow(false);
823	this.foreground(c, w, h);
824};
825
826mxRackHorRoutingBank1U.prototype.background = function(c, w, h)
827{
828	c.rect(0, 0, 160.9, 14.8);
829	c.fillAndStroke();
830};
831
832mxRackHorRoutingBank1U.prototype.foreground = function(c, w, h)
833{
834	c.rect(10, 4, 17, 6.8);
835	c.stroke();
836	c.rect(31, 4, 17, 6.8);
837	c.stroke();
838	c.rect(52, 4, 17, 6.8);
839	c.stroke();
840	c.rect(73, 4, 17, 6.8);
841	c.stroke();
842	c.rect(94, 4, 17, 6.8);
843	c.stroke();
844	c.rect(115, 4, 17, 6.8);
845	c.stroke();
846	c.rect(136, 4, 17, 6.8);
847	c.stroke();
848};
849
850//**********************************************************************************************************************************************************
851//2U Cable Routing Bank
852//**********************************************************************************************************************************************************
853/**
854* Extends mxShape.
855*/
856function mxRackHorRoutingBank2U(bounds, fill, stroke, strokewidth)
857{
858	mxShape.call(this);
859	this.bounds = bounds;
860	this.fill = fill;
861	this.stroke = stroke;
862	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
863};
864
865/**
866* Extends mxShape.
867*/
868mxUtils.extend(mxRackHorRoutingBank2U, mxShape);
869
870mxRackHorRoutingBank2U.prototype.cst =
871{
872		SHAPE_RACK_HOR_ROUTING_BANK_2U : 'mxgraph.rackGeneral.horRoutingBank2U'
873};
874
875/**
876* Function: paintVertexShape
877*
878* Paints the vertex shape.
879*/
880mxRackHorRoutingBank2U.prototype.paintVertexShape = function(c, x, y, w, h)
881{
882	c.translate(x, y);
883	this.background(c, w, h);
884	c.setShadow(false);
885	this.foreground(c, w, h);
886};
887
888mxRackHorRoutingBank2U.prototype.background = function(c, w, h)
889{
890	c.rect(0, 0, 160.9, 29.6);
891	c.fillAndStroke();
892};
893
894mxRackHorRoutingBank2U.prototype.foreground = function(c, w, h)
895{
896	c.rect(10, 4, 17, 6.8);
897	c.stroke();
898	c.rect(31, 4, 17, 6.8);
899	c.stroke();
900	c.rect(52, 4, 17, 6.8);
901	c.stroke();
902	c.rect(73, 4, 17, 6.8);
903	c.stroke();
904	c.rect(94, 4, 17, 6.8);
905	c.stroke();
906	c.rect(115, 4, 17, 6.8);
907	c.stroke();
908	c.rect(136, 4, 17, 6.8);
909	c.stroke();
910
911	c.rect(10, 18.8, 17, 6.8);
912	c.stroke();
913	c.rect(31, 18.8, 17, 6.8);
914	c.stroke();
915	c.rect(52, 18.8, 17, 6.8);
916	c.stroke();
917	c.rect(73, 18.8, 17, 6.8);
918	c.stroke();
919	c.rect(94, 18.8, 17, 6.8);
920	c.stroke();
921	c.rect(115, 18.8, 17, 6.8);
922	c.stroke();
923	c.rect(136, 18.8, 17, 6.8);
924	c.stroke();
925};
926
927//**********************************************************************************************************************************************************
928//2U Neat-Patch
929//**********************************************************************************************************************************************************
930/**
931* Extends mxShape.
932*/
933function mxRackNeatPatch2U(bounds, fill, stroke, strokewidth)
934{
935	mxShape.call(this);
936	this.bounds = bounds;
937	this.fill = fill;
938	this.stroke = stroke;
939	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
940};
941
942/**
943* Extends mxShape.
944*/
945mxUtils.extend(mxRackNeatPatch2U, mxShape);
946
947mxRackNeatPatch2U.prototype.cst =
948{
949		SHAPE_RACK_NEAT_PATCH_2U : 'mxgraph.rackGeneral.neatPatch2U'
950};
951
952/**
953* Function: paintVertexShape
954*
955* Paints the vertex shape.
956*/
957mxRackNeatPatch2U.prototype.paintVertexShape = function(c, x, y, w, h)
958{
959	c.translate(x, y);
960	this.background(c, w, h);
961	c.setShadow(false);
962	this.mainText(c, w, h);
963};
964
965mxRackNeatPatch2U.prototype.background = function(c, w, h)
966{
967	c.setFillColor('#666666');
968	c.rect(0, 0, 160.9, 29.6);
969	c.fillAndStroke();
970};
971
972mxRackNeatPatch2U.prototype.mainText = function(c, w, h)
973{
974	c.setFontSize('12');
975	c.setFontColor('#ffffff');
976	c.setFontStyle(mxConstants.FONT_BOLD);
977	c.text(80.45, 24, 0, 0, 'NEAT-PATCH', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
978};
979
980//**********************************************************************************************************************************************************
981//1U shelf
982//**********************************************************************************************************************************************************
983/**
984* Extends mxShape.
985*/
986function mxRackShelf1U(bounds, fill, stroke, strokewidth)
987{
988	mxShape.call(this);
989	this.bounds = bounds;
990	this.fill = fill;
991	this.stroke = stroke;
992	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
993};
994
995/**
996* Extends mxShape.
997*/
998mxUtils.extend(mxRackShelf1U, mxShape);
999
1000mxRackShelf1U.prototype.cst =
1001{
1002		SHAPE_RACK_SHELF_1U : 'mxgraph.rackGeneral.shelf1U'
1003};
1004
1005/**
1006* Function: paintVertexShape
1007*
1008* Paints the vertex shape.
1009*/
1010mxRackShelf1U.prototype.paintVertexShape = function(c, x, y, w, h)
1011{
1012	c.translate(x, y);
1013	this.background(c, w, h);
1014};
1015
1016mxRackShelf1U.prototype.background = function(c, w, h)
1017{
1018	c.setStrokeWidth(2);
1019	c.begin();
1020	c.moveTo(0, 0);
1021	c.lineTo(0, 14.8);
1022	c.lineTo(160.9, 14.8);
1023	c.lineTo(160.9, 0);
1024	c.fillAndStroke();
1025};
1026
1027//**********************************************************************************************************************************************************
1028//2U shelf
1029//**********************************************************************************************************************************************************
1030/**
1031* Extends mxShape.
1032*/
1033function mxRackShelf2U(bounds, fill, stroke, strokewidth)
1034{
1035	mxShape.call(this);
1036	this.bounds = bounds;
1037	this.fill = fill;
1038	this.stroke = stroke;
1039	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1040};
1041
1042/**
1043* Extends mxShape.
1044*/
1045mxUtils.extend(mxRackShelf2U, mxShape);
1046
1047mxRackShelf2U.prototype.cst =
1048{
1049		SHAPE_RACK_SHELF_2U : 'mxgraph.rackGeneral.shelf2U'
1050};
1051
1052/**
1053* Function: paintVertexShape
1054*
1055* Paints the vertex shape.
1056*/
1057mxRackShelf2U.prototype.paintVertexShape = function(c, x, y, w, h)
1058{
1059	c.translate(x, y);
1060	this.background(c, w, h);
1061};
1062
1063mxRackShelf2U.prototype.background = function(c, w, h)
1064{
1065	c.setStrokeWidth(2);
1066	c.begin();
1067	c.moveTo(0, 0);
1068	c.lineTo(0, 29.6);
1069	c.lineTo(160.9, 29.6);
1070	c.lineTo(160.9, 0);
1071	c.fillAndStroke();
1072};
1073
1074//**********************************************************************************************************************************************************
1075//4U shelf
1076//**********************************************************************************************************************************************************
1077/**
1078* Extends mxShape.
1079*/
1080function mxRackShelf4U(bounds, fill, stroke, strokewidth)
1081{
1082	mxShape.call(this);
1083	this.bounds = bounds;
1084	this.fill = fill;
1085	this.stroke = stroke;
1086	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1087};
1088
1089/**
1090* Extends mxShape.
1091*/
1092mxUtils.extend(mxRackShelf4U, mxShape);
1093
1094mxRackShelf4U.prototype.cst =
1095{
1096		SHAPE_RACK_SHELF_4U : 'mxgraph.rackGeneral.shelf4U'
1097};
1098
1099/**
1100* Function: paintVertexShape
1101*
1102* Paints the vertex shape.
1103*/
1104mxRackShelf4U.prototype.paintVertexShape = function(c, x, y, w, h)
1105{
1106	c.translate(x, y);
1107	this.background(c, w, h);
1108};
1109
1110mxRackShelf4U.prototype.background = function(c, w, h)
1111{
1112	c.setStrokeWidth(2);
1113	c.begin();
1114	c.moveTo(0, 0);
1115	c.lineTo(0, 59.2);
1116	c.lineTo(160.9, 59.2);
1117	c.lineTo(160.9, 0);
1118	c.fillAndStroke();
1119};
1120
1121//**********************************************************************************************************************************************************
1122//END LEGACY RACKS
1123//**********************************************************************************************************************************************************
1124
1125
1126//**********************************************************************************************************************************************************
1127//Channel Base
1128//**********************************************************************************************************************************************************
1129/**
1130* Extends mxShape.
1131*/
1132function mxRackChannelBase(bounds, fill, stroke, strokewidth)
1133{
1134	mxShape.call(this);
1135	this.bounds = bounds;
1136	this.fill = fill;
1137	this.stroke = stroke;
1138	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1139};
1140
1141/**
1142 * Extends mxShape.
1143 */
1144mxUtils.extend(mxRackChannelBase, mxShape);
1145
1146mxRackChannelBase.prototype.cst =
1147{
1148		SHAPE_RACK_CHANNEL_BASE : 'mxgraph.rackGeneral.channelBase'
1149};
1150
1151/**
1152 * Function: paintVertexShape
1153 *
1154 * Paints the vertex shape.
1155 */
1156mxRackChannelBase.prototype.paintVertexShape = function(c, x, y, w, h)
1157{
1158	w = Math.max(w, 20);
1159	h = Math.max(h, 20);
1160	c.translate(x, y);
1161
1162	this.background(c, w, h);
1163	c.setShadow(false);
1164	this.foreground(c, w, h);
1165};
1166
1167mxRackChannelBase.prototype.background = function(c, w, h)
1168{
1169	c.rect(10, h - 15, 5, 15);
1170	c.fillAndStroke();
1171	c.rect(w - 15, h - 15, 5, 15);
1172	c.fillAndStroke();
1173	c.rect(0, 0, w, h - 5);
1174	c.fillAndStroke();
1175};
1176
1177mxRackChannelBase.prototype.foreground = function(c, w, h)
1178{
1179	c.setFillColor('#000000');
1180	c.rect(10, h - 15, 5, 15);
1181	c.fillAndStroke();
1182	c.rect(w - 15, h - 15, 5, 15);
1183	c.fillAndStroke();
1184};
1185
1186//**********************************************************************************************************************************************************
1187//Cabinet Leg
1188//**********************************************************************************************************************************************************
1189/**
1190* Extends mxShape.
1191*/
1192function mxRackCabinetLeg(bounds, fill, stroke, strokewidth)
1193{
1194	mxShape.call(this);
1195	this.bounds = bounds;
1196	this.fill = fill;
1197	this.stroke = stroke;
1198	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1199};
1200
1201/**
1202* Extends mxShape.
1203*/
1204mxUtils.extend(mxRackCabinetLeg, mxShape);
1205
1206mxRackCabinetLeg.prototype.cst =
1207{
1208		SHAPE_RACK_CABINET_LEG : 'mxgraph.rackGeneral.cabinetLeg'
1209};
1210
1211/**
1212* Function: paintVertexShape
1213*
1214* Paints the vertex shape.
1215*/
1216mxRackCabinetLeg.prototype.paintVertexShape = function(c, x, y, w, h)
1217{
1218	w = Math.max(w, 20);
1219	h = Math.max(h, 20);
1220	c.translate(x, y);
1221
1222	this.background(c, w, h);
1223};
1224
1225mxRackCabinetLeg.prototype.background = function(c, w, h)
1226{
1227	c.begin();
1228	c.moveTo(0, h - 10);
1229	c.lineTo(5, h - 10);
1230	c.lineTo(5, h - 12);
1231	c.lineTo(9, h - 12);
1232	c.lineTo(9, h - 10);
1233	c.lineTo(w - 10, h - 10);
1234	c.lineTo(w - 10, 9);
1235	c.lineTo(w - 12, 9);
1236	c.lineTo(w - 12, 5);
1237	c.lineTo(w - 10, 5);
1238	c.lineTo(w - 10, 0);
1239	c.lineTo(w, 0);
1240	c.lineTo(w, h);
1241	c.lineTo(0, h);
1242	c.close();
1243	c.fillAndStroke();
1244};
1245
1246// New generic unit size implementations
1247mxCellRenderer.registerShape(mxRackContainer.prototype.cst.SHAPE_RACK_CONTAINER, mxRackContainer);
1248mxCellRenderer.registerShape(mxRackHorCableDuct.prototype.cst.SHAPE_RACK_HOR_CABLE_DUCT, mxRackHorCableDuct);
1249mxCellRenderer.registerShape(mxRackHorRoutingBank.prototype.cst.SHAPE_RACK_HOR_ROUTING_BANK, mxRackHorRoutingBank);
1250mxCellRenderer.registerShape(mxRackNeatPatch.prototype.cst.SHAPE_RACK_NEAT_PATCH, mxRackNeatPatch);
1251mxCellRenderer.registerShape(mxRackShelf.prototype.cst.SHAPE_RACK_SHELF, mxRackShelf);
1252mxCellRenderer.registerShape(mxRackPlate.prototype.cst.SHAPE_RACK_PLATE, mxRackPlate);
1253
1254// Legacy resizable / fixed unit size implementations
1255mxCellRenderer.registerShape(mxRackRackNumbering.prototype.cst.SHAPE_RACK_RACK_NUMBERING, mxRackRackNumbering);
1256mxCellRenderer.registerShape(mxRackRackCabinet.prototype.cst.SHAPE_RACK_RACK_CABINET, mxRackRackCabinet);
1257mxCellRenderer.registerShape(mxRackHorCableDuct1U.prototype.cst.SHAPE_RACK_HOR_CABLE_DUCT_1U, mxRackHorCableDuct1U);
1258mxCellRenderer.registerShape(mxRackHorCableDuct2U.prototype.cst.SHAPE_RACK_HOR_CABLE_DUCT_2U, mxRackHorCableDuct2U);
1259mxCellRenderer.registerShape(mxRackHorRoutingBank1U.prototype.cst.SHAPE_RACK_HOR_ROUTING_BANK_1U, mxRackHorRoutingBank1U);
1260mxCellRenderer.registerShape(mxRackHorRoutingBank2U.prototype.cst.SHAPE_RACK_HOR_ROUTING_BANK_2U, mxRackHorRoutingBank2U);
1261mxCellRenderer.registerShape(mxRackNeatPatch2U.prototype.cst.SHAPE_RACK_NEAT_PATCH_2U, mxRackNeatPatch2U);
1262mxCellRenderer.registerShape(mxRackShelf1U.prototype.cst.SHAPE_RACK_SHELF_1U, mxRackShelf1U);
1263mxCellRenderer.registerShape(mxRackShelf2U.prototype.cst.SHAPE_RACK_SHELF_2U, mxRackShelf2U);
1264mxCellRenderer.registerShape(mxRackShelf4U.prototype.cst.SHAPE_RACK_SHELF_4U, mxRackShelf4U);
1265
1266mxCellRenderer.registerShape(mxRackChannelBase.prototype.cst.SHAPE_RACK_CHANNEL_BASE, mxRackChannelBase);
1267mxCellRenderer.registerShape(mxRackCabinetLeg.prototype.cst.SHAPE_RACK_CABINET_LEG, mxRackCabinetLeg);