File Coverage

blib/lib/Catalyst/Helper/Firebug.pm
Criterion Covered Total %
statement 12 20 60.0
branch 0 2 0.0
condition 0 3 0.0
subroutine 4 5 80.0
pod 1 1 100.0
total 17 31 54.8


line stmt bran cond sub pod time code
1             package Catalyst::Helper::Firebug;
2 1     1   9815 use strict;
  1         2  
  1         42  
3 1     1   6 use warnings;
  1         2  
  1         32  
4              
5 1     1   848 use MIME::Base64;
  1         856  
  1         65  
6 1     1   6 use File::Spec;
  1         2  
  1         167  
7              
8             =head1 NAME
9              
10             Catalyst::Helper::Firebug - Catalyst Helper to generate Firebug Lite files
11              
12             =head1 SYNOPSIS
13              
14             ./script/myapp_create.pl Firebug [path]
15            
16             path: output directory path (default: root/js/firebug)
17              
18             =head1 DESCRIPTION
19              
20             Catalyst Helper to generate Firebug Lite files
21              
22             =head1 SEE ALSO
23              
24             Firebug, http://getfirebug.com/
25              
26             Firebug Lite, http://getfirebug.com/lite.html
27              
28             =head1 METHODS
29              
30             =head2 mk_stuff
31              
32             Create Firebug Lite files
33              
34             =cut
35              
36             sub mk_stuff {
37 0     0 1   my ($self, $helper, $path) = @_;
38 0   0       $path ||= File::Spec->catfile(qw/root js firebug/);
39              
40 0           $helper->mk_dir( File::Spec->catfile( $helper->{base}, $path ) );
41              
42 0           my @files = qw/errorIcon.png firebug.css firebug.html firebug.js firebugx.js infoIcon.png warningIcon.png/;
43              
44 0           for my $file (@files) {
45 0           my $data = $helper->get_file(__PACKAGE__, $file);
46 0 0         $data = decode_base64($data) if $file =~ /\.png$/;
47 0           $helper->mk_file( File::Spec->catfile( $helper->{base}, $path, $file ), $data );
48             }
49             }
50              
51             =head1 AUTHOR
52              
53             Daisuke Murase <typester@cpan.org>
54              
55             =head1 COPYRIGHT
56              
57             This program is free software; you can redistribute
58             it and/or modify it under the same terms as Perl itself.
59              
60             The full text of the license can be found in the
61             LICENSE file included with this module.
62              
63             =cut
64              
65             1;
66              
67             __DATA__
68              
69             __errorIcon.png__
70             iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFbSURBVHjafJI9SwNBEIZnE8HKRrDQNAr6Cw78AZI6IBzYploQrKz8ATYprCWVhaWgEkWUa1JYieksRCEWKhaBi1/Br2J952Yntx6YhSc7OzNvZmZvjXOOdB0YU8ZmQQ1Mefcd2F12rkXBMiqEqG6IdmZhT4NxnzAA9+AJKdi28QdJFmDhPtHaGcyUj//wCI4BcpeyYjAmD+F4HSFSHkS4x8ISiq4u4GeCy1erkmJtPgzb7EOsImPEGKs2BjuuaFK3S9TvEzWbuZBt9nEMa0bmjbnV5++wpShyLk3dcLHNPh/vSbvtEhVXp0PUaORnttmnn0G2Mle8fgsrWptX0srsK1wQC7duwzbD9sK2fbuXIqyzcP4Ih4EKk+TPTKFP53MSyR7ARhvm14hv+A5ORbgyFHrx5gmON/7mfsAnwNW7K9AS0brmm8Ijn+MHARZBBD7ABTj37/RFc38FGACwGjGO2PzGygAAAABJRU5ErkJggg==
71             __firebug.css__
72              
73             html, body {
74             margin: 0;
75             background: #FFFFFF;
76             font-family: Lucida Grande, Tahoma, sans-serif;
77             font-size: 11px;
78             overflow: hidden;
79             }
80              
81             a {
82             text-decoration: none;
83             }
84              
85             a:hover {
86             text-decoration: underline;
87             }
88              
89             .toolbar {
90             height: 14px;
91             border-top: 1px solid ThreeDHighlight;
92             border-bottom: 1px solid ThreeDShadow;
93             padding: 2px 6px;
94             background: ThreeDFace;
95             }
96              
97             .toolbarRight {
98             position: absolute;
99             top: 4px;
100             right: 6px;
101             }
102              
103             #log {
104             overflow: auto;
105             position: absolute;
106             left: 0;
107             width: 100%;
108             }
109              
110             #commandLine {
111             position: absolute;
112             bottom: 0;
113             left: 0;
114             width: 100%;
115             height: 18px;
116             border: none;
117             border-top: 1px solid ThreeDShadow;
118             }
119              
120             /************************************************************************************************/
121              
122             .logRow {
123             position: relative;
124             border-bottom: 1px solid #D7D7D7;
125             padding: 2px 4px 1px 6px;
126             background-color: #FFFFFF;
127             }
128              
129             .logRow-command {
130             font-family: Monaco, monospace;
131             color: blue;
132             }
133              
134             .objectBox-null {
135             padding: 0 2px;
136             border: 1px solid #666666;
137             background-color: #888888;
138             color: #FFFFFF;
139             }
140              
141             .objectBox-string {
142             font-family: Monaco, monospace;
143             color: red;
144             white-space: pre;
145             }
146              
147             .objectBox-number {
148             color: #000088;
149             }
150              
151             .objectBox-function {
152             font-family: Monaco, monospace;
153             color: DarkGreen;
154             }
155              
156             .objectBox-object {
157             color: DarkGreen;
158             font-weight: bold;
159             }
160              
161             /************************************************************************************************/
162              
163             .logRow-info,
164             .logRow-error,
165             .logRow-warning {
166             background: #FFFFFF no-repeat 2px 2px;
167             padding-left: 20px;
168             padding-bottom: 3px;
169             }
170              
171             .logRow-info {
172             background-image: url(infoIcon.png);
173             }
174              
175             .logRow-warning {
176             background-color: cyan;
177             background-image: url(warningIcon.png);
178             }
179              
180             .logRow-error {
181             background-color: LightYellow;
182             background-image: url(errorIcon.png);
183             }
184              
185             .errorMessage {
186             vertical-align: top;
187             color: #FF0000;
188             }
189              
190             .objectBox-sourceLink {
191             position: absolute;
192             right: 4px;
193             top: 2px;
194             padding-left: 8px;
195             font-family: Lucida Grande, sans-serif;
196             font-weight: bold;
197             color: #0000FF;
198             }
199              
200             /************************************************************************************************/
201              
202             .logRow-group {
203             background: #EEEEEE;
204             border-bottom: none;
205             }
206              
207             .logGroup {
208             background: #EEEEEE;
209             }
210              
211             .logGroupBox {
212             margin-left: 24px;
213             border-top: 1px solid #D7D7D7;
214             border-left: 1px solid #D7D7D7;
215             }
216              
217             /************************************************************************************************/
218              
219             .selectorTag,
220             .selectorId,
221             .selectorClass {
222             font-family: Monaco, monospace;
223             font-weight: normal;
224             }
225              
226             .selectorTag {
227             color: #0000FF;
228             }
229              
230             .selectorId {
231             color: DarkBlue;
232             }
233              
234             .selectorClass {
235             color: red;
236             }
237              
238             /************************************************************************************************/
239              
240             .objectBox-element {
241             font-family: Monaco, monospace;
242             color: #000088;
243             }
244              
245             .nodeChildren {
246             margin-left: 16px;
247             }
248              
249             .nodeTag {
250             color: blue;
251             }
252              
253             .nodeValue {
254             color: #FF0000;
255             font-weight: normal;
256             }
257              
258             .nodeText,
259             .nodeComment {
260             margin: 0 2px;
261             vertical-align: top;
262             }
263              
264             .nodeText {
265             color: #333333;
266             }
267              
268             .nodeComment {
269             color: DarkGreen;
270             }
271              
272             /************************************************************************************************/
273              
274             .propertyNameCell {
275             vertical-align: top;
276             }
277              
278             .propertyName {
279             font-weight: bold;
280             }
281              
282             __firebug.html__
283             <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
284             "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
285              
286             <html xmlns="http://www.w3.org/1999/xhtml">
287              
288             <head>
289             <title>Firebug</title>
290             <link rel="stylesheet" type="text/css" href="firebug.css">
291             </head>
292              
293             <body>
294             <div id="toolbar" class="toolbar">
295             <a href="#" onclick="parent.console.clear()">Clear</a>
296             <span class="toolbarRight">
297             <a href="#" onclick="parent.console.close()">Close</a>
298             </span>
299             </div>
300             <div id="log"></div>
301             <input type="text" id="commandLine">
302            
303             <script>parent.onFirebugReady(document);</script>
304             </body>
305             </html>
306              
307             __firebug.js__
308              
309             if (!("console" in window) || !("firebug" in console)) {
310             (function()
311             {
312             window.console =
313             {
314             log: function()
315             {
316             logFormatted(arguments, "");
317             },
318            
319             debug: function()
320             {
321             logFormatted(arguments, "debug");
322             },
323            
324             info: function()
325             {
326             logFormatted(arguments, "info");
327             },
328            
329             warn: function()
330             {
331             logFormatted(arguments, "warning");
332             },
333            
334             error: function()
335             {
336             logFormatted(arguments, "error");
337             },
338            
339             assert: function(truth, message)
340             {
341             if (!truth)
342             {
343             var args = [];
344             for (var i = 1; i < arguments.length; ++i)
345             args.push(arguments[i]);
346            
347             logFormatted(args.length ? args : ["Assertion Failure"], "error");
348             throw message ? message : "Assertion Failure";
349             }
350             },
351            
352             dir: function(object)
353             {
354             var html = [];
355            
356             var pairs = [];
357             for (var name in object)
358             {
359             try
360             {
361             pairs.push([name, object[name]]);
362             }
363             catch (exc)
364             {
365             }
366             }
367            
368             pairs.sort(function(a, b) { return a[0] < b[0] ? -1 : 1; });
369            
370             html.push('<table>');
371             for (var i = 0; i < pairs.length; ++i)
372             {
373             var name = pairs[i][0], value = pairs[i][1];
374            
375             html.push('<tr>',
376             '<td class="propertyNameCell"><span class="propertyName">',
377             escapeHTML(name), '</span></td>', '<td><span class="propertyValue">');
378             appendObject(value, html);
379             html.push('</span></td></tr>');
380             }
381             html.push('</table>');
382            
383             logRow(html, "dir");
384             },
385            
386             dirxml: function(node)
387             {
388             var html = [];
389            
390             appendNode(node, html);
391             logRow(html, "dirxml");
392             },
393            
394             group: function()
395             {
396             logRow(arguments, "group", pushGroup);
397             },
398            
399             groupEnd: function()
400             {
401             logRow(arguments, "", popGroup);
402             },
403            
404             time: function(name)
405             {
406             timeMap[name] = (new Date()).getTime();
407             },
408            
409             timeEnd: function(name)
410             {
411             if (name in timeMap)
412             {
413             var delta = (new Date()).getTime() - timeMap[name];
414             logFormatted([name+ ":", delta+"ms"]);
415             delete timeMap[name];
416             }
417             },
418            
419             count: function()
420             {
421             this.warn(["count() not supported."]);
422             },
423            
424             trace: function()
425             {
426             this.warn(["trace() not supported."]);
427             },
428            
429             profile: function()
430             {
431             this.warn(["profile() not supported."]);
432             },
433            
434             profileEnd: function()
435             {
436             },
437            
438             clear: function()
439             {
440             consoleBody.innerHTML = "";
441             },
442              
443             open: function()
444             {
445             toggleConsole(true);
446             },
447            
448             close: function()
449             {
450             if (frameVisible)
451             toggleConsole();
452             }
453             };
454            
455             // ********************************************************************************************
456            
457             var consoleFrame = null;
458             var consoleBody = null;
459             var commandLine = null;
460            
461             var frameVisible = false;
462             var messageQueue = [];
463             var groupStack = [];
464             var timeMap = {};
465            
466             var clPrefix = ">>> ";
467            
468             var isFirefox = navigator.userAgent.indexOf("Firefox") != -1;
469             var isIE = navigator.userAgent.indexOf("MSIE") != -1;
470             var isOpera = navigator.userAgent.indexOf("Opera") != -1;
471             var isSafari = navigator.userAgent.indexOf("AppleWebKit") != -1;
472              
473             // ********************************************************************************************
474              
475             function toggleConsole(forceOpen)
476             {
477             frameVisible = forceOpen || !frameVisible;
478             if (consoleFrame)
479             consoleFrame.style.visibility = frameVisible ? "visible" : "hidden";
480             else
481             waitForBody();
482             }
483              
484             function focusCommandLine()
485             {
486             toggleConsole(true);
487             if (commandLine)
488             commandLine.focus();
489             }
490              
491             function waitForBody()
492             {
493             if (document.body)
494             createFrame();
495             else
496             setTimeout(waitForBody, 200);
497             }
498              
499             function createFrame()
500             {
501             if (consoleFrame)
502             return;
503            
504             window.onFirebugReady = function(doc)
505             {
506             window.onFirebugReady = null;
507              
508             var toolbar = doc.getElementById("toolbar");
509             toolbar.onmousedown = onSplitterMouseDown;
510              
511             commandLine = doc.getElementById("commandLine");
512             addEvent(commandLine, "keydown", onCommandLineKeyDown);
513              
514             addEvent(doc, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
515            
516             consoleBody = doc.getElementById("log");
517             layout();
518             flush();
519             }
520              
521             var baseURL = getFirebugURL();
522              
523             consoleFrame = document.createElement("iframe");
524             consoleFrame.setAttribute("src", baseURL+"/firebug.html");
525             consoleFrame.setAttribute("frameBorder", "0");
526             consoleFrame.style.visibility = (frameVisible ? "visible" : "hidden");
527             consoleFrame.style.zIndex = "2147483647";
528             consoleFrame.style.position = "fixed";
529             consoleFrame.style.width = "100%";
530             consoleFrame.style.left = "0";
531             consoleFrame.style.bottom = "0";
532             consoleFrame.style.height = "200px";
533             document.body.appendChild(consoleFrame);
534             }
535            
536             function getFirebugURL()
537             {
538             var scripts = document.getElementsByTagName("script");
539             for (var i = 0; i < scripts.length; ++i)
540             {
541             if (scripts[i].src.indexOf("firebug.js") != -1)
542             {
543             var lastSlash = scripts[i].src.lastIndexOf("/");
544             return scripts[i].src.substr(0, lastSlash);
545             }
546             }
547             }
548            
549             function evalCommandLine()
550             {
551             var text = commandLine.value;
552             commandLine.value = "";
553              
554             logRow([clPrefix, text], "command");
555            
556             var value;
557             try
558             {
559             value = eval(text);
560             }
561             catch (exc)
562             {
563             }
564              
565             console.log(value);
566             }
567            
568             function layout()
569             {
570             var toolbar = consoleBody.ownerDocument.getElementById("toolbar");
571             var height = consoleFrame.offsetHeight - (toolbar.offsetHeight + commandLine.offsetHeight);
572             consoleBody.style.top = toolbar.offsetHeight + "px";
573             consoleBody.style.height = height + "px";
574            
575             commandLine.style.top = (consoleFrame.offsetHeight - commandLine.offsetHeight) + "px";
576             }
577            
578             function logRow(message, className, handler)
579             {
580             if (consoleBody)
581             writeMessage(message, className, handler);
582             else
583             {
584             messageQueue.push([message, className, handler]);
585             waitForBody();
586             }
587             }
588            
589             function flush()
590             {
591             var queue = messageQueue;
592             messageQueue = [];
593            
594             for (var i = 0; i < queue.length; ++i)
595             writeMessage(queue[i][0], queue[i][1], queue[i][2]);
596             }
597              
598             function writeMessage(message, className, handler)
599             {
600             var isScrolledToBottom =
601             consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight;
602              
603             if (!handler)
604             handler = writeRow;
605            
606             handler(message, className);
607            
608             if (isScrolledToBottom)
609             consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight;
610             }
611            
612             function appendRow(row)
613             {
614             var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody;
615             container.appendChild(row);
616             }
617              
618             function writeRow(message, className)
619             {
620             var row = consoleBody.ownerDocument.createElement("div");
621             row.className = "logRow" + (className ? " logRow-"+className : "");
622             row.innerHTML = message.join("");
623             appendRow(row);
624             }
625              
626             function pushGroup(message, className)
627             {
628             logFormatted(message, className);
629              
630             var groupRow = consoleBody.ownerDocument.createElement("div");
631             groupRow.className = "logGroup";
632             var groupRowBox = consoleBody.ownerDocument.createElement("div");
633             groupRowBox.className = "logGroupBox";
634             groupRow.appendChild(groupRowBox);
635             appendRow(groupRowBox);
636             groupStack.push(groupRowBox);
637             }
638              
639             function popGroup()
640             {
641             groupStack.pop();
642             }
643            
644             // ********************************************************************************************
645              
646             function logFormatted(objects, className)
647             {
648             var html = [];
649              
650             var format = objects[0];
651             var objIndex = 0;
652              
653             if (typeof(format) != "string")
654             {
655             format = "";
656             objIndex = -1;
657             }
658              
659             var parts = parseFormat(format);
660             for (var i = 0; i < parts.length; ++i)
661             {
662             var part = parts[i];
663             if (part && typeof(part) == "object")
664             {
665             var object = objects[++objIndex];
666             part.appender(object, html);
667             }
668             else
669             appendText(part, html);
670             }
671              
672             for (var i = objIndex+1; i < objects.length; ++i)
673             {
674             appendText(" ", html);
675            
676             var object = objects[i];
677             if (typeof(object) == "string")
678             appendText(object, html);
679             else
680             appendObject(object, html);
681             }
682            
683             logRow(html, className);
684             }
685              
686             function parseFormat(format)
687             {
688             var parts = [];
689              
690             var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
691             var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
692              
693             for (var m = reg.exec(format); m; m = reg.exec(format))
694             {
695             var type = m[8] ? m[8] : m[5];
696             var appender = type in appenderMap ? appenderMap[type] : appendObject;
697             var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
698              
699             parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
700             parts.push({appender: appender, precision: precision});
701              
702             format = format.substr(m.index+m[0].length);
703             }
704              
705             parts.push(format);
706              
707             return parts;
708             }
709              
710             function escapeHTML(value)
711             {
712             function replaceChars(ch)
713             {
714             switch (ch)
715             {
716             case "<":
717             return "&lt;";
718             case ">":
719             return "&gt;";
720             case "&":
721             return "&amp;";
722             case "'":
723             return "&#39;";
724             case '"':
725             return "&quot;";
726             }
727             return "?";
728             };
729             return String(value).replace(/[<>&"']/g, replaceChars);
730             }
731              
732             function objectToString(object)
733             {
734             try
735             {
736             return object+"";
737             }
738             catch (exc)
739             {
740             return null;
741             }
742             }
743              
744             // ********************************************************************************************
745              
746             function appendText(object, html)
747             {
748             html.push(escapeHTML(objectToString(object)));
749             }
750              
751             function appendNull(object, html)
752             {
753             html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
754             }
755              
756             function appendString(object, html)
757             {
758             html.push('<span class="objectBox-string">&quot;', escapeHTML(objectToString(object)),
759             '&quot;</span>');
760             }
761              
762             function appendInteger(object, html)
763             {
764             html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
765             }
766              
767             function appendFloat(object, html)
768             {
769             html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
770             }
771              
772             function appendFunction(object, html)
773             {
774             var reName = /function ?(.*?)\(/;
775             var m = reName.exec(objectToString(object));
776             var name = m ? m[1] : "function";
777             html.push('<span class="objectBox-function">', escapeHTML(name), '()</span>');
778             }
779            
780             function appendObject(object, html)
781             {
782             try
783             {
784             if (object == undefined)
785             appendNull("undefined", html);
786             else if (object == null)
787             appendNull("null", html);
788             else if (typeof object == "string")
789             appendString(object, html);
790             else if (typeof object == "number")
791             appendInteger(object, html);
792             else if (typeof object == "function")
793             appendFunction(object, html);
794             else if (object.nodeType == 1)
795             appendSelector(object, html);
796             else if (typeof object == "object")
797             appendObjectFormatted(object, html);
798             else
799             appendText(object, html);
800             }
801             catch (exc)
802             {
803             }
804             }
805            
806             function appendObjectFormatted(object, html)
807             {
808             var text = objectToString(object);
809             var reObject = /\[object (.*?)\]/;
810              
811             var m = reObject.exec(text);
812             html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>')
813             }
814            
815             function appendSelector(object, html)
816             {
817             html.push('<span class="objectBox-selector">');
818              
819             html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>');
820             if (object.id)
821             html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>');
822             if (object.className)
823             html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>');
824              
825             html.push('</span>');
826             }
827              
828             function appendNode(node, html)
829             {
830             if (node.nodeType == 1)
831             {
832             html.push(
833             '<div class="objectBox-element">',
834             '&lt;<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>');
835              
836             for (var i = 0; i < node.attributes.length; ++i)
837             {
838             var attr = node.attributes[i];
839             if (!attr.specified)
840             continue;
841            
842             html.push('&nbsp;<span class="nodeName">', attr.nodeName.toLowerCase(),
843             '</span>=&quot;<span class="nodeValue">', escapeHTML(attr.nodeValue),
844             '</span>&quot;')
845             }
846              
847             if (node.firstChild)
848             {
849             html.push('&gt;</div><div class="nodeChildren">');
850              
851             for (var child = node.firstChild; child; child = child.nextSibling)
852             appendNode(child, html);
853            
854             html.push('</div><div class="objectBox-element">&lt;/<span class="nodeTag">',
855             node.nodeName.toLowerCase(), '&gt;</span></div>');
856             }
857             else
858             html.push('/&gt;</div>');
859             }
860             else if (node.nodeType == 3)
861             {
862             html.push('<div class="nodeText">', escapeHTML(node.nodeValue),
863             '</div>');
864             }
865             }
866              
867             // ********************************************************************************************
868            
869             function addEvent(object, name, handler)
870             {
871             if (document.all)
872             object.attachEvent("on"+name, handler);
873             else
874             object.addEventListener(name, handler, false);
875             }
876            
877             function removeEvent(object, name, handler)
878             {
879             if (document.all)
880             object.detachEvent("on"+name, handler);
881             else
882             object.removeEventListener(name, handler, false);
883             }
884            
885             function cancelEvent(event)
886             {
887             if (document.all)
888             event.cancelBubble = true;
889             else
890             event.stopPropagation();
891             }
892              
893             function onError(msg, href, lineNo)
894             {
895             var html = [];
896            
897             var lastSlash = href.lastIndexOf("/");
898             var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
899            
900             html.push(
901             '<span class="errorMessage">', msg, '</span>',
902             '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
903             );
904            
905             logRow(html, "error");
906             };
907              
908             function onKeyDown(event)
909             {
910             if (event.keyCode == 123)
911             toggleConsole();
912             else if ((event.keyCode == 108 || event.keyCode == 76) && event.shiftKey
913             && (event.metaKey || event.ctrlKey))
914             focusCommandLine();
915             else
916             return;
917            
918             cancelEvent(event);
919             }
920              
921             function onSplitterMouseDown(event)
922             {
923             if (isSafari || isOpera)
924             return;
925            
926             addEvent(document, "mousemove", onSplitterMouseMove);
927             addEvent(document, "mouseup", onSplitterMouseUp);
928              
929             for (var i = 0; i < frames.length; ++i)
930             {
931             addEvent(frames[i].document, "mousemove", onSplitterMouseMove);
932             addEvent(frames[i].document, "mouseup", onSplitterMouseUp);
933             }
934             }
935            
936             function onSplitterMouseMove(event)
937             {
938             var win = document.all
939             ? event.srcElement.ownerDocument.parentWindow
940             : event.target.ownerDocument.defaultView;
941              
942             var clientY = event.clientY;
943             if (win != win.parent)
944             clientY += win.frameElement ? win.frameElement.offsetTop : 0;
945            
946             var height = consoleFrame.offsetTop + consoleFrame.clientHeight;
947             var y = height - clientY;
948            
949             consoleFrame.style.height = y + "px";
950             layout();
951             }
952            
953             function onSplitterMouseUp(event)
954             {
955             removeEvent(document, "mousemove", onSplitterMouseMove);
956             removeEvent(document, "mouseup", onSplitterMouseUp);
957              
958             for (var i = 0; i < frames.length; ++i)
959             {
960             removeEvent(frames[i].document, "mousemove", onSplitterMouseMove);
961             removeEvent(frames[i].document, "mouseup", onSplitterMouseUp);
962             }
963             }
964            
965             function onCommandLineKeyDown(event)
966             {
967             if (event.keyCode == 13)
968             evalCommandLine();
969             else if (event.keyCode == 27)
970             commandLine.value = "";
971             }
972            
973             window.onerror = onError;
974             addEvent(document, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
975            
976             if (document.documentElement.getAttribute("debug") == "true")
977             toggleConsole(true);
978             })();
979             }
980              
981             __firebugx.js__
982              
983             if (!("console" in window) || !("firebug" in console))
984             {
985             var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
986             "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
987              
988             window.console = {};
989             for (var i = 0; i < names.length; ++i)
990             window.console[names[i]] = function() {}
991             }
992             __infoIcon.png__
993             iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGeSURBVHjajFJNKERRFP7efc+YMTNhpIaFmmRkZeFna0E2pGjULK1GykYUZaukxGIWkgVlg41SFiKllLKwIgthITUbmfE3P557nfNmHm8k+eq755zb+c6577yjKaVgo7RpXicTI/YRqwvXt8T17OXEDhzQbCGJhihcld5mSHc9lCjLJ5gpiPQFROZ6m8IlKrD/JSTRqDIq4mZFD5SrBpV+YHksX3l4EXh8BgmvYCT3AJnpJPGhIFEAmh43A/2WiNHSAAx25Mk+Q7obYJZ3szvCh8HOh68Nyqj6ev/BGTC18u3bkJ4wZLo+Qs36BMUR6Q47vxuTUepEV10teeuE9DSyiXDHkNLL8RP8TEalr/he6X42dQK/YG4Df8CS6HwmNPmK/0L7sHITLNwVmZt/C0XWyt1l4ZL+ckKVnoqGYyPW6+iWu4N4Oz+i/7hmL8CUctXOvgcGqKTbmqRzKPxLNDMJ42GLG0RJuOlcuRklvNPS1wrpCkKVBGmE7xC5BHW6h/56xvE4iRaKdrUgDhU2o50XiJgmnhKPC3uasnM/BRgAWJKYVu7pMGEAAAAASUVORK5CYII=
994             __warningIcon.png__
995             iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGWSURBVHjaYvz//z8DDKzu5mEGUmlA7AfEolDh+0C8OLT0yyYGJMAI0wjUlMDIyDBfSf83g5TKXwZ2Loj41w9MDA+vsTA8u8O8HsidDjRgN1gCpHFVF3fOttmc/98+YwJx/585w/C/o4Ph/927YGkwfnKL+f+GSVz/gWqdwJYBGUJrern/f3zDBFfk4sIAsg6sGSYGwo9vsIA0rgZxmIAKMtVNfzPwCf9jIARk1P+AvBEC9JYfSGMISIBYIKMGVhsC0qjIzf8fRdLYGEIrKWFq5OIDq5VjwmaqoCAqjRINjGCKGaTxxY+vjAz4DEAGULUvWIDE1uf3mNV5hRCBk5aG6mRkAFQLoraCbJx+7Rgrw7dPCFtXr2Zg2LOHgeHsWVRNrx8zMzy4wnIQmAgWMAGJO79/Mlae2MzB8OsHRDNIEwzDwJf3TAyntrGDmNPRk1wLB/f/ajWT3wxMXP8Y7j35x+Bgx8Dw7gUTw5snzAx3zrMw/PnFWAy0qA9FI1SzIihBALEZyItA/B2ITwHxEWg6/QhTCxBgAB4kvHiHyye8AAAAAElFTkSuQmCC